// ==UserScript==
// @name WME Split POI
// @namespace https://gf.qytechs.cn/fr/scripts/13008-wme-split-poi
// @description Split POI with a new seg
// @description:fr Découpage d'un POI en deux en utisant un nouveau segment
// @include https://www.waze.com/editor/*
// @include https://www.waze.com/*/editor/*
// @include https://editor-beta.waze.com/*
// @version 1.0
// @grant none
// ==/UserScript==
var LevelAutorise=1;
var WMESP_version = "1.0";
/* bootstrap, will call WMESP_init() */
function WMESP_bootstrap(){
log('Init');
if (typeof(unsafeWindow) === "undefined"){
unsafeWindow = ( function () {
var dummyElem = document.createElement('p');
dummyElem.setAttribute('onclick', 'return window;');
return dummyElem.onclick();
}) ();
}
/* begin running the code! */
setTimeout(initialize, 1000);
}
//========== Helper ==============================//
function getElementsByClassName(classname, node) {
if(!node) node = document.getElementsByTagName("body")[0];
var a = [];
var re = new RegExp('\\b' + classname + '\\b');
var els = node.getElementsByTagName("*");
for (var i=0,j=els.length; i<j; i++)
if (re.test(els[i].className)) a.push(els[i]);
return a;
}
function getId(node) {
return document.getElementById(node);
}
function log(msg, obj)
{
if (obj==null)
console.log("WME Split POI v" + WMESP_version + " - " + msg);
else
console.debug("WME Split POI v" + WMESP_version + " - " + msg + " " ,obj);
}
//========== /Helper ==============================//
function initialize()
{
log ("init");
initializeWazeObjects();
initWazeAPI(emptyFunc);
log ("init done");
}
function emptyFunc(){}
function initWazeAPI(handler)
{
var APIRequired=[{o: "Waze", s: "waze"},
{o: "Waze.model", s: "wazeModel"},
{o: "Waze.map", s: "wazeMap"},
{o: "Waze.loginManager", s: "loginManager"},
{o: "Waze.selectionManager", s: "selectionManager"},
{o: "Waze.loginManager.user", s: "me"},
{o: "Waze/Action/UpdateObject", s: "WazeActionUpdateObject"},
{o: "Waze/Action/UpdateSegmentGeometry", s: "WazeUpdateSegmentGeometry"},
{o: "Waze/Action/UpdateFeatureGeometry", s: "WazeActionUpdateFeatureGeometry"},
{o: "Waze/Feature/Vector/Landmark", s: "WazefeatureVectorLandmark"},
{o: "Waze/Action/AddLandmark", s: "WazeActionAddLandmark"},
{o: "localStorage", s: null}
];
if (typeof wazeAPI === "undefined")
wazeAPI={};
for (var i=0; i<APIRequired.length; i++)
{
if (APIRequired[i].o.indexOf('/')!=-1)
{
wazeAPI[APIRequired[i].s]=require(APIRequired[i].o);
if (typeof wazeAPI[APIRequired[i].s] === "undefined")
{
window.setTimeout(initWazeAPI, 500);
return;
}
}
else
{
var path=APIRequired[i].o.split('.');
var object=unsafeWindow;
for (var j=0; j<path.length; j++)
{
object=object[path[j]];
if (typeof object === "undefined")
{
window.setTimeout(initWazeAPI, 500);
return;
}
}
if (APIRequired[i].s!=null)
{
wazeAPI[APIRequired[i].s] = object;
}
}
}
log ("wazeAPI:", wazeAPI);
handler();
}
function waitForObject(object)
{
var obj=null;
log ("eval: " + "typeof(unsafeWindow." + object.o.replace(/\//g, '.') + ")");
if (object.r==true)
{
eval ((object.s!=null?object.s:'dummy') + '=require("' + object.o + '")');
eval ("obj=" + (object.s!=null?object.s:'dummy'));
log("obj", obj);
}
//obj=require(object.o);
else
obj=eval("typeof(unsafeWindow." + object.o.replace(/\//g, '.') + ")");
if(obj === "undefined")
{
log(object.o + ' KO');
window.setTimeout(waitForObject.caller, 500);
return false;
}
log(object.s + ' OK');
if (object.s!=null && object.r==false)
eval (object.s + "=" + object.o.replace(/\//g, '.'));
return true;
}
function initializeWazeObjects()
{
if (typeof unsafeWindow === "undefined")
{
unsafeWindow = ( function () {
var dummyElem = document.createElement('p');
dummyElem.setAttribute('onclick', 'return window;');
return dummyElem.onclick();
}) ();
}
var objectToCheck = [
{o: "Waze", s: "waze", r: false},
{o: "Waze.vent", s: "wazeVent", r: false},
{o: "Waze.controller", s: "wazeController", r: false},
{o: "Waze.model", s: "wazeModel", r: false},
{o: "Waze.map", s: "wazeMap", r: false},
{o: "OpenLayers", s: "wazeOL", r: false},
{o: "Waze.loginManager", s: "loginManager", r: false},
{o: "Waze.selectionManager", s: "selectionManager", r: false},
{o: "Waze.loginManager.user", s: "me", r: false},
{o: "Waze/Action/UpdateObject", s: "WazeActionUpdateObject", r: true},
{o: "Waze/Action/UpdateFeatureAddress", s: "WazeActionUpdateFeatureAddress", r: true},
{o: "Waze/Action/UpdateSegmentGeometry", s: "WazeUpdateSegmentGeometry", r: true},
{o: "Waze/Action/ConnectSegment", s: "WazeActionConnectSegment", r: true},
{o: "Waze/Action/DisconnectSegment", s: "WazeActionDisconnectSegment", r: true},
{o: "Waze/Action/MergeSegments", s: "WazeActionMergeSegments", r: true},
{o: "Waze/Action/SplitSegments", s: "WazeActionSplitSegments", r: true},
{o: "Waze/Action/ModifyConnection", s: "WazeActionModifyConnection", r: true},
{o: "Waze/Action/ModifyAllConnections", s: "WazeActionModifyAllConnections", r: true},
{o: "Waze/Action/HouseNumber", s: "WazeActionHouseNumber", r: true},
{o: "Waze/Action/DeleteObject", s: "WazeActionDeleteObject", r: true},
{o: "Waze/Action/UpdateFeatureGeometry", s: "WazeActionUpdateFeatureGeometry", r: true},
{o: "Waze/Feature/Vector/Landmark", s: "WazefeatureVectorLandmark", r: true},
{o: "Waze/Action/AddLandmark", s: "WazeActionAddLandmark", r: true},
{o: "localStorage", s: null, r: false}
];
for (var i=0; i<objectToCheck.length; i++)
{
if (!waitForObject(objectToCheck[i])) return;
}
initializeWazeUI();
}
function initializeWazeUI()
{
var userInfo = getId('user-info');
if (userInfo==null)
{
window.setTimeout(initializeWazeUI, 500);
return;
}
var navTabs=userInfo.getElementsByTagName('ul');
if (navTabs.length==0)
{
window.setTimeout(initializeWazeUI, 500);
return;
}
if (typeof(navTabs[0])==='undefined')
{
window.setTimeout(initializeWazeUI, 500);
return;
}
var tabContents=userInfo.getElementsByTagName('div');
if (tabContents.length==0)
{
window.setTimeout(initializeWazeUI, 500);
return;
}
if (typeof(tabContents[0])==='undefined')
{
window.setTimeout(initializeWazeUI, 500);
return;
}
WMESP_Init();
}
function WMESP_Init()
{
log('Initialise');
//WMESP_InitDiv();
selectionManager.events.register("selectionchanged", null, WMESP_newSelectionAvailable);
log("init done.");
// window.setInterval(WMESP_update,250);
}
function WMESP_newSelectionAvailable()
{
if (selectionManager.selectedItems.length!=1)
return;
var selectedObject = selectionManager.selectedItems[0].model;
if (selectedObject.type!="venue")
return;
var attributes = selectedObject.attributes;
log("selectedObject", selectedObject);
if (!attributes.geometry.hasOwnProperty("components"))
return;
if (!((attributes.categories == "NATURAL_FEATURES" ) || (attributes.categories == "FOREST_GROVE") || (attributes.categories == "RIVER_STREAM" ) || (attributes.categories == "CANAL" )))
return;
log("poi categories", selectedObject.attributes.categories);
var editPanel=getId('edit-panel');
if (editPanel.firstElementChild.style.display=='none')
window.setTimeout(WMESP_newSelectionAvailable, 100);
// ok: 1 selected item and pannel is shown
// On verifie que le segment est éditable
if (!objIsEditable(selectedObject))
{
log("Not editable!");
return;
}
if (selectedObject.type=="venue")
{
item=getId("landmark-edit-general");
var attSection = getElementsByClassName("attributes-form side-panel-section", item);
log("attSection",attSection);
var btnResidential = getElementsByClassName("btn-link toggle-residential",item);
log("btnResidential",btnResidential);
var parent1 = btnResidential[0].parentNode;
log("parent1",parent1);
var parent = parent1.parentNode;
log("parent",parent);
var WMESP_Controle=document.createElement('Div');
WMESP_Controle.id="WMESP-Controle";
WMESP_Controle.innerHTML+='<br><input type="button" id="_btnSplitPOI" value="Split POI"><br>';
attSection[0].insertBefore(WMESP_Controle, parent);
//item.appendChild(WMESP_Controle);
//attSection[0].appendChild(WMESP_Controle);
getId("_btnSplitPOI").onclick=SplitPOI;
log("wazeModel.actionManager",wazeModel.actionManager);
}
}
function onScreen(obj)
{
if (obj.geometry)
{
return(wazeMap.getExtent().intersectsBounds(obj.geometry.getBounds()));
}
return false;
}
function objIsEditable(obj)
{
if (obj==null) return false;
if (Waze.loginManager.user.isCountryManager()) return true;
if (obj.attributes.permissions == 0)
return false;
return true;
}
function SplitPOI()
{
if (selectionManager.selectedItems.length!=1)
return;
var poi = selectionManager.selectedItems[0].model;
if (poi.type!="venue")
return;
var poiAttr = poi.attributes;
var poiId = poiAttr.id;
//if (poiAttr.geometry.type!="Polygon")
if (!poiAttr.geometry.components[0].hasOwnProperty("components"))
return;
var poiPoints = [];
var segPoints = [];
log("poi",poi);
log("poiAttr",poiAttr);
for (var seg in Waze.model.segments.objects)
{
var segment = Waze.model.segments.get(seg);
var segAttr = segment.attributes;
if (segAttr.primaryStreetID==null)
{
if (onScreen(segment))
{
var segLineString = segAttr.geometry.clone();
}
}
}
var poiGeo = poiAttr.geometry.clone();
var oldPoiGeo = poiAttr.geometry.clone();
//log("poiGeo",poiGeo);
var poiLineString = poiGeo.components[0].clone();
var poiLine = new OpenLayers.Geometry.LinearRing();
var segLine = new OpenLayers.Geometry.LinearRing();
var intersectPoint = []; // new OpenLayers.Geometry.Point();
var intersectLine = []; // new OpenLayers.Geometry.LinearRing();
// Calcul des point d'intersection seg // poi
for (var n=0; n < parseInt(poiLineString.components.length-1); n++)
{
poiLine.components["0"] = poiLineString.components[n].clone();
poiLine.components["1"] = poiLineString.components[n+1].clone();
//log(n + " poiLine", poiLine);
for (var m=0; m < parseInt(segLineString.components.length-1); m++)
{
segLine.components["0"] = segLineString.components[m].clone();
segLine.components["1"] = segLineString.components[m+1].clone();
//log(m + " segLine", segLine);
if (poiLine.intersects(segLine))
{
intersectPoint.push({index: n, intersect: intersection(poiLine, segLine)});
}
segLine.removeComponent("0");
segLine.removeComponent("1");
}
poiLine.removeComponent("0");
poiLine.removeComponent("1");
}
// intégration des points au contour du POI avec memo du nouvel index
var i=1;
for (var n=0; n < intersectPoint.length; n++)
{
var point = intersectPoint[n].intersect;
var index = parseInt(intersectPoint[n].index)+i;
poiLineString.addComponent(point, index);
intersectPoint[n].newIndex = index;
i++;
}
log("poiLineString",poiLineString);
log("intersectPoint", intersectPoint);
// création des deux nouvelles géométries
var TabLine1 = [];
var TabLine2 = [];
var index1 = parseInt(intersectPoint[0].newIndex);
var index2 = parseInt(intersectPoint[1].newIndex);
log("index1 = "+ index1);
log("index2 = "+ index2);
for (var n=0; n < parseInt(poiLineString.components.length); n++)
{
var x = poiLineString.components[n].x;
var y = poiLineString.components[n].y;
var point = new OpenLayers.Geometry.Point(x ,y);
if (n < index1){
TabLine1.push(point);
log("1 n = " + n + "; index1 = "+ index1);
}
if (n == index1){
TabLine1.push(point);
TabLine2.push(point);
log("2 n = " + n + "; index1 = "+ index1 );
}
if ((index1 < n) && (n < index2)){
TabLine2.push(point);
log("3 n = " + n + "; index2 = "+ index2);
}
if (n == index2){
TabLine1.push(point);
TabLine2.push(point);
log("4 n = " + n + "; index2 = "+ index2);
}
if (index2 < n){
TabLine1.push(point);
log("5 n = " + n + "; index1 = "+ index1);
}
}
var LineString1 = new OpenLayers.Geometry.LinearRing(TabLine1);
var LineString2 = new OpenLayers.Geometry.LinearRing(TabLine2);
log("TabLine1",TabLine1);
log("TabLine2",TabLine2);
log("LineString1",LineString1);
log("LineString2",LineString2);
/*i=0;
for (var m=0; m < parseInt(segLineString.components.length-1); m++)
{
segLine.components["0"] = segLineString.components[m].clone();
segLine.components["1"] = segLineString.components[m+1].clone();
var point = intersectPoint[i].intersect;
var contains = segLine.containsPoint(point);
log("segLine.containsPoint(point)",contains);
if (contains != false)
{
intersectLine.push(intersectPoint[i]);
i++;
}else
}
log("intersectLine",intersectLine);
*/
/*var m=0;
do{
for (var n=0; n < intersectPoint.length; n++)
{
if ((m << intersectPoint[n].newIndex) || (m >> intersectPoint[n].newIndex))
{
}
if (m == intersectPoint[n].newIndex)
{
}
if ((m intersectPoint[n].newIndex) || (m >> intersectPoint[n].newIndex))
{
}
}
m++;
}while (m < parseInt(segLineString.components.length-1));
*/
/*i=1;
for (var m=0; m < parseInt(poiLineString.components.length-1); m++)
{
point = segLineString.components[m].clone();
index=i;
intersectLineString.addComponent(point, index);
i++;
}
log("intersectLineString",intersectLineString);
*/
/*
var entryExitPoints = {};
entryExitPoints.entry = poi.attributes.entryExitPoints[0].entry;
entryExitPoints.exit = poi.attributes.entryExitPoints[0].exit;
entryExitPoints.name = poi.attributes.entryExitPoints[0].name;
point = {};
point.x = poi.attributes.entryExitPoints[0].point.x;
point.y = poi.attributes.entryExitPoints[0].point.y;
entryExitPoints.point = new OpenLayers.Geometry.Point(point);
log("poi.attributes.entryExitPoints[0]",poi.attributes.entryExitPoints[0]);
log("entryExitPoints",entryExitPoints);
*/
poiGeo = new OpenLayers.Geometry.Polygon(LineString1);
wazeModel.actionManager.add(new WazeActionUpdateFeatureGeometry(poi, Waze.model.venues,oldPoiGeo,poiGeo));
clonePoi = new WazefeatureVectorLandmark();
var oldClonePoi = clonePoi.clone();
var clonePoiAttr = clonePoi.attributes;
var oldClonePoiAttr = clonePoi.attributes;
clonePoiAttr.adLocked = poi.attributes.adLocked;
clonePoiAttr.aliases = poi.attributes.aliases;
clonePoiAttr.approved = poi.attributes.approved;
clonePoiAttr.categories = poi.attributes.categories;
clonePoiAttr.description = poi.attributes.description;
clonePoiAttr.externalProviderIDs = poi.attributes.externalProviderIDs;
clonePoiAttr.houseNumber = poi.attributes.houseNumber;
clonePoiAttr.openingHours = poi.attributes.openingHours;
clonePoiAttr.lockRank = poi.attributes.lockRank;
clonePoiAttr.name = poi.attributes.name;
clonePoiAttr.residential = poi.attributes.residential;
clonePoiAttr.phone = poi.attributes.phone;
clonePoiAttr.services = poi.attributes.services;
clonePoiAttr.url = poi.attributes.url;
//clonePoiAttr.entryExitPoints.push(entryExitPoints);
//clonePoiAttr.images = poi.attributes.images;
clonePoi.attributes.geometry = new OpenLayers.Geometry.Polygon(LineString2);
log("clonePoi",clonePoi);
wazeModel.actionManager.add(new WazeActionAddLandmark(clonePoi));
var streetName='';
var street=wazeModel.streets.objects[poi.attributes.streetID];
if (street.isEmpty==false)
streetName=street.name;
var cityName='';
var city=wazeModel.cities.objects[street.cityID];
if (city.isEmpty==false)
cityName=city.name;
var countryID=wazeModel.countries.objects[street.countryID];
var newAtts={streetName: streetName, emptyStreet: street.isEmpty, cityName: cityName, emptyCity: city.isEmpty, stateID: city.stateID, countryID: city.countryID};
wazeModel.actionManager.add(new WazeActionUpdateFeatureAddress(clonePoi, newAtts, {streetIDField: 'streetID'} ));
}
function intersection(D1, D2)
{
var a,b,c,d,x,y;
var seg = {}; //{x1, y1, x2, y2};
var seg1 = {}; //{x1, y1, x2, y2};
var seg2 = {}; //{x1, y1, x2, y2};
var options = {};
options.point = true;
if (D1.components[0].x < D1.components[1].x)
{
seg1.x1 = D1.components[0].x;
seg1.y1 = D1.components[0].y;
seg1.x2 = D1.components[1].x;
seg1.y2 = D1.components[1].y;
}else if (D1.components[0].x > D1.components[1].x)
{
seg1.x1 = D1.components[1].x;
seg1.y1 = D1.components[1].y;
seg1.x2 = D1.components[0].x;
seg1.y2 = D1.components[0].y;
}
if (D2.components[0].x < D2.components[1].x)
{
seg2.x1 = D2.components[0].x;
seg2.y1 = D2.components[0].y;
seg2.x2 = D2.components[1].x;
seg2.y2 = D2.components[1].y;
}else if (D2.components[0].x > D2.components[1].x)
{
seg2.x1 = D2.components[1].x;
seg2.y1 = D2.components[1].y;
seg2.x2 = D2.components[0].x;
seg2.y2 = D2.components[0].y;
}
return OpenLayers.Geometry.segmentsIntersect(seg1,seg2,options);
/*
a = (seg1.y2 - seg1.y1) / (seg1.x2-seg1.x1);
b = seg1.y1 - a*seg1.x1;
c = (seg2.y2 - seg2.y1) / (seg2.x2-seg2.x1);
d = seg2.y1 - a*seg2.x1;
if (a!=c)
{ //y = a*x+b = c*x+d
x=(d-b)/(a-c);
y=a*x+b;
var point = new OpenLayers.Geometry.Point();
point.x = x;
point.y = y;
return point;
}else return new OpenLayers.Geometry.Point();
*/
}
WMESP_bootstrap();