WME Split POI

Split POI with a new seg

目前为 2015-10-11 提交的版本。查看 最新版本

// ==UserScript==
// @name					 WME Split POI
// @namespace			 https://greasyfork.org/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 initialize() */
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);
}
function debuglog(msg, obj)
{
  if ( LevelAutorise > 1)
  { 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()
{
    debuglog ("init");
    initializeWazeObjects();   
    initWazeAPI(emptyFunc);
    
}

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;
            }
        }
    }
    debuglog("wazeAPI:", wazeAPI);
    handler();
    
}

function waitForObject(object)
{
    var obj=null;
    debuglog ("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'));
    		debuglog("obj", obj);
    }
        //obj=require(object.o);
		else
        obj=eval("typeof(unsafeWindow." + object.o.replace(/\//g, '.') + ")");
    if(obj === "undefined")
    {
        debuglog(object.o + ' KO');
        window.setTimeout(waitForObject.caller, 500);
        return false;
    }
    debuglog(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.model",													s: "wazeModel",												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/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}
				  ];
        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;
    }
  
		selectionManager.events.register("selectionchanged", null, WMESP_newSelectionAvailable);
    
    log("init done.");
}

function WMESP_newSelectionAvailable()
{
    if (selectionManager.selectedItems.length!=1)
        return;
    var selectedObject = selectionManager.selectedItems[0].model;
    if (selectedObject.type!="venue")
        return;
    
    var attributes = selectedObject.attributes;
		
		if (!attributes.geometry.hasOwnProperty("components"))
		  return;
		
		if (!((attributes.categories == "NATURAL_FEATURES" ) || (attributes.categories == "FOREST_GROVE") || (attributes.categories == "RIVER_STREAM" ) || (attributes.categories == "CANAL" )))
		  return;
		
    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))
        return;
    
    if (selectedObject.type=="venue")
    {
        item=getId("landmark-edit-general");
        
        var attSection = getElementsByClassName("attributes-form side-panel-section", item);
        var btnResidential = getElementsByClassName("btn-link toggle-residential",item);
        var parent1 = btnResidential[0].parentNode;
        var parent = parent1.parentNode;
        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);
        getId("_btnSplitPOI").onclick=SplitPOI;
    }
    
}


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.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(); 
		var poiLineString = poiGeo.components[0].clone();
    
    var poiLine = new OpenLayers.Geometry.LinearRing();
    var segLine = new OpenLayers.Geometry.LinearRing();
   
    var intersectPoint = [];
    var intersectLine  = [];
    
    // 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();
      
      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();
        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++;
    }
    
    // création des deux nouvelles géométries
    var TabLine1 = [];
    var TabLine2 = [];
    
    var index1 = parseInt(intersectPoint[0].newIndex);
    var index2 = parseInt(intersectPoint[1].newIndex);
    
    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);
      }
      if (n == index1){
        TabLine1.push(point);
        TabLine2.push(point);
      }
      if ((index1 < n) && (n < index2)){
        TabLine2.push(point);
      }
      if (n == index2){
        TabLine1.push(point);
        TabLine2.push(point);
      }
      if (index2 < n){
        TabLine1.push(point);
      }
    }
    var LineString1 = new OpenLayers.Geometry.LinearRing(TabLine1);
    var LineString2 = new OpenLayers.Geometry.LinearRing(TabLine2);
    
    poiGeo = new OpenLayers.Geometry.Polygon(LineString1);
            
    wazeModel.actionManager.add(new WazeActionUpdateFeatureGeometry(poi, Waze.model.venues,oldPoiGeo,poiGeo));
    
    // Création du nouveau poi
    clonePoi = new WazefeatureVectorLandmark();
    
    var clonePoiAttr = 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 = poi.attributes.entryExitPoints;
    //clonePoiAttr.images = poi.attributes.images;
    
    clonePoi.attributes.geometry = new OpenLayers.Geometry.Polygon(LineString2);
    
    wazeModel.actionManager.add(new WazeActionAddLandmark(clonePoi));
    
    // copie du nom et mise à jour du nouveau poi
    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);
          
   
}    


WMESP_bootstrap();