WME Reverse Nodes AB

Serves to reverse the nodes A and B of a segment, in order to better manage restrictions on mutiples segments.

目前為 2015-12-23 提交的版本,檢視 最新版本

// ==UserScript==
// @name             WME Reverse Nodes AB
// @name:fr          WME Reverse Nodes AB
// @description		   Serves to reverse the nodes A and B of a segment, in order to better manage restrictions on mutiples segments.
// @description:fr   Sert à inverser les nodes A et B d'un segment, dans le but de mieux gérer les restrictions sur segments mutiples.
// @include          https://www.waze.com/editor/*
// @include          https://www.waze.com/*/editor/*
// @include          https://editor-beta.waze.com/*
// @exclude          https://www.waze.com/user/*
// @exclude          https://www.waze.com/*/user/*
// @namespace        WME_Reverse_Nodes_AB
// @version          0.1
// @grant            none
// ==/UserScript==

var WRNAB_version = "0.1";
var debug = false;

/* bootstrap */
function WRNAB_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);
  log("Start");
}

//==========  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 Invert Nodes v" + WRNAB_version + " - " + msg);
  else if(debug)
     console.debug("WME Invert Nodes v" + WRNAB_version + " - " + msg + " " ,obj);
  
}
    



//==========  /Helper ==============================//

function initialize()
{
    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/Action/UpdateObject",					s: "WazeActionUpdateObject"},
                     {o: "Waze/Action/UpdateSegmentGeometry", s: "WazeUpdateSegmentGeometry"},
                     {o: "Waze/Action/ModifyConnection",			s: "WazeActionModifyConnection"},
                     {o: "Waze/Action/ConnectSegment",			  s: "WazeActionConnectSegment"},
                     {o: "Waze/Action/ModifyAllConnections",	s: "WazeActionModifyAllConnections"},
                     {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()
{
  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: "Waze.loginManager",									s: "loginManager",										r: false},
	  {o: "Waze.selectionManager",							s: "selectionManager",								r: false},
	  {o: "Waze/Action/UpdateObject",						s: "WazeActionUpdateObject",					r: true},
	  {o: "Waze/Action/UpdateSegmentGeometry",  s: "WazeUpdateSegmentGeometry",       r: true},
		{o: "Waze/Action/ConnectSegment",			    s: "WazeActionConnectSegment",        r: true},
	  {o: "Waze/Action/ModifyConnection",		    s: "WazeActionModifyConnection",	    r: true},
	  {o: "Waze/Action/ModifyAllConnections",		s: "WazeActionModifyAllConnections",	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;
    }
  
    WRNAB_Init();
}



function WRNAB_newSelectionAvailable()
{
    if (selectionManager.selectedItems.length!=1)
        return;
    var selectedObject = selectionManager.selectedItems[0].model;
    if (selectedObject.type!="segment")
        return;
    
    var attributes = selectedObject.attributes;
		log('attributes', attributes);
		
		if (attributes.fwdRestrictions.length > 0){
		  var fwdRestrictions = attributes.fwdRestrictions;
		}
		if (attributes.revRestrictions.length > 0){
		  var revRestrictions = attributes.revRestrictions;
		}
		
    var editPanel=getId('edit-panel');
    if (editPanel.firstElementChild.style.display=='none')
        window.setTimeout(WRNAB_newSelectionAvailable, 100);
    
    // ok: 1 selected item and pannel is shown
    
    
    
    if (selectedObject.type=="segment")
    {
        item=getId("segment-edit-general");
        
        var WRNAB_Controle=document.createElement('Div');
        WRNAB_Controle.id="WRNAB-Controle";

		    WRNAB_Controle.innerHTML='<input type="button" id="_btnInvertAB" value="Reverse Nodes A/B">';
				
		    item.appendChild(WRNAB_Controle);
        
        getId("_btnInvertAB").onclick=invertNodeAB;
        log("wazeModel.actionManager",wazeModel.actionManager);
    }
    
}

function WRNAB_Init()
{
		log('Initialise');

    selectionManager.events.register("selectionchanged", null, WRNAB_newSelectionAvailable);
    
    log("WME Invert Nodes v" + WRNAB_version + "init done.");

}

function onScreen(obj)
{
    if (obj.geometry)
    {
        return(wazeMap.getExtent().intersectsBounds(obj.geometry.getBounds()));
    }
    return false;
}

function isSegmentEditable(seg)
{
    var rep = true;
    if (seg==null) return false;
    //if (Waze.loginManager.user.isCountryManager() ) rep = true;
    var ndA = wazeModel.nodes.get(seg.attributes.fromNodeID);
    var ndB = wazeModel.nodes.get(seg.attributes.toNodeID);
    
    if ((seg.attributes.permissions == 0) || (seg.attributes.hasClosures))
      rep = false;
    
    if ((ndA.attributes.permissions == 0) || (seg.attributes.hasClosures))
      rep = false;
    
    if ((ndB.attributes.permissions == 0) || (seg.attributes.hasClosures))
      rep = false;

    return rep;
}

function invertNodeAB()
{
    if (selectionManager.selectedItems.length!=1)
        return;
    var seg =  wazeModel.segments.get(selectionManager.selectedItems[0].model.attributes.id);
    if (seg.type!="segment")
        return;
    
    var attr = seg.attributes;
    log("seg",seg);
		log("attr",attr);
		
		
		var sid = attr.id;
		
    // si non nomme, on touche pas:
    if (attr.primaryStreetID==null)
    {
        log("Unnamed segment. Do not put my name on it!");
        return;
    }
    
    // si locke: on edite pas
    /*if ((attr.lockRank==null && attr.rank>usrRank) ||
        (attr.lockRank!=null && attr.lockRank>usrRank)) 
    {
        log("locked: " + attr.rank + " " + attr.lockRank);
        continue;
    }
    */
    
    //var ndA = wazeModel.nodes.objects[attr.fromNodeID];
    //var ndB = wazeModel.nodes.objects[attr.toNodeID];
    var ndA = wazeModel.nodes.get(attr.fromNodeID);
    var ndB = wazeModel.nodes.get(attr.toNodeID);
    
    
    // verification de pbs sur nodes (unterminated roads par ex)
    if (!ndA || !ndB) 
    {
        log("Bad nodes: A=" + ndA + " B=" + ndB);
        return;
    }        


    // On verifie que le segment est affiche a l'ecran
    if (onScreen(ndA) && onScreen(ndB))
    {
        log("IN");
    }
    else
    {
        log("OUT");
        return;
    }
    
    // On verifie que le segment est éditable
    if (!isSegmentEditable(seg))
    {
        log("Not editable!");
        return;
    }
        
    // On mémorise les directions autorisées vers le segment 
    var sconA=[];
    var sconB=[];
    // pour les segments connecté à la node A
    for (var s=0; s<ndA.attributes.segIDs.length; s++)
    {
      var scon=ndA.attributes.segIDs[s];
      if (wazeModel.segments.objects[scon].attributes.fromConnections.hasOwnProperty(attr.id))
        sconA.push(scon);
      if (wazeModel.segments.objects[scon].attributes.toConnections.hasOwnProperty(attr.id))
        sconA.push(scon);
    }
    // pour les segments connecté à la node B    
    for (var s=0; s<ndB.attributes.segIDs.length; s++)
    {
      var scon=ndB.attributes.segIDs[s];
      if (wazeModel.segments.objects[scon].attributes.fromConnections.hasOwnProperty(attr.id))
        sconB.push(scon);
        
      if (wazeModel.segments.objects[scon].attributes.toConnections.hasOwnProperty(attr.id))
        sconB.push(scon);
    }
    log("sconA",sconA);
    log("sconB",sconB);
    

		// Mémorisation des paramètre du segment pour les reporter après changement de sens
		var newAttr={};
		var fromConnections = attr.toConnections;
    var toConnections = attr.fromConnections;
		newAttr.fwdTurnsLocked = attr.revTurnsLocked;
    newAttr.revTurnsLocked = attr.fwdTurnsLocked;
    newAttr.fwdDirection = attr.revDirection;
    newAttr.revDirection = attr.fwdDirection;
    newAttr.fwdMaxSpeed = attr.revMaxSpeed;
    newAttr.revMaxSpeed = attr.fwdMaxSpeed;
    newAttr.fwdRestrictions = attr.revRestrictions;
    newAttr.revRestrictions = attr.fwdRestrictions;
    
    
		log("seg",seg);
		log("attr",attr);
		log("newAttr", newAttr);
		
		
		//on inverse la géométrie du segment
		var geo = seg.geometry.clone();
		geo.components.reverse();
		wazeModel.actionManager.add(new WazeUpdateSegmentGeometry (seg,seg.geometry,geo));
		
		// On reconecte le segment
		wazeModel.actionManager.add(new WazeActionConnectSegment(ndA, seg));
		wazeModel.actionManager.add(new WazeActionConnectSegment(ndB, seg));
		
		//on replace les paramètre inversé
		wazeModel.actionManager.add(new WazeActionUpdateObject(seg, newAttr));
		
		//on replace les autorisations sortantes
		for (var sid  in fromConnections)
    {
      log("attr.id: " + attr.id + " -  sid: " + sid); 
      wazeModel.actionManager.add(new WazeActionModifyConnection(attr.id, ndB, sid, true));
    }
    for (var sid  in toConnections)
    {
      log("attr.id: " + attr.id + " -  sid: " + sid); 
      wazeModel.actionManager.add(new WazeActionModifyConnection(attr.id, ndA, sid, true));
    }
    
		//on replace les autorisations entrantes
		for (var s=0; s<sconB.length; s++)
    { 
  		log("ndB", ndB);
  		log("sconB["+s+"] :" + sconB[s] + " nodeB: " + ndB.attributes.id + " attr.id: " + attr.id);
  		wazeModel.actionManager.add(new WazeActionModifyConnection(sconB[s], ndB, attr.id, false));
   		wazeModel.actionManager.add(new WazeActionModifyConnection(sconB[s], ndB, attr.id, true));
   	}
		for (var s=0; s<sconA.length; s++)
    { 
      log("ndA", ndA);
  		log("sconA["+s+"] :" + sconA[s] + " nodeA: " + ndA.attributes.id + " attr.id: " + attr.id);
  		wazeModel.actionManager.add(new WazeActionModifyConnection(sconA[s], ndA, attr.id, false));
			wazeModel.actionManager.add(new WazeActionModifyConnection(sconA[s], ndA, attr.id, true));
		}
		
}



WRNAB_bootstrap();



QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址