您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
This script add functionnality to select and modify roads
当前为
// ==UserScript== // @name WME Select Same Type Roads // @author buchet37 // @namespace https://greasyfork.org/users/4062 // @description This script add functionnality to select and modify roads // @match https://world.waze.com/editor/* // @match https://www.waze.com/editor/* // @match https://world.waze.com/map-editor/* // @match https://www.waze.com/map-editor/* // @include https://*.waze.com/editor/* // @include https://*.waze.com/*/editor/* // @include https://*.waze.com/map-editor/* // @include https://*.waze.com/beta_editor/* // @include https://descarte*.waze.com/beta/* // @include https://editor-beta.waze.com/* // @grant none // @version 4.9.10 // ==/UserScript== // Based on Street to River ( http://userscripts.org/scripts/show/122049 ) // Thanks to alcolo47 (some functions are based on WME Extented Tools) // Thanks to gdu1971, bgodette, Timbones for part of code // Adapted by buchet37 for "Select Same Type Road" // Mini howto: // 1) install this script as greasemonkey script or chrome extension // 2) Select 2 segments // 3) Click the "Select Roads A<=>B" button // The script will select all same type road between A and B with a limit of 50 segments if ('undefined' == typeof __RTLM_PAGE_SCOPE_RUN__) { (function page_scope_runner() { // If we're _not_ already running in the page, grab the full source // of this script. var my_src = "(" + page_scope_runner.caller.toString() + ")();"; // Create a script node holding this script, plus a marker that lets us // know we are running in the page scope (not the Greasemonkey sandbox). // Note that we are intentionally *not* scope-wrapping here. var script = document.createElement('script'); script.setAttribute("type", "text/javascript"); script.textContent = "var __RTLM_PAGE_SCOPE_RUN__ = true;\n" + my_src; // Insert the script node into the page, so it will run, and immediately // remove it to clean up. Use setTimeout to force execution "outside" of // the user script scope completely. setTimeout(function() { document.body.appendChild(script); document.body.removeChild(script); }, 0); })(); // Stop running, because we know Greasemonkey actually runs us in // an anonymous wrapper. return; } // function t(toto) { // return require.modules[eval(toto)]; //} function selectSameTypeRoad() { var defaultWidth = "15 m"; //Default Width is equal to 15m // ***************** COMPATIBILITY WITH NEW EDITOR *********** var WazeActionCreateObject = require("Waze/Action/CreateObject"); var WazeActionCreateRoundabout = require ("Waze/Action/CreateRoundabout"); var WazeActionDeleteSegment = require ("Waze/Action/DeleteSegment"); var WazeActionModifyConnection = require ("Waze/Action/ModifyConnection"); var WazeActionMultiAction = require ("Waze/Action/MultiAction"); var WazeActionUpdateObject = require("Waze/Action/UpdateObject"); var WazeActionUpdateSegmentGeometry = require("Waze/Action/UpdateSegmentGeometry"); var WazeFeatureVectorLandmark = require("Waze/Feature/Vector/Landmark"); var WazeActionAddLandmark = require("Waze/Action/AddLandmark"); // ***************************************************************** insertButton() function insertButton() { if(document.getElementById('WME_SSTR_All') != null) return; var chk1 = $('<Label style="font-weight:normal"><input type="checkbox"; style="vertical-align: middle;margin: 0px;" id="WME_SSTR_enable" title="Enable or Disable WME SSTR">On-Off </input></Label>'); var chk2 = $('<Label style="font-weight:normal"><input type="checkbox"; style="vertical-align: middle;margin: 0px;" id="WME_SSTR_SmthRvr" title="Check for smoothing">Smooth</input></Label>'); var chk3 = $('<Label style="font-weight:normal"><input type="checkbox"; style="vertical-align: middle;margin: 0px;" id="WME_SSTR_SmthPlt" title="Check for smoothing">Smooth</input></Label>'); var url1 = $('<div style="font-size:12px;display: inline;"> <u><i><a href="https://greasyfork.org/scripts/4715-wme-select-same-type-roads" target="_blank">Select Same Type Road V4.9.10</a></i></u>'); var btn1 = $('<button class="btn btn-default" style="padding:0px 10px; height:22px" title="Select 1 or more segments and click this button">Select Same Type Roads</button>'); var btn2 = $('<button class="btn btn-default" style="padding:0px 10px; height:22px" title="Select adjacent segment from node A">Side A</button>'); var btn3 = $('<button class="btn btn-default" style="padding:0px 10px; height:22px" title="Select adjacent segment from node B">Side B</button>'); var btn4 = $('<button class="btn btn-default" style="padding:0px 10px; height:22px" title="Start from segment 1 to join Segment 2 (if possible)">1 => 2</button>'); var btn6 = $('<button class="btn btn-default" style="padding:0px 10px; height:22px" title="Create a ParkingLot from railroad geometry">Railroad => PkgLot</button>'); var btn7 = $('<button class="btn btn-default" style="padding:0px 10px; height:22px" title="Create a River from Street Geometry">Street => River</button>'); var btn8 = $('<button class="btn btn-default" style="padding:0px 10px; height:22px" title="Select road(s) to make an Overall Landmark">Do Landmark</button>'); var btn10= $('<button class="btn btn-default" style="padding:0px 10px; height:22px" title="Make a new roundabout from 1 segment of an old one or a set of segments">Redo Roundabout</button>'); var btn12= $('<button class="btn btn-default" style="padding:0px 10px; height:22px" title="click this button to suppress road geometry">Clear Road Geometry</button>'); var btn13= $('<button class="btn btn-default" style="padding:0px 10px; height:22px" title="click this button to allow "All drives" and "All Turns" on selected roads)">All drives on Selection</button>'); btn1.click (select_same_type_roads); btn2.click (Side_A); btn3.click (Side_B); btn4.click (select_AB); btn6.click (Railroad_ParkingLot); btn7.click (Street_River); btn8.click (Roads_to_Interchange); btn10.click (Redo_RoundAbout); btn12.click (Clear_Road_Geometry); btn13.click (All_drives_on_Selection); var WME_SSTR_Menu = $ ('<div id="WME_SSTR_All" style="height: auto;width:100%;"/>'); var cnt0 = $('<section id="WME_SSTR_lnk" style="padding-top:2px"/>'); cnt0.append(chk1);cnt0.append(" ");cnt0.append(url1); var cnt1 = $('<section id="WME_SSTR" style="padding-top:2px"/>'); cnt1.append(btn1); var cnt2 = $('<section id="WME_SSTR_Side" style="padding-top:2px; padding-bottom:5px"/>'); cnt2.append(btn2); cnt2.append(" ");cnt2.append(btn3); var cnt3 = $('<section id="WME_SSTR_12" style="padding-top:2px; padding-bottom:5px"/>'); cnt3.append(btn4); var cnt4 = $('<section id="WME_SSTR_River" style="padding-top:2px"/>'); cnt4.append(btn7); cnt4.append(" ");cnt4.append(chk2); var cnt5 = $('<section id="WME_SSTR_Pklt" style="padding-top:2px"/>'); cnt5.append(btn6); cnt5.append(" ");cnt5.append(chk3); var cnt6 = $('<section id="WME_SSTR_Ldmk" style="padding-top:2px"/>'); cnt6.append(btn8); var cnt7 = $('<section id="WME_SSTR_Rdt" style="padding-top:2px; padding-bottom:5px"/>'); cnt7.append(btn10); var cnt8 = $('<section id="WME_SSTR_CrgAds" style="padding-top:2px"/>'); cnt8.append(btn12); cnt8.append(" ");cnt8.append(btn13); WME_SSTR_Menu.append(cnt0); WME_SSTR_Menu.append(cnt1); WME_SSTR_Menu.append(cnt2); WME_SSTR_Menu.append(cnt3); WME_SSTR_Menu.append(cnt4); // Problems in new editor WME_SSTR_Menu.append(cnt5); WME_SSTR_Menu.append(cnt6); WME_SSTR_Menu.append(cnt7); WME_SSTR_Menu.append(cnt8); // ******* Mise en place des buttons var WME_SSTR_MenuFlag = false, myDialogBoxFlag = false; function put_WME_SSTR_Menu() { // wait for 'sidebar' if (document.getElementById('sidebar')!=null) { if (document.getElementById('WME_JCB_All')!=null) { // si mon menu existe $("#WME_JCB_All").append('<hr style="margin-bottom:5px; margin-top:5px;width=100%;color:SkyBlue; background-color:SkyBlue; height:1px;">');} // on ajoute une barre else { var WME_JCB_Menu = $ ('<div id="WME_JCB_All" style="padding:2px 5px 2px 5px;margin:5px 0px 30px 0px;width:295px; border-width:3px; border-style:double;border-color: SkyBlue; border-radius:10px"/>'); $("#sidebar").append(WME_JCB_Menu); } $("#WME_JCB_All").append(WME_SSTR_Menu); // on ajoute le nemu CRN WME_SSTR_MenuFlag = true; } else { setTimeout (function () {put_WME_SSTR_Menu();}, 501); } } put_WME_SSTR_Menu(); // Boite d'alerte var myAlertBoxFlag = false; function put_myAlertBox() { if (document.getElementById('map-search')!=null) { if (document.getElementById('WME_JCB_AlertBox')==null) { var myAlertBox = $('<div id="WME_JCB_AlertBox" class="form-control search-query" style="opacity : 0.8;display :none; height: auto;min-height: 30px; position: absolute;top :16px; margin-left: 350px; margin-right: auto; "/>'); var myAlertTxt = $('<div id="WME_JCB_AlertTxt" style=" opacity : 1;display:inline;padding:0px 0px">City ID/'); myAlertBox.append(myAlertTxt); $("#map-search").append(myAlertBox) } myAlertBoxFlag = true; } else {setTimeout (function () {put_myAlertBox();}, 501);} } put_myAlertBox(); function start_init_WME_SSTR() { // si tous les boutons sont chargés on démarre le script if (WME_SSTR_MenuFlag && myAlertBoxFlag) { init_WME_SSTR(); } else {setTimeout(function () {start_init_WME_SSTR();}, 501);} } start_init_WME_SSTR(); } function Clear_Road_Geometry(ev) { if (Waze.selectionManager.selectedItems.length!=0) { if (confirm ("Do you want to clear the geometry for selected segments") ) { for (var i = 0; i < Waze.selectionManager.selectedItems.length; i++) { var seg = Waze.selectionManager.selectedItems[i].model; if (seg.type == "segment") { var newGeo = seg.geometry.clone(); newGeo.components.splice(1,newGeo.components.length -2); // on garde le 1er et le dernier point newGeo.components[0].calculateBounds(); newGeo.components[1].calculateBounds(); Waze.model.actionManager.add (new WazeActionUpdateSegmentGeometry (seg,seg.geometry,newGeo)); } } } } } function All_drives_on_Selection(ev) { if (Waze.selectionManager.selectedItems.length!=0) { var action = []; var nodeToAllowed = []; var selectRoadIDs = []; for (var i = 0; i < Waze.selectionManager.selectedItems.length; i++) { var seg = Waze.selectionManager.selectedItems[i].model; if (seg != null && seg.type == "segment" && !seg.attributes.locked && seg.attributes.junctionID == null) { selectRoadIDs.push (seg.getID()); action.push (new WazeActionUpdateObject( seg, {fwdDirection: true, revDirection: true})); // pass to two ways if (Waze.model.nodes.objects[seg.attributes.fromNodeID]!= null) { // store node A nodeToAllowed.push (seg.attributes.fromNodeID); } if (Waze.model.nodes.objects[seg.attributes.toNodeID]!= null) { // store node B nodeToAllowed.push (seg.attributes.toNodeID); } } } nodeToAllowed = areTwice (nodeToAllowed); // on ne traite que les segments inttermédiaires for (var l = 0; l < nodeToAllowed.length; l++) { var node = Waze.model.nodes.objects[nodeToAllowed[l]]; var roadIDs = node.attributes.segIDs; for (var j = 0; j < roadIDs.length; j++) { for (var k = 0; k < roadIDs.length; k++) { if (roadIDs[j]!= roadIDs[k] && isInArray (roadIDs[j],selectRoadIDs) && isInArray (roadIDs[k],selectRoadIDs)) { action.push (new WazeActionModifyConnection(roadIDs[j], node, roadIDs[k], true)); } } } } if (action.length !=0) { Waze.model.actionManager.add (new WazeActionMultiAction(action));} //alert ("On va au bout"); } } function areTwice (myArray) { var myNewArray = []; if (myArray.length > 0) { for (var i = 0; i < myArray.length-1; i++) { for (var j = i+1; j < myArray.length; j++) { if (myArray [i] == myArray[j]) { myNewArray.push(myArray [i]); } } } return delete_multi_Ids(myNewArray); } else { return (myArray); } } function Redo_RoundAbout (ev) { var selectedGood = (Waze.selectionManager.selectedItems.length!=0); if (selectedGood) { if (Waze.selectionManager.selectedItems[0].model.attributes.junctionID !=null) { var sel = Waze.selectionManager.selectedItems[0].model; var junc = Waze.model.junctions.objects[sel.attributes.junctionID]; var listRoadIds = junc.segIDs; } else { var listRoadIds = []; for (var i = 0; i < Waze.selectionManager.selectedItems.length; i++) { var sel = Waze.selectionManager.selectedItems[i].model; listRoadIds.push (sel.getID()); } } var oldRdt = extract_rdt (listRoadIds); if (oldRdt.higherRank == false) { var action = []; for (var j = 0; j < oldRdt.listRoadIds.length; j++) { var seg = Waze.model.segments.objects[oldRdt.listRoadIds[j]] action.push(new WazeActionDeleteSegment(seg)); // ******* Delete Roundabout } for (var i = 0; i < oldRdt.listAdjRoadIds.length; i++) { var seg = Waze.model.segments.objects[oldRdt.listAdjRoadIds[i].id]; var newGeo = seg.geometry.clone(); if (oldRdt.listAdjRoadIds[i].sideConnect == "A") { var index1 =0; var index2 =1; var nodeEnd = Waze.model.nodes.objects [seg.attributes.toNodeID]; } else { var index1 = newGeo.components.length-1; var index2 = newGeo.components.length-2; var nodeEnd = Waze.model.nodes.objects [seg.attributes.fromNodeID]; } if (nodeEnd !=null && nodeEnd.onScreen() && nodeEnd.attributes.segIDs.length <2) { action.push (new Waze.Action.UpdateObject(seg, {fwdDirection: true, revDirection: true}));} // dead-end is always two ways roads if (!seg.attributes.fwdDirection && !seg.attributes.revDirection) { // unknown roads are fixed to two ways roads action.push (new Waze.Action.UpdateObject(seg, {fwdDirection: true, revDirection: true}));} var deltaX = newGeo.components[index1].x - newGeo.components[index2].x; var deltaY = newGeo.components[index1].y - newGeo.components[index2].y; var angle = angleDeg (deltaX,deltaY); var meanExt = 0.10 * (oldRdt.rx + oldRdt.ry); newGeo.components[index1].x = newGeo.components[index1].x + meanExt* Math.cos(convertDegRad(angle)); newGeo.components[index1].y = newGeo.components[index1].y + meanExt* Math.sin(convertDegRad(angle)); newGeo.components[index1].calculateBounds(); action.push(new WazeActionUpdateSegmentGeometry (seg,seg.geometry,newGeo)); } Waze.model.actionManager.add (new WazeActionMultiAction(action)); // ******* Strech adjacent segments var R = {}; R.center = {x: oldRdt.centerX, y:oldRdt.centerY}; R.rx = Math.min (parseInt(144),oldRdt.rx); R.ry = Math.min (parseInt(144),oldRdt.ry); if (Math.abs (R.rx - R.ry) < (0.15 * R.rx)) { // if Rx near Ry => Circle with mean value R.rx = (R.rx + R.ry) / 2; R.ry = R.rx; } R.bounds = new OpenLayers.Bounds(R.center.x - R.rx, R.center.y - R.ry, R.center.x+R.rx, R.center.y + R.ry); var action = new WazeActionCreateRoundabout(R); Waze.model.actionManager.add (action); var rbtRoadIds = []; for (var j = 0; j < action.roundaboutSegments.length; j++) { // store new SegIds rbtRoadIds.push (action.roundaboutSegments[j].getID()); } newRdt = searchNewRdt (rbtRoadIds,oldRdt.primaryStreetID); var action = []; for (var k = 0; k < rbtRoadIds.length; k++) { var road = Waze.model.segments.objects[rbtRoadIds[k]]; action.push(new WazeActionUpdateObject(road, {roadType: newRdt.roadtype, level: newRdt.level, lockRank: "0"} )); if (oldRdt.primaryStreetID != null) { action.push(new WazeActionUpdateObject(road, {primaryStreetID: oldRdt.primaryStreetID})); } } Waze.model.actionManager.add(new WazeActionMultiAction(action)); select (rbtRoadIds); } else { alert ("Your ranking is not higher\nto redo this roundabout"); } } else { alert ("Incorrect Selection : \n\nOne segment must be selected \nOr It is not Roundabout Segment"); } } function searchNewRdt (listRdtSegIds,StreetID) { var roadpriority = []; roadpriority [1] = 0; //"Streets" roadpriority [2] = 1; //"Primary Street" roadpriority [3] = 3; //"Freeways" roadpriority [4] = 2; //"Ramps" roadpriority [6] = 3; //"Major Highway" roadpriority [7] = 2; //"Minor Highway" roadpriority [8] = 0; //"Dirt roads" roadpriority [18] = 0; //"Railroad" roadpriority [19] = 0; //"Runway/Taxiway" roadpriority [20] = 0; //"Parking Lot Road" roadpriority [5] = 0; //"Walking Trails" roadpriority [10] = 0; //"Pedestrian Bw" roadpriority [16] = 0; //"Stairway" roadpriority [17] = 0; //"Private Road" roadpriority [21] = 0; //"Service Road" var priorityToRoadtype = []; priorityToRoadtype [0] = 1; //"Streets" priorityToRoadtype [1] = 2; //"Primary Street" priorityToRoadtype [2] = 7; //"Minor Highway" priorityToRoadtype [3] = 6; //"Major Highway" var compteur = [0,0,0,0]; //array for number of roads by type var listRdtNodeIds = []; for (var i = 0; i < listRdtSegIds.length; i++) { var road = Waze.model.segments.objects[listRdtSegIds[i]]; if (road != null) { listRdtNodeIds.push (road.attributes.fromNodeID); listRdtNodeIds.push (road.attributes.toNodeID); } } listRdtNodeIds = delete_multi_Ids (listRdtNodeIds); var usedNodeIDs = []; usedNodeIDs.push.apply (usedNodeIDs,listRdtNodeIds); var rdt = {}; rdt.level = -5; var action = []; for (var j = 0; j <listRdtNodeIds.length; j++) { // Search connected Segments var node = Waze.model.nodes.objects[listRdtNodeIds[j]]; if (node != null) { var nbSegs = node.attributes.segIDs.length; for (var k = 0; k < nbSegs;k++) { var road = Waze.model.segments.objects[node.attributes.segIDs[k]]; if ((road != null) && (notInArray (road.getID(),listRdtSegIds))) { rdt.level = Math.max (rdt.level,road.attributes.level); if (road.attributes.roadType == 3 ) { // Freeways are not allowed in roundabout action.push (new Waze.Action.UpdateObject(road, {roadType: 6}));} if (notInArray(road.attributes.roadType,([1,2,3,4,6,7]))) { // Road type on roundabout should be at least "Street" action.push (new Waze.Action.UpdateObject(road, {roadType: 1}));} if (!road.attributes.fwdDirection && !road.attributes.revDirection) { // unknown roads are fixed to two ways roads action.push (new Waze.Action.UpdateObject(road, {fwdDirection: true, revDirection: true}));} if (road.attributes.primaryStreetID == null && StreetID != null) { // Unnamed Roadsd are named as the rdt action.push(new Waze.Action.UpdateObject(road, {primaryStreetID: StreetID}));} if (notInArray(road.attributes.fromNodeID,usedNodeIDs) || notInArray(road.attributes.toNodeID,usedNodeIDs)) { compteur [roadpriority[road.attributes.roadType]] ++; usedNodeIDs.push (usedNodeIDs, road.attributes.fromNodeID); usedNodeIDs.push (usedNodeIDs, road.attributes.toNodeID); } } } } } rdt.roadtype = priorityToRoadtype [0]; var foundMax = false; for (var k = 3; k > 0; k --) { if ((compteur[k] > 1) && (foundMax == false)) { rdt.roadtype = priorityToRoadtype [k]; foundMax = true; } else { compteur [k-1] = compteur[k-1] + compteur[k]; compteur [k] = 0; } } rdt.level ++; // up Roundabout level if (action.length !=0) {Waze.model.actionManager.add ( new Waze.Action.MultiAction(action));} // do modifications if there are return rdt; } function extractNodes (listRoadIds) { var nodeList = []; for (var i = 0; i<listRoadIds.length;i++) { var road = Waze.model.segments.objects[listRoadIds[i]]; if (road != null) { nodeList.push (road.attributes.fromNodeID); nodeList.push (road.attributes.toNodeID); } } return delete_multi_Ids (nodeList); } function extract_rdt (listIDs) { var rdt = {}; rdt.listAdjRoadIds = []; rdt.higherRank = false; rdt.listRoadIds = listIDs; var xmin = 10000000000000; var ymin = xmin; var xmax = -10000000000000; var ymax = xmax; for (var i = 0; i<rdt.listRoadIds.length;i++) { var road = Waze.model.segments.objects[rdt.listRoadIds[i]]; if (road != null) { rdt.higherRank = rdt.higherRank || road.isLockedByHigherRank(); for (var j = 0;j < road.geometry.components.length;j++) { xmin = Math.min (xmin, road.geometry.components[j].x); xmax = Math.max (xmax, road.geometry.components[j].x); ymin = Math.min (ymin, road.geometry.components[j].y); ymax = Math.max (ymax, road.geometry.components[j].y); } } } rdt.listNodeIds = extractNodes (rdt.listRoadIds); rdt.rx = (xmax-xmin)/2; rdt.ry = (ymax-ymin)/2; rdt.centerX = (xmin+xmax) / 2; rdt.centerY = (ymin+ymax) / 2; var roadIDs =[]; for (var i = 0; i <rdt.listNodeIds.length; i++) { // Search connected Segments var node = Waze.model.nodes.objects[rdt.listNodeIds[i]]; if (node != null) { var nbSegs = node.attributes.segIDs.length; roadIDs = roadIDs.concat(node.attributes.segIDs); //collect rioadsIds connect to rdt for (var j=0; j<nbSegs;j++) { var road = Waze.model.segments.objects[node.attributes.segIDs[j]]; if ((road != null) && (notInArray (road.getID(),rdt.listRoadIds))) { rdt.higherRank = rdt.higherRank || road.isLockedByHigherRank(); // test if locked at higher rank if (isInArray (road.attributes.fromNodeID,rdt.listNodeIds)) { rdt.listAdjRoadIds.push ({id:road.getID(),sideConnect :"A"}); } if (isInArray (road.attributes.toNodeID,rdt.listNodeIds)) { rdt.listAdjRoadIds.push ({id:road.getID(),sideConnect :"B"}); } } } } } var city_ID =[]; //search for primaryStreetID roadIDs = delete_multi_Ids(roadIDs); for (var i = 0; i <roadIDs.length; i++) { var sel = Waze.model.segments.objects[roadIDs[i]]; var streetID = sel.attributes.primaryStreetID; if (streetID && Waze.model.streets.objects[streetID]) { var street = Waze.model.streets.objects[streetID]; if (street.cityID && Waze.model.cities.objects[street.cityID]) { city_ID.push(street.cityID); } } } city_ID = delete_multi_Ids (city_ID); var cityName = ""; var city = Waze.model.cities.objects[city_ID[0]]; if (city_ID.length == 1 && city && city.name) { if (city.name!=""){cityName = city.name;} } var state_ID = (city.stateID) ? city.stateID : ""; var country_Id = (city.countryID) ? city.countryID : ""; if (city.stateID && city.countryID) { var newCityID = SearchCityID (city.countryID, city.stateID, cityName); rdt.primaryStreetID = searchPrimaryID (newCityID, ""); } return rdt; } function SearchCityID (country_ID, state_ID, cityName) { var emptyct = (cityName===""); var fattr = {countryID: country_ID, stateID: state_ID, isEmpty: emptyct, name : cityName }; var city = Waze.model.cities.getByAttributes(fattr); if (city.length === 0) { myAlert ("Create new city: "+cityName); var f = new WazeActionCreateObject(WazeModelObjectType.CITY, { countryID: country_ID,stateID: state_ID,isEmpty: emptyct,name: cityName}); Waze.model.actionManager.add(f); return f.newObject.getID(); } if (city.length === 1) {return city[0].getID();} if (city.length > 1) { myAlert ("Problems with cityID : "+city.length+" cities with same name. Please save and redo"); return null; } return null; } function searchPrimaryID (newCityID, newStreetName) { if (newCityID == null) { return null; } if (newStreetName == null) {newStreetName ="";} var emptyst = (newStreetName ==""); var fattr = {cityID: newCityID, isEmpty: emptyst}; if (emptyst == false) { fattr.name = newStreetName;} var st = Waze.model.streets.getByAttributes(fattr); if (st.length === 0) { myAlert ("Create new street: "+newCityName+" "+newStreetName); var a = new WazeActionCreateObject(WazeModelObjectType.STREET, { name: newStreetName,isEmpty: emptyst,cityID: newCityID}); Waze.model.actionManager.add(a); var newPrimaryStreetID = a.newObject.getID(); } if (st.length === 1) {var newPrimaryStreetID = st[0].getID();} if (st.length > 1) { myAlert ("Problems with StreetID : "+st.length+" streets with same name. Please save and redo"); return null; } return newPrimaryStreetID; } // function captureCity (roadListID) { // var road = {}; // road.NoCityNoStreet = null; // road.CityNoStreet = null; // road.altStreetID = null; // for (var i = 0; i < roadListID.length;i++) { // var road1 = Waze.model.segments.objects[roadListID[i]]; // if (road1 != null && road1.attributes.primaryStreetID!= null) { // var adress = road1.getAddress(); // road.altStreetID = road1.attributes.primaryStreetID; // if ((adress.city.isEmpty ) && (adress.street.isEmpty)) { // road.NoCityNoStreet = road1.attributes.primaryStreetID;} // if ((adress.city.name != null) && (adress.city.name != "") && (adress.street.isEmpty)) { // road.CityNoStreet = road1.attributes.primaryStreetID;} // } // } // return road; // } function Roads_to_Interchange(ev) { var foundSelectedSegment = false; var selectedGood = (Waze.selectionManager.selectedItems.length>0); var roadIds = []; for (var i = 0; i<Waze.selectionManager.selectedItems.length;i++) { // Test if selection are segment var sel = Waze.selectionManager.selectedItems[i].model; selectedGood = ((selectedGood) && (sel.type == "segment")); if ((selectedGood)&& (sel.attributes.junctionID!=null)) { // if it is a roundabout var jId = sel.attributes.junctionID; var junc = Waze.model.junctions.objects[jId]; roadIds.push.apply (roadIds,junc.segIDs); // we add all segment of the roundabout } if (selectedGood) { roadIds.push ( sel.getID());} // stocke les segments } if ((selectedGood) &&( roadIds.length != 0)) { roadIds = delete_multi_Ids (roadIds); // delete double roads var totalPoints = []; var name; var leftEnv = []; var rightEnv = []; var typeLandmak; leftEnv.push ({x: 100000000000000,y:2000000000}); var yMax = -100000000000; //alert (roadIds); for (var k = 0; k<roadIds.length;k++) { var sel = Waze.model.segments.objects[roadIds[k]]; //alert (sel.getID()); if (name == null) {name = getStreet(sel).name;} if (typeLandmak == null) { switch (sel.attributes.roadType) { case 1: //"Streets" case 2: //"Primary Street" case 3: //"Freeways" case 4: //"Ramps" case 6: //"Major Highway" case 7: //"Minor Highway" typeLandmak = ["JUNCTION_INTERCHANGE"]; break;// Jonction/interchange case 8: //"Dirt roads" case 18: //"Railroad" case 19: //"Runway/Taxiway" case 20: //"Parking Lot Road" typeLandmak = ["PARKING_LOT"]; break; // ParkingLot case 5: //"Walking Trails" case 10: //"Pedestrian Bw" case 16: //"Stairway" case 17: //"Private Road" case 21: //"Service Road" typeLandmak = ["PARK"]; break; // Park } } for (var j = 0; j < sel.geometry.components.length;j++) { totalPoints.push (sel.geometry.components[j].clone()); if (leftEnv[0].y > sel.geometry.components[j].y) { // Stocke le Y mini leftEnv[0] = sel.geometry.components[j].clone(); rightEnv[0] = sel.geometry.components[j].clone(); } if (sel.geometry.components[j].y > yMax) { yMax = sel.geometry.components[j].y;} } } while ( rightEnv[rightEnv.length-1].y <yMax) { // traitement de la voie droite var anglemin = 190; for (var i = 0; i<totalPoints.length;i++) { if (totalPoints[i].y > rightEnv[rightEnv.length-1].y) { var deltaX = totalPoints[i].x - rightEnv[rightEnv.length-1].x; if (deltaX !=0) { var deltaY = totalPoints[i].y - rightEnv[rightEnv.length-1].y; var angle = angleDeg( deltaX , deltaY); if (angle < anglemin) { anglemin = angle; var iMin = i; } } } } rightEnv.push (totalPoints[iMin]); } while ( leftEnv[leftEnv.length-1].y <yMax) { // traitement de la voie droite var anglemax = 0; for (var i = 0; i<totalPoints.length;i++) { if (totalPoints[i].y > leftEnv[leftEnv.length-1].y) { var deltaX = totalPoints[i].x - leftEnv[leftEnv.length-1].x; if (deltaX !=0) { var deltaY = totalPoints[i].y - leftEnv[leftEnv.length-1].y; var angle = angleDeg( deltaX , deltaY); if (angle > anglemax) { anglemax = angle; var iMax = i; } } } } leftEnv.push (totalPoints[iMax]); } leftEnv.shift(); leftEnv.pop(); //On ote le premier et le dernier point( communs avec droite) rightEnv.push.apply (rightEnv,leftEnv.reverse ()); //on ajoute la partie Gauche var dummy = doLandmark (rightEnv,name,typeLandmak); // make the landmark alert("Successfully created Landmark");} else { alert("Incorrect Selection : \n\nOne segment must be selected \nOr It is not RoundAbout Segment"); } } function doLandmark (geometry,nameLandmak,typeLandmak) { var polyPoints = null; for (var i = 0; i<geometry.length;i++) { var vertex = geometry[i]; if (polyPoints == null) { polyPoints = [geometry[i]]; var ri = new OpenLayers.Geometry.Point(geometry[i].x, geometry[i].y); polyPoints.push(ri) } else { var ri = new OpenLayers.Geometry.Point(geometry[i].x, geometry[i].y); polyPoints.push(ri); } } var polygon = new OpenLayers.Geometry.Polygon(new OpenLayers.Geometry.LinearRing(polyPoints)); var landmark = new WazeFeatureVectorLandmark(); landmark.geometry = polygon; landmark.attributes.name = nameLandmak; landmark.attributes.categories = typeLandmak; var what = Waze.model.actionManager.add(new WazeActionAddLandmark(landmark)); activateLayer ("landmarks", true ); return true; } function Street_River (ev) { var selectedGood = (Waze.selectionManager.selectedItems.length==1); var sel = Waze.selectionManager.selectedItems[0].model; selectedGood = selectedGood && (sel.type == "segment") && (sel.attributes.roadType != "18"); if (selectedGood) { var offset = getDisplacement(); // valeur en mètres if (offset == null) { return;} var name = getStreet(sel).name; var points = StreetToLandmark (sel, offset); //var dummy = doLandmark (points,name,"H3010") // river var dummy = doLandmark (points,name,["RIVER_STREAM"]); // river alert("Successfully created a River Landmark");} else { alert ("Incorrect Selection : \n\nOne segment must be selected \nOr It is not Street Segment"); } } function Railroad_ParkingLot (ev) { var selectedGood = (Waze.selectionManager.selectedItems.length==1); var sel = Waze.selectionManager.selectedItems[0].model; selectedGood = selectedGood && (sel.type == "segment") && (sel.attributes.roadType == "18"); if (selectedGood) { var offset = getDisplacement(); // valeur en mètres if (offset == null) { return;} var name = getStreet(sel).name; var points = StreetToLandmark (sel, offset); //var dummy = doLandmark (points,name,"W0001") // ParkingLot var dummy = doLandmark (points,name,["PARKING_LOT"]); // ParkingLot alert("Successfully created ParkingLot Landmark");} else { alert ("Incorrect Selection : \n\nOne segment must be selected \nOr It is not Railroad Segment"); } } function getDisplacement() { var scale = 1.44449796; // Scale mètres => coordonnées waze var width = prompt ("Enter new Width or leave it to old value ",defaultWidth); if (width == null) { return null} else { if (width.match("m","g")) { width =parseInt(width); if (width < 1) {width = 1;} //minimum width equal to 1m if (width >100) {width = 100;} //maximum width equal to 100m defaultWidth=width+" m"; return width * scale / 2; } if (width.match("ft","g")) { width =parseInt(width); if (width < 3) {width =3;} //minimum width equal to 3 ft if (width > 300) {width =300;} //maximum width equal to 300 ft defaultWidth=width+" ft"; return width * 0.3048 * scale /2; } width=15; defaultWidth="15 m"; return width * scale / 2; } } function StreetToLandmark (seg,offset) { var decal = decalage (seg.geometry.components, offset); if (document.getElementById ('WME_SSTR_SmthRvr').checked == 1) { decal.dir = optGeometry (decal.dir); decal.sym = optGeometry (decal.sym); decal.dir = b_spline (decal.dir); // creation des B - splines X & Y decal.sym = b_spline (decal.sym); decal.dir = sup_unneed (decal.dir); // delete aligned points decal.sym = sup_unneed (decal.sym); // delete aligned points } decal.dir.push.apply (decal.dir,decal.sym.reverse()); // on rajoute le trajet retour return decal.dir; } function sup_unneed (decal) { for (var phase = 0; phase < 3; phase ++) { var decal1 = []; decal1 [0] = decal [0]; for (var i = 1; i< decal.length-2; i++) { if ((decal1[decal1.length-1].x != decal[i+1].x) && (decal[i+1].x != decal[i+2].x)) { // non vertical => can calculate Atan var angle1 = ((decal1[decal1.length-1].y - decal[i+1].y) / (decal1[decal1.length-1].x - decal[i+1].x)); var angle2 = ((decal[i+1].y - decal[i+2].y) / (decal[i+1].x - decal[i+2].x)); var length1 = longueur (decal1[decal1.length-1].x,decal1[decal1.length-1].y,decal[i+1].x,decal[i+1].y); if (testUnneed (angle1,angle2,length1,phase)) { decal1.push (decal[i+1]); } } else { decal1.push (decal[i+1]); } } decal1.push (decal[decal.length-1]); decal = decal1; } return decal1; } function testUnneed (angle1,angle2,longueur,phase) { var deltaAngle = Math.abs (AtanDeg (angle1) - AtanDeg (angle2)); switch (phase) { case 0: if ((deltaAngle < 45) && (longueur < 10)) {return false;}; break; case 1: if ((deltaAngle < 1 ) && (longueur >= 10) && (longueur < 250)) {return false;}; break; case 2: if ((deltaAngle < 2 ) && (longueur >= 10) && (longueur < 50 )) {return false;}; break; } return true; } function optGeometry ( line) { var opt = []; opt[0] = line[0].clone(); for (var i = 1; i< line.length; i++) { var deltaX = line[i].x-line[i-1].x; var deltaY = line[i].y-line[i-1].y; opt.push ({x: line[i-1].x + deltaX * 0.33, y: line[i-1].y + deltaY * 0.33}); // add 2 extra control points opt.push ({x: line[i-1].x + deltaX * 0.66, y: line[i-1].y + deltaY * 0.66}); opt.push ({x: line[i].x, y: line[i].y}); } return opt; } function decalage (geom,offset) { var decal = {}; decal.dir = []; // décalage d'un coté decal.sym = []; // décalage de l'autre decal.dir[0] = geom[0].clone(); decal.sym[0] = geom[0].clone(); if (Math.abs(geom[1].x - geom[0].x) < 0.1) {geom[1].x = geom[0].x+0.1;} // traitement de la verticalité var deltaX = geom[1].x - geom[0].x; var deltaY = geom[1].y - geom[0].y; var angle = Math.atan (deltaY/deltaX); decal.dir[0].x = geom[0].x - sign (deltaX) * offset * Math.sin (angle); decal.dir[0].y = geom[0].y + sign (deltaX) * offset * Math.cos (angle); decal.sym[0].x = geom[0].x + sign (deltaX) * offset * Math.sin (angle); decal.sym[0].y = geom[0].y - sign (deltaX) * offset * Math.cos (angle); var aprev = deltaY / deltaX; var b = geom[0].y - aprev * geom[0].x; // y = ax+b var off1 = sign(deltaX) * offset / Math.cos (angle); var bprev = b + off1; var bprev1 = b - off1; for (var i = 1; i < geom.length-1; i++) { if (Math.abs(geom[i+1].x - geom[i].x)< 0.1) {geom[i+1].x = geom[i].x+0.1;} // traitement de la verticalité deltaX = geom[i+1].x - geom[i].x; deltaY = geom[i+1].y - geom[i].y; var anext = deltaY / deltaX; b = geom[i].y - anext * geom[i].x; angle = Math.atan (deltaY/deltaX); off1 = sign(deltaX) * offset / Math.cos (angle); var bnext = b + off1; var bnext1 = b - off1; var x1 = -(bprev - bnext) / (aprev - anext); var x2 = -(bprev1 - bnext1) / (aprev - anext); decal.dir.push ({x: x1, y: (aprev * x1 + bprev)}); // décalage d'un coté decal.sym.push ({x: x2, y: (aprev * x2 + bprev1)}); // décalage de l'autre coté aprev = anext; bprev = bnext; bprev1 = bnext1; } // derniers point decal.dir.push ({x: (geom[i].x - sign(deltaX) * offset * Math.sin (angle)),y: (geom[i].y + sign(deltaX) * offset * Math.cos (angle))}); decal.sym.push ({x: (geom[i].x + sign(deltaX) * offset * Math.sin (angle)),y: (geom[i].y - sign(deltaX) * offset * Math.cos (angle))}); return decal; } function b_spline (ligne) { var ligne1 = []; ligne1 [0] = ligne [0]; for (var j = 1; j < ligne.length-2;j++) { var t = 4; // nombre de sous-segments for (var i = 0; i < 1;i+=1/t) { var x1 = ((1-i)*(1-i)*(1-i)*ligne[j-1].x + (3*i*i*i -6*i*i +4)*ligne[j].x + (-3*i*i*i +3*i*i +3*i +1)*ligne[j+1].x + i*i*i*ligne[j+2].x)/6; var y1 = ((1-i)*(1-i)*(1-i)*ligne[j-1].y + (3*i*i*i -6*i*i +4)*ligne[j].y + (-3*i*i*i +3*i*i +3*i +1)*ligne[j+1].y + i*i*i*ligne[j+2].y)/6; ligne1.push ({x: (x1), y: (y1)}); } } ligne1.push( ligne[ligne.length-1] ); return ligne1; } function getStreet(segment) { if (!segment.attributes.primaryStreetID) return null; var street = segment.model.streets.get(segment.attributes.primaryStreetID); return street; } function select_same_type_roads(ev) { var nbRoad = Waze.selectionManager.selectedItems.length; var selectedGood = true; // selection must have 1 or 2 items for (var i = 0; i<nbRoad;i++) { // Test if selection are segment var sel = Waze.selectionManager.selectedItems[i].model; selectedGood = ((selectedGood) && (sel.type == "segment")); } if (selectedGood) { var Select_IDs =[]; //tableau de stockage des Routes electionnées for (var j = 0; j < nbRoad; j++) { var sel = Waze.selectionManager.selectedItems[j].model; if (sel.attributes.junctionID!=null) { // It's un roundabout var jId = sel.attributes.junctionID; var junc = Waze.model.junctions.objects[jId]; Select_IDs.push.apply(Select_IDs,junc.segIDs);} // Add to pervious selected Ids else { var roadFrom = sel.attributes.fromNodeID; var nodeFrom = Waze.model.nodes.objects[roadFrom]; // recherche à partir du premier noeud var segList = searchRoad(nodeFrom,sel,"0"); Select_IDs.push.apply(Select_IDs,segList.IDs); // Add to pervious selected Ids var roadTo = sel.attributes.toNodeID; var nodeTo = Waze.model.nodes.objects[roadTo]; // recherche à partir du deuxième noeud var segList = searchRoad(nodeTo,sel,"0"); Select_IDs.push.apply(Select_IDs,segList.IDs); // Add to pervious selected Ids } } select (Select_IDs); } if (!selectedGood) { alert("You must select road(s)");} } function Side_A(ev) { var nbRoad = Waze.selectionManager.selectedItems.length; var sel = Waze.selectionManager.selectedItems[0].model; if ((nbRoad == 1) && (sel.type == "segment")) { var roadFrom = sel.attributes.fromNodeID; var nodeFrom = Waze.model.nodes.objects[roadFrom]; // recherche à partir du noeud A var segList = searchRoad(nodeFrom,sel,"0") select (segList.IDs);} else { alert ("One segment (and only one)\nmust be selected"); } } function Side_B(ev) { var nbRoad = Waze.selectionManager.selectedItems.length; var sel = Waze.selectionManager.selectedItems[0].model; if ((nbRoad == 1) && (sel.type == "segment")) { var roadTo = sel.attributes.toNodeID; var nodeTo = Waze.model.nodes.objects[roadTo]; // recherche à partir du noeud A var segList = searchRoad(nodeTo,sel,"0") select (segList.IDs);} else { alert ("One segment (and only one)\nmust be selected"); } } function select_AB(ev) { var nbRoad = Waze.selectionManager.selectedItems.length; // **** Validate selection ***** var selectedGood = (nbRoad == 2); // selection must have 2 items if (selectedGood) { var sel = Waze.selectionManager.selectedItems[0].model; var sel1 = Waze.selectionManager.selectedItems[1].model; selectedGood = ((sel.type == "segment") && (sel1.type == "segment")); // Test if selection are segment selectedGood = ((selectedGood) && (sel.attributes.roadType == sel1.attributes.roadType)); // Test if selection have same road Type } if (selectedGood) { var lengthMin = 1000000; var goodTrip = []; var select1 = select_12(sel,sel1); if (select1[select1.length-1] == sel1.getID()) { // on a trouvé un chemin dans ce sens goodTrip = select1; lengthMin = lengthTrip (select1); } var select2 = select_12(sel1,sel); if ((select2[select2.length-1] == sel.getID()) && (lengthTrip (select2) < lengthMin)){ // on a trouvé un chemin dans ce sens goodTrip = select2; lengthMin = lengthTrip (select2); } var nodeTrip1 = nodeFromTrip (select1); // ******* search for Common Nodes var nodeTrip2 = nodeFromTrip (select2); var CommonNode = []; for (var m = 0; m < nodeTrip1.length; m++) { if (isInArray (nodeTrip1[m],nodeTrip2)) { CommonNode.push (nodeTrip1[m]); } } if (CommonNode.length !=0) { for (var i = 0; i < CommonNode.length; i++) { var select3 = []; var road = Waze.model.segments.objects[select1[0]]; for (var j = 0; ((road.attributes.fromNodeID != CommonNode[i]) && (road.attributes.toNodeID != CommonNode[i])); j++) { select3.push (road.getID()); road = Waze.model.segments.objects[select1[j]]; } select3.push (road.getID()); road = Waze.model.segments.objects[select2[0]]; for (var k = 0; ((road.attributes.fromNodeID != CommonNode[i]) && (road.attributes.toNodeID != CommonNode[i])); k++) { select3.push (road.getID()); road = Waze.model.segments.objects[select2[k]]; } select3.push (road.getID()); select3 = delete_multi_Ids (select3); if (lengthTrip (select3) <lengthMin) { goodTrip = select3; lengthMin = lengthTrip (goodTrip); } } } if (lengthMin != 1000000) { // a path was found goodTrip = addRoundabout (goodTrip); // Add roundabout segments goodTrip = addAlternativePaths (goodTrip); // add alternative simple way like fork in roundabaout select (goodTrip);} // make the selection else { alert("No Path found"); } } else { alert("You must select 2 roads \nwith the same type"); } } function addAlternativePaths (trip) { var alternativeSegs = []; var listNodeIDs = nodeFromTrip (trip); // list of nodesIds of the trip var road = Waze.model.segments.objects[trip[0]]; var roadtype = road.attributes.roadType; for (var i = 0; i < listNodeIDs.length;i++) { var node = Waze.model.nodes.objects[listNodeIDs[i]]; var nodeSegIdList = node.attributes.segIDs; for (var j = 0; j < nodeSegIdList.length;j++) { var road1 = Waze.model.segments.objects[nodeSegIdList[j]]; if ((road1 != null) && (road1.attributes.roadType == roadtype) && (isInArray (road1.attributes.fromNodeID,listNodeIDs)) && (isInArray (road1.attributes.toNodeID,listNodeIDs))) { alternativeSegs.push (road1.getID()); } } } if (alternativeSegs.length != 0 ) { trip.push.apply(trip,alternativeSegs); trip = delete_multi_Ids (trip); } return trip; } function addRoundabout (trip) { var roundaboutSegs = []; for (var i = 0; i < trip.length;i++) { var road = Waze.model.segments.objects[trip[i]]; if (road.attributes.junctionID!=null) { // It's un roundabout var jId = road.attributes.junctionID; var junc = Waze.model.junctions.objects[jId]; roundaboutSegs.push.apply(roundaboutSegs,junc.segIDs); // prepare to add roundabout to select } } if (roundaboutSegs.length != 0 ) { trip.push.apply(trip,roundaboutSegs); trip = delete_multi_Ids (trip); } return trip; } function nodeFromTrip (Trip) { var node =[]; for (var i = 0; i < Trip.length; i++) { var road = Waze.model.segments.objects[Trip[i]]; node.push (road.attributes.fromNodeID); node.push (road.attributes.toNodeID); } node = delete_multi_Ids (node); return node; } function lengthTrip (listRoadID) { var length= 0; for (var i = 0; i < listRoadID.length;i++) { var road = Waze.model.segments.objects[listRoadID[i]]; length = length + road.attributes.length; } return length; } function select_12(startRoad,endRoad) { var Select_IDs =[]; //tableau de stockage des Routes electionnées var endRoadFrom; var endRoadTo; if (endRoad.attributes.fromNodeID != null) { // Validate node for End Road endRoadFrom = Waze.model.nodes.objects[endRoad.attributes.fromNodeID];} else {endRoadFrom = Waze.model.nodes.objects[endRoad.attributes.toNodeID];} if (endRoad.attributes.toNodeID != null) { endRoadTo = Waze.model.nodes.objects[endRoad.attributes.toNodeID];} else {endRoadTo = Waze.model.nodes.objects[endRoad.attributes.fromNodeID];} var node = choiceStartNode (startRoad,endRoadFrom,endRoadTo); // Choix du node de depart var segList = searchRoad(node,startRoad,endRoad.getID()); Select_IDs.push.apply(Select_IDs,segList.IDs); //alert (Select_IDs); while ((segList.stop == "multiRoads") && (segList.roads.length >"1") && (Select_IDs.length < 50)) { // Manage jonctions with same type road var BestNextNode = searchBestNextNode (segList.node, segList.roads, endRoad); if ( BestNextNode.getID() != segList.node.getID() ) { // search road with best node for (var i = 0; i < segList.roads.length;i++) { var road = Waze.model.segments.objects[segList.roads[i]]; if ((BestNextNode.getID() == road.attributes.fromNodeID) || (BestNextNode.getID() == road.attributes.toNodeID)) { var bestRoad = road; } } var segList = searchRoad (BestNextNode, bestRoad, endRoad.getID()); Select_IDs.push.apply(Select_IDs, segList.IDs);} else { segList.stop = "none"; } } return (Select_IDs); } function searchBestNextNode (StartNode,listRoadID,endRoad) { var EndNode1 = Waze.model.nodes.objects[endRoad.attributes.fromNodeID]; var EndNode2 = Waze.model.nodes.objects[endRoad.attributes.toNodeID]; if (distance(StartNode,EndNode2) > distance(StartNode,EndNode1)) { // determine de noeud de référence de fin var EndNode = EndNode1;} else { var EndNode = EndNode2; } var angleEnd = angle(StartNode, EndNode); var angleMin = 360; var BestNode; for (var i = 0; i < listRoadID.length;i++) { var road = Waze.model.segments.objects[listRoadID[i]]; if (road.attributes.fromNodeID == StartNode.getID()) { // determine de noeud à tester pour la fin du segment var node = Waze.model.nodes.objects[road.attributes.toNodeID];} else { var node = Waze.model.nodes.objects[road.attributes.fromNodeID]; } var angle1 = Math.abs(angle (StartNode,node) - angleEnd); if (angle1 > 180 ) { angle1= 360 - angle1;} // angle complémentaire if ( angle1 < angleMin ) { angleMin = angle1; BestNode = node; } } return BestNode; } //function sign (x) { //if ( x < 0 ) { return (-1);} // else {return (1);} //} // **** Math functions ***** function sign (x) {return (x < 0) ? (-1) : (1);} function AtanDeg ( x) {return ( 180 * Math.atan (x) / Math.PI );} function convertDegRad (angledeg) {return (Math.PI * (angledeg) / 180 );} function angle (node1,node2) { //var deltaX = (node2.geometry.x - node1.geometry.x); //var deltaY = (node2.geometry.y - node1.geometry.y); //return angleDeg (deltaX,deltaY); return angleDeg ((node2.geometry.x - node1.geometry.x),(node2.geometry.y - node1.geometry.y)); } function angleDeg (deltaX,deltaY) { if (deltaX == 0) { return ( sign( deltaY ) * 90);} if (deltaX > 0 ) { return (AtanDeg( deltaY / deltaX));} else { return ((sign( deltaY )* 180) + AtanDeg( deltaY / deltaX));} } function longueur (x1,y1,x2,y2) { return (Math.sqrt (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))); } // ********************** function select (Select_IDs) { Select_IDs = delete_multi_Ids (Select_IDs) ; // suppression des doublons var foundSegs =[]; for (var i = 0; i<Select_IDs.length;i++) { foundSegs.push(Waze.model.segments.objects[Select_IDs[i]]); // créer la selection } Waze.selectionManager.select(foundSegs); } function delete_multi_Ids (myArray) { var myNewArray = []; if (myArray.length >0) { myNewArray[0]= myArray [0]; for (var i = 0; i < myArray.length; i++) { if (notInArray (myArray [i],myNewArray)) { myNewArray.push(myArray [i]); } } } return myNewArray; } function minInArray (array) { if (array.length > 0) { var minimum = array [0]; for (var i = 1; i < array.length; i++) { //if (array [i] < minimum) {minimum = array [i];} minimum = Math.min (minimum,array [i]); } return minimum; } else {return null;} } function isInArray (item,array) {return array.indexOf(item) !== -1;} function notInArray (item,array) {return array.indexOf(item) === -1;} function searchRoad(node,roadStart,roadEndID) { var roadtype = roadStart.attributes.roadType; var roadStartID = roadStart.getID(); var roadID = roadStartID; var foundSegs = {}; // object for return parameters foundSegs.IDs = []; foundSegs.roads = []; //init array foundSegs.stop = "none"; //init Stop cause foundSegs.IDs.push(roadID); var nbSeg = 1; //Number of searched segments while ((nbSeg < 50) && (roadID != roadEndID)) { var nodeSegIdList = node.attributes.segIDs; // list of road connected to node var sameTypeRoad = []; for (var i = 0; i < nodeSegIdList.length;i++) { var segID = nodeSegIdList [i]; var seg1 =Waze.model.segments.objects[segID]; if (seg1 == null ) return foundSegs; // le segment n'est pas chargé en mémoire else { if ((seg1.attributes.roadType == roadtype) && (seg1.getID() != roadID)) { sameTypeRoad.push(segID); } } } if (sameTypeRoad.length !=1) { if (isInArray (roadEndID,sameTypeRoad)) { // End Road is in the fork foundSegs.IDs.push(roadEndID); // We add it and go away return foundSegs; } sameTypeRoad = validate (sameTypeRoad); // delete cul-de-sac } if (sameTypeRoad.length !=1) { // not an unique segment (0,2 or more) foundSegs.stop = "multiRoads"; foundSegs.roads = sameTypeRoad; foundSegs.node = node; return foundSegs;} // on retourne le tableau d'Ids s else { var roadID = sameTypeRoad[0]; if (isInArray (roadID,foundSegs.IDs)) return foundSegs; // we are in a lopp : we go away foundSegs.IDs.push(roadID); nbSeg = nbSeg + 1; var seg2 = Waze.model.segments.objects[roadID]; if (node.getID() == seg2.attributes.fromNodeID) { var nodeID = seg2.attributes.toNodeID;} else { var nodeID = seg2.attributes.fromNodeID;} var node = Waze.model.nodes.objects[nodeID]; if (node == null ) return foundSegs; // It's a cul-de-sac : we go away } } return foundSegs; } function validate (sameTypeRoad) { var myNewSameTypeRoad = []; for (var i = 0; i < sameTypeRoad.length; i++) { var sel = Waze.model.segments.objects[sameTypeRoad[i]]; if ((sel.attributes.fromNodeID !=null) && (sel.attributes.toNodeID!=null)) { //it is not a cul-de-sac myNewSameTypeRoad.push (sameTypeRoad[i]); } } return myNewSameTypeRoad; } function choiceStartNode (road1,node3,node4) { var node1,node2; if (road1.attributes.fromNodeID != null) { // test of cul-de-sac & change node if it is node1 = Waze.model.nodes.objects[road1.attributes.fromNodeID];} else { node1 = Waze.model.nodes.objects[road1.attributes.toNodeID];} if (road1.attributes.toNodeID != null) { node2 = Waze.model.nodes.objects[road1.attributes.toNodeID];} else { node2 = Waze.model.nodes.objects[road1.attributes.fromNodeID];} var nodeStart = node1; var dist_min = distance (node1,node3); var dist = distance (node1,node4); if (dist < dist_min ) {dist_min=dist;} dist = distance (node2,node3); if (dist < dist_min ) { dist_min = dist; nodeStart = node2;} dist = distance (node2,node4); if (dist < dist_min ) { dist_min = dist; nodeStart = node2;} return nodeStart; } function distance (node1 , node2) { var dist = (node1.geometry.x - node2.geometry.x)*(node1.geometry.x - node2.geometry.x); dist = dist + (node1.geometry.y - node2.geometry.y)*(node1.geometry.y - node2.geometry.y); return Math.sqrt(dist); } function activateLayer (layerName, flag) { if (flag == true || flag == false) { var index; switch (layerName.toUpperCase()) { case "AERIALS": index = 0; break; case "CITIES": index = 1; break; case "NEW CITIES": index = 2; break; case "ROADS": index = 3; break; case "OLD ROADS": index = 4; break; case "GPS POINTS": index = 5; break; case "NEW GPS POINTS": index = 6; break; case "AREA MANAGERS": index = 8; break; case "LANDMARKS": index = 9; break; case "PLACES UPDATE": index = 10;break; case "BIG JUNCTIONS": index = 11;break; case "SPEED CAMERAS": index = 14;break; case "MAP PROBLEMS": index = 16;break; case "UPDATE REQUESTS": index = 17;break; case "EDITABLE AREAS": index = 18;break; case "CLOSURES": index = 20;break; case "LIVE USERS": index = 30;break; } if (index != null) { var layerID = Waze.map.controls[0].map.layers[index].id; Waze.map.controls[0].map.getLayer(layerID).setVisibility(flag); } } } function afficheObjet (objet) { for (var e in objet) {alert("objet["+e+"] ="+ objet[e]+" !");} } function manage_WME_SSTR(ev) { localStorage['WME_SSTR_enable'] = document.getElementById ('WME_SSTR_enable').checked == 1; var road = []; for (var i = 0; i<Waze.selectionManager.selectedItems.length;i++) { var seg = Waze.selectionManager.selectedItems[i].model; if (seg != null && seg.type == "segment") { road.push(seg);} } effaceMenu (); if(document.getElementById ('WME_SSTR_enable').checked == 1) { if (road.length == 1) { document.getElementById ('WME_SSTR_Side').style.display = "block"; if (road[0].attributes.roadType == "18") { document.getElementById ('WME_SSTR_Pklt').style.display = "block";} else { document.getElementById ('WME_SSTR_River').style.display = "block";} } if (road.length >= 1) { document.getElementById ('WME_SSTR').style.display = "block"; document.getElementById ('WME_SSTR_Ldmk').style.display = "block"; if (road[0].attributes.junctionID !=null) { document.getElementById ('WME_SSTR_Rdt').style.display = "block"; } if (Waze.loginManager.user.normalizedLevel >= 3) { document.getElementById ('WME_SSTR_CrgAds').style.display = "block";} } if (road.length == 2) { document.getElementById ('WME_SSTR_12').style.display = "block"; } } return; } function effaceMenu () { document.getElementById ('WME_SSTR').style.display = "none"; document.getElementById ('WME_SSTR_Side').style.display = "none"; document.getElementById ('WME_SSTR_12').style.display = "none"; document.getElementById ('WME_SSTR_River').style.display = "none"; document.getElementById ('WME_SSTR_Pklt').style.display = "none"; document.getElementById ('WME_SSTR_Ldmk').style.display = "none"; document.getElementById ('WME_SSTR_Rdt').style.display = "none"; document.getElementById ('WME_SSTR_CrgAds').style.display = "none"; } function manageSmoothRiver () { if (document.getElementById ('WME_SSTR_SmthRvr').checked == 1) { // recopie river sur Parling lot document.getElementById ('WME_SSTR_SmthPlt').checked = 1;} else { document.getElementById ('WME_SSTR_SmthPlt').checked = 0; } localStorage['WME_SSTR_Smth'] = document.getElementById ('WME_SSTR_SmthRvr').checked == 1; return; } function manageSmoothPklt () { if (document.getElementById ('WME_SSTR_SmthPlt').checked == 1) { // recopie Parling lot sur river document.getElementById ('WME_SSTR_SmthRvr').checked = 1;} else { document.getElementById ('WME_SSTR_SmthRvr').checked = 0;} localStorage['WME_SSTR_Smth'] = document.getElementById ('WME_SSTR_SmthPlt').checked == 1; return; } function init_WME_SSTR() { if (localStorage['WME_SSTR_enable']=='true') { // restaure old Values (if exist) document.getElementById ('WME_SSTR_enable').checked = 1;} if (localStorage['WME_SSTR_Smth']=='true') { document.getElementById ('WME_SSTR_SmthRvr').checked = 1; document.getElementById ('WME_SSTR_SmthPlt').checked = 1; } if (typeof(Waze.map) != "object" || typeof(require.modules) != "object") { //alert ("WME_MUR_Not_init") myAlert("WME_SSTR : Waze.map not ready"); setTimeout(init_WME_SSTR, 2001);} else { Waze.selectionManager.events.register("selectionchanged", null, manage_WME_SSTR); document.getElementById('WME_SSTR_enable').onclick = manage_WME_SSTR; document.getElementById('WME_SSTR_SmthRvr').onclick = manageSmoothRiver; document.getElementById('WME_SSTR_SmthPlt').onclick = manageSmoothPklt; effaceMenu(); manage_WME_SSTR(); myAlert("WME_SSTR initialized"); console_log("Select Same Type Roads initialized"); } } function myAlert (message) { if (document.getElementById('map-search')!=null && !document.getElementById ('WME_JCB_AlertTxt')) { // verif (et réafffichage) de l'alerteBox var myAlertBox = $('<div id="WME_JCB_AlertBox" class="form-control search-query" style="opacity : 0.8;display :none; height: auto;min-height: 30px; position: absolute;top :16px; margin-left: 350px; margin-right: auto; "/>'); var myAlertTxt = $('<div id="WME_JCB_AlertTxt" style=" opacity : 1;display:inline;padding:0px 0px">City ID/'); myAlertBox.append(myAlertTxt); $("#map-search").append(myAlertBox); } if (document.getElementById ('WME_JCB_AlertTxt')){ var myMessage = document.getElementById ('WME_JCB_AlertTxt').innerHTML; var line = myMessage.split("<br>"); if (line.length==1 && line[0]==""){ line[0]= message;} else { line.push (message);} document.getElementById ('WME_JCB_AlertTxt').innerHTML = line.join ("<br>"); document.getElementById ('WME_JCB_AlertBox').style.display = "block"; setTimeout(function() {endAlert();}, 3750 + 500*Math.random()); } } function endAlert() { var myMessage = document.getElementById ('WME_JCB_AlertTxt').innerHTML; var line = myMessage.split("<br>"); line.shift(); document.getElementById ('WME_JCB_AlertTxt').innerHTML = line.join ("<br>"); if (line.length ==0){ document.getElementById ('WME_JCB_AlertBox').style.display = "none"; } } function console_log(msg) { if (console) { console.log(msg);} } } selectSameTypeRoad();