WME Reverse Nodes

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

目前为 2016-08-18 提交的版本。查看 最新版本

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


function WRNAB_Injected()
{
  
var WRNAB_version = "0.6";
var debug = false;

/* bootstrap */
function WRNAB_bootstrap(){
	if (typeof(unsafeWindow) === "undefined"){
		unsafeWindow = ( function () {
			var dummyElem = document.createElement('p');
			dummyElem.setAttribute('onclick', 'return window;');
			return dummyElem.onclick();
		}) ();
	}
  /* begin running the code! */
	log("Start");
	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 Reverse Nodes AB v" + WRNAB_version + " - " + msg);
  else if(debug)
     console.debug("WME Reverse Nodes AB v" + WRNAB_version + " - " + msg + " " ,obj);
  
}
    



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

function initialize()
{
    initializeWazeObjects();   
}

function waitForObject(object)
{
    var obj=null;
    if (debug) 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;
    }
    if (debug) 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: "WazeLoginManager",										r: false},
	  {o: "Waze.selectionManager",							s: "WazeSelectionManager",								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: "Waze.loginManager.user",             s: "me",															r: false},
    {o: "me.rank",									          s: "ul",															r: false},
    {o: "me.isAreaManager",					          s: "uam",															r: false},
	  {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()
{
    log('WazeSelectionManager',WazeSelectionManager);
    if (WazeSelectionManager.selectedItems.length!=1)
        return;
    var selectedObject = WazeSelectionManager.selectedItems[0].model;
    if (selectedObject.type!="segment")
        return;
    log('uam', uam);
		if (!uam) 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()
{
		
    WazeSelectionManager.events.register("selectionchanged", null, WRNAB_newSelectionAvailable);

    log('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;
    if (!uam) rep = false;
    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 (WazeSelectionManager.selectedItems.length!=1)
        return;
    var seg =  wazeModel.segments.get(WazeSelectionManager.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);
    log("ndA", ndA);
    log("ndB", ndB);
    // 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 Screen!");
    }
    else
    {
        log("OUT of Screen");
        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;
		//var fromConnections = attr.toConnections.clone();
    //var toConnections = attr.fromConnections.clone();
		newAttr.fwdDirection = attr.revDirection;
    newAttr.revDirection = attr.fwdDirection;
    newAttr.fwdTurnsLocked = attr.revTurnsLocked;
    newAttr.revTurnsLocked = attr.fwdTurnsLocked;
    newAttr.fwdMaxSpeed = attr.revMaxSpeed;
    newAttr.revMaxSpeed = attr.fwdMaxSpeed;
    newAttr.fwdMaxSpeedUnverified = attr.revMaxSpeedUnverified;
    newAttr.revMaxSpeedUnverified = attr.fwdMaxSpeedUnverified;
    newAttr.fwdRestrictions = attr.revRestrictions.clone();
    newAttr.revRestrictions = attr.fwdRestrictions.clone();
    
    
		log("seg",seg);
		log("attr",attr);
		log("newAttr", newAttr);
		log("fromConnections", fromConnections);
		log("toConnections", toConnections);
		
		//on inverse la géométrie du segment
		var geo = seg.geometry.clone();
		geo.components.reverse();
		
    // controle de position
		var nbPoints = geo.components.length-1;
		if (!geo.components[0].equals(ndB.attributes.geometry)){
		  if (debug) log("point 0 et dif de node A");
		  var delta = {x:0, y:0};
		  delta.x =ndB.attributes.geometry.x - geo.components[0].x;
		  delta.y = ndB.attributes.geometry.y - geo.components[0].y;
		  geo.components[0].move(delta.x, delta.y);
		} 
		if (!geo.components[nbPoints].equals(ndA.attributes.geometry)){
		  if (debug) log("point "+nbPoints+ " est dif de node B");
		  var delta = {x:0, y:0};
		  delta.x = ndA.attributes.geometry.x - geo.components[nbPoints].x;
		  delta.y = ndA.attributes.geometry.y - geo.components[nbPoints].y;
		  geo.components[nbPoints].move(delta.x, delta.y);
		  
		}
		
		// maj de la géo du seg
		wazeModel.actionManager.add(new WazeUpdateSegmentGeometry (seg,seg.geometry,geo));
		

		// On reconecte le segment
		wazeModel.actionManager.add(new WazeActionConnectSegment(ndB, seg));
		wazeModel.actionManager.add(new WazeActionConnectSegment(ndA, seg));
		
		//on replace les paramètre inversé
		wazeModel.actionManager.add(new WazeActionUpdateObject(seg, newAttr));
		
		//on replace les autorisations sortantes
		for (var sid  in fromConnections)
    {
      if (debug) log("attr.id: " + attr.id + " --> NodeA --> sid: " + sid); 
      wazeModel.actionManager.add(new WazeActionModifyConnection(attr.id, ndB, sid, true));
    }
    for (var sid  in toConnections)
    {
      if (debug) log("attr.id: " + attr.id + " --> NodeB -->  sid: " + sid); 
      wazeModel.actionManager.add(new WazeActionModifyConnection(attr.id, ndA, sid, true));
    }
    
		//on replace les autorisations entrantes
		log("ndB", ndB);
  	for (var s=0; s<sconB.length; s++)
    { 
  	  if (debug) log("sconB["+s+"] :" + sconB[s] + " nodeA: " + 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));
   	}
		log("ndA", ndA);
  	for (var s=0; s<sconA.length; s++)
    { 
      if (debug) log("sconA["+s+"] :" + sconA[s] + " nodeB: " + 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));
		}
		log('Invert node for segment '+attr.id+': Ok');

}



WRNAB_bootstrap();

}

var WRNAB_Injected_script = document.createElement("script");
WRNAB_Injected_script.textContent = '' + WRNAB_Injected.toString() + ' \n' + 'WRNAB_Injected();';
WRNAB_Injected_script.setAttribute("type", "application/javascript");
document.body.appendChild(WRNAB_Injected_script);

QingJ © 2025

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