WME Select Same Type Roads

This script add functionnality to select and modify roads

当前为 2019-12-05 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name WME Select Same Type Roads
  3. // @author buchet37
  4. // @namespace https://greasyfork.org/users/4062
  5. // @description This script add functionnality to select and modify roads
  6. // @match https://world.waze.com/editor*
  7. // @match https://www.waze.com/editor*
  8. // @match https://world.waze.com/map-editor*
  9. // @match https://www.waze.com/map-editor*
  10. // @include https://*.waze.com/editor*
  11. // @include https://*.waze.com/*/editor*
  12. // @include https://*.waze.com/map-editor*
  13. // @include https://*.waze.com/beta_editor*
  14. // @include https://descarte*.waze.com/beta*
  15. // @include https://editor-beta.waze.com*
  16. // @grant none
  17. // @version 4.10.3
  18. // ==/UserScript==
  19.  
  20. // Based on Street to River ( http://userscripts.org/scripts/show/122049 )
  21. // Thanks to alcolo47 (some functions are based on WME Extented Tools)
  22. // Thanks to gdu1971, bgodette, Timbones for part of code
  23. // Adapted by buchet37 for "Select Same Type Road"
  24.  
  25. // Mini howto:
  26. // 1) install this script as greasemonkey script or chrome extension
  27. // 2) Select 2 segments
  28. // 3) Click the "Select Roads A<=>B" button
  29. // The script will select all same type road between A and B with a limit of 50 segments
  30.  
  31. var WME_SSTR_version = "4.10.3" ;
  32.  
  33. if ('undefined' == typeof __RTLM_PAGE_SCOPE_RUN__) {
  34. (function page_scope_runner() {
  35. // If we're _not_ already running in the page, grab the full source
  36. // of this script.
  37. var my_src = "(" + page_scope_runner.caller.toString() + ")();";
  38.  
  39. // Create a script node holding this script, plus a marker that lets us
  40. //F know we are running in the page scope (not the Greasemonkey sandbox).
  41. // Note that we are intentionally *not* scope-wrapping here.
  42. var script = document.createElement('script');
  43. script.setAttribute("type", "text/javascript");
  44. script.textContent = "var __RTLM_PAGE_SCOPE_RUN__ = true;\n" + my_src;
  45.  
  46. // Insert the script node into the page, so it will run, and immediately
  47. // remove it to clean up. Use setTimeout to force execution "outside" of
  48. // the user script scope completely.
  49. setTimeout(function() {
  50. document.body.appendChild(script);
  51. document.body.removeChild(script);
  52. }, 0);
  53. })();
  54.  
  55. // Stop running, because we know Greasemonkey actually runs us in
  56. // an anonymous wrapper.
  57. return;
  58. }
  59.  
  60. function selectSameTypeRoad() {
  61. if (W && W.map && W.model && 'undefined' != typeof require ) {start_selectSameTypeRoad(); }
  62. else { setTimeout(selectSameTypeRoad , 1000); }
  63. }
  64.  
  65. function start_selectSameTypeRoad() {
  66.  
  67. var defaultWidth = "15 m"; //Default Width is equal to 15m
  68.  
  69. // ***************** COMPATIBILITY WITH NEW EDITOR ***********
  70. var WazeActionAddLandmark = require("Waze/Action/AddLandmark");
  71. var WazeActionAddOrGetCity = require("Waze/Action/AddOrGetCity");
  72. var WazeActionAddOrGetStreet = require("Waze/Action/AddOrGetStreet");
  73. //var WazeActionCreateObject = require("Waze/Action/CreateObject");
  74. var WazeActionCreateRoundabout = require ("Waze/Action/CreateRoundabout");
  75. var WazeActionDeleteSegment = require ("Waze/Action/DeleteSegment");
  76. //var WazeActionModifyConnection = require ("Waze/Action/ModifyConnection");
  77. var WazeActionMultiAction = require ("Waze/Action/MultiAction");
  78. var WazeActionUpdateObject = require("Waze/Action/UpdateObject");
  79. var WazeActionUpdateSegmentGeometry = require("Waze/Action/UpdateSegmentGeometry");
  80. var WazeFeatureVectorLandmark = require("Waze/Feature/Vector/Landmark");
  81. // *****************************************************************
  82.  
  83. setTimeout (function () {insertButton();}, 5001); //tempo
  84.  
  85. function insertButton() {
  86. if(document.getElementById('WME_SSTR_All') != null) return;
  87. var WME_SSTR_ALL1 = create_WME_SSTR_ALL ();
  88.  
  89. // ******* Mise en place des buttons ****
  90. var WME_SSTR_ALL_Flag = false, myDialogBoxFlag = false;
  91.  
  92. function put_WME_SSTR_ALL() { // wait for 'sidebar'
  93. if (document.getElementById('segment-edit-general')!=null) {
  94. //if (document.getElementById('sidebar')!=null) {
  95. $("#segment-edit-general").append(WME_SSTR_ALL1);
  96. WME_SSTR_ALL_Flag = true;
  97. }
  98. else {
  99. setTimeout (function () {put_WME_SSTR_ALL();}, 1001);
  100. }
  101. }
  102.  
  103. put_WME_SSTR_ALL();
  104.  
  105. // Boite d'alerte
  106. var myAlertBoxFlag = false;
  107. function put_myAlertBox() {
  108. if (document.getElementById('search')!=null) {
  109. if (document.getElementById('WME_JCB_AlertBox')==null) {
  110. 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; "/>');
  111. var myAlertTxt = $('<div id="WME_JCB_AlertTxt" style=" opacity : 1;display:inline;padding:0px 0px">City ID/');
  112. myAlertBox.append(myAlertTxt);
  113. $("#search").append(myAlertBox);
  114. }
  115. myAlertBoxFlag = true;
  116. }
  117. else {setTimeout (function () {put_myAlertBox();}, 501);}
  118. }
  119. put_myAlertBox();
  120.  
  121. function start_init_WME_SSTR() { // si tous les boutons sont chargés on démarre le script
  122. if (WME_SSTR_ALL_Flag && myAlertBoxFlag) {
  123. init_WME_SSTR();
  124. }
  125. else {setTimeout(function () {start_init_WME_SSTR();}, 501);}
  126. }
  127. start_init_WME_SSTR();
  128. return;
  129. }
  130.  
  131. function put_WME_SSTR_button () {
  132. if(document.getElementById('WME_SSTR_All') != null) return ;
  133. var selectedItems = W.selectionManager.getSelectedFeatures();
  134. if (selectedItems.length != 0 &&
  135. selectedItems[0].model.type == "segment") { // s'il y aune selection de segment active
  136. var WME_SSTR_ALL1 = create_WME_SSTR_ALL ();
  137. if (document.getElementById('segment-edit-general')!=null) {
  138. $("#segment-edit-general").append(WME_SSTR_ALL1); //on met le menu et on intilise les check box
  139. if (localStorage['WME_SSTR_enable']=='true') { // restaure old Values (if exist)
  140. document.getElementById ('WME_SSTR_enable').checked = 1;}
  141. if (localStorage['WME_SSTR_Smth']=='true') {
  142. document.getElementById ('WME_SSTR_SmthRvr').checked = 1;}
  143. }
  144. else {
  145. setTimeout (function () {put_WME_SSTR_button();}, 1001); //autrement on attend
  146. }
  147. }
  148. return;
  149. }
  150.  
  151. function create_WME_SSTR_ALL () {
  152. 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>');
  153. var chk2 = $('<Label style="font-weight:normal;margin:0px 5px 0px 0px"><input type="checkbox"; style="vertical-align: middle;margin:0px;" id="WME_SSTR_SmthRvr" title="Check for smoothing">Smooth</input></Label>');
  154. 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 ' + WME_SSTR_version+ '</a></i></u>');
  155.  
  156. var btn1 = $('<button class="waze-btn waze-btn-small waze-btn-white" style="padding:0px 6px; height:20px;" title="Select 1 or more segments and click this button">Select Same Type Roads</button>');
  157. var btn2 = $('<button class="waze-btn waze-btn-small waze-btn-white" style="padding:0px 6px; height:20px; margin-right:5px;" title="Select adjacent segment from node A">A =></button>');
  158. var btn3 = $('<button class="waze-btn waze-btn-small waze-btn-white" style="padding:0px 6px; height:20px" title="Select adjacent segment from node B">B =></button>');
  159. var btn4 = $('<button class="waze-btn waze-btn-small waze-btn-white" style="padding:0px 6px; height:20px" title="Start from segment 1 to join Segment 2 (if possible)">1 => 2</button>');
  160. var btn7 = $('<button class="waze-btn waze-btn-small waze-btn-white" style="padding:0px 6px; height:20px; margin-right:5px; " title="Create a River from Street Geometry">Street => River</button>');
  161. var btn8 = $('<button class="waze-btn waze-btn-small waze-btn-white" style="padding:0px 6px; height:20px;" title="Select road(s) to make an Overall Landmark">Do Landmark</button>');
  162. var btn10= $('<button class="waze-btn waze-btn-small waze-btn-white" style="padding:0px 6px; height:20px" title="Make a new roundabout from 1 segment of an old one">Redo Roundabout</button>');
  163. var btn12= $('<button class="waze-btn waze-btn-small waze-btn-white" style="padding:0px 6px; height:20px; margin-right:5px; " title="click this button to suppress road geometry">Clear Road Geometry</button>');
  164. var btn13= $('<button class="waze-btn waze-btn-small waze-btn-white" style="padding:0px 6px; height:20px" title="click this button to allow "All drives" and "All Turns" on selected roads)">All drives on Selection</button>');
  165.  
  166. btn1.click (select_same_type_roads);
  167. btn2.click (Side_A);
  168. btn3.click (Side_B);
  169. btn4.click (select_AB);
  170. btn7.click (Street_River);
  171. btn8.click (Roads_to_Interchange);
  172. btn10.click (Redo_RoundAbout);
  173. btn12.click (Clear_Road_Geometry);
  174. btn13.click (All_drives_on_Selection);
  175. chk1.click (manage_WME_SSTR);
  176. chk2.click (manageSmoothRiver);
  177.  
  178. WME_SSTR_ALL = $ ('<div id="WME_SSTR_All" style="height: auto; padding:2px 2px 2px 5px;margin:5px 0px 0px -5px;width:295px; border-width:3px; border-style:double;border-color: SkyBlue; border-radius:10px"/>');
  179.  
  180. var cnt0 = $('<section id="WME_SSTR_lnk" style="padding-top:2px; margin:2px;"/>'); cnt0.append(chk1);cnt0.append(" ");cnt0.append(url1);
  181. var cnt1 = $('<section id="WME_SSTR" style="padding-top:2px; margin:2px; display:inline;"/>'); cnt1.append(btn1);
  182. var cnt2 = $('<section id="WME_SSTR_Side" style="padding-top:2px; margin:2px;"/>'); cnt2.append(btn2);cnt2.append(btn3);
  183. var cnt3 = $('<section id="WME_SSTR_12" style="padding-top:2px; margin:2px;"/>'); cnt3.append(btn4);
  184. var cnt4 = $('<section id="WME_SSTR_River" style="padding-top:2px; margin:2px;"/>'); cnt4.append(btn7); cnt4.append(chk2);
  185. var cnt6 = $('<section id="WME_SSTR_Ldmk" style="padding-top:2px; margin:2px;"/>'); cnt6.append(btn8);
  186. var cnt7 = $('<section id="WME_SSTR_Rdt" style="padding-top:2px; margin:2px;"/>'); cnt7.append(btn10);
  187. var cnt8 = $('<section id="WME_SSTR_CrgAds" style="padding-top:2px; margin:2px;"/>'); cnt8.append(btn12);
  188. // cnt8.append(btn13);
  189.  
  190. WME_SSTR_ALL.append(cnt0);
  191. WME_SSTR_ALL.append(cnt1);
  192. WME_SSTR_ALL.append(cnt2);
  193. WME_SSTR_ALL.append(cnt3);
  194. WME_SSTR_ALL.append(cnt4);
  195. WME_SSTR_ALL.append(cnt6);
  196. WME_SSTR_ALL.append(cnt7);
  197. WME_SSTR_ALL.append(cnt8);
  198.  
  199. return WME_SSTR_ALL;
  200. }
  201.  
  202. function Clear_Road_Geometry(ev) {
  203. var selectedItems = W.selectionManager.getSelectedFeatures();
  204. if (selectedItems.length!=0) {
  205. if (confirm ("Do you want to clear the geometry for selected segments") ) {
  206. for (var i = 0; i < selectedItems.length; i++) {
  207. var seg = selectedItems[i].model;
  208. if (seg.type == "segment") {
  209. var newGeo = seg.geometry.clone();
  210. newGeo.components.splice(1,newGeo.components.length -2); // on garde le 1er et le dernier point
  211. newGeo.components[0].calculateBounds();
  212. newGeo.components[1].calculateBounds();
  213. W.model.actionManager.add (new WazeActionUpdateSegmentGeometry (seg,seg.geometry,newGeo));
  214. }
  215. }
  216. }
  217. }
  218. }
  219.  
  220. function All_drives_on_Selection(ev) {
  221. var selectedItems = W.selectionManager.getSelectedFeatures();
  222. if (selectedItems.length!=0) {
  223. var action = [];
  224. var nodeToAllowed = [];
  225. var selectRoadIDs = [];
  226. for (var i = 0; i < selectedItems.length; i++) {
  227. var seg = selectedItems[i].model;
  228. if (seg != null && seg.type == "segment" && !seg.attributes.locked && seg.attributes.junctionID == null) {
  229. selectRoadIDs.push (seg.getID());
  230. action.push (new WazeActionUpdateObject( seg, {fwdDirection: true, revDirection: true})); // pass to two ways
  231. if (W.model.nodes.objects[seg.attributes.fromNodeID]!= null) { // store node A
  232. nodeToAllowed.push (seg.attributes.fromNodeID); }
  233. if (W.model.nodes.objects[seg.attributes.toNodeID]!= null) { // store node B
  234. nodeToAllowed.push (seg.attributes.toNodeID);}
  235. }
  236. }
  237. nodeToAllowed = areTwice (nodeToAllowed); // on ne traite que les segments inttermédiaires
  238. for (var l = 0; l < nodeToAllowed.length; l++) {
  239. var node = W.model.nodes.objects[nodeToAllowed[l]];
  240. var roadIDs = node.attributes.segIDs;
  241. for (var j = 0; j < roadIDs.length; j++) {
  242. for (var k = 0; k < roadIDs.length; k++) {
  243. if (roadIDs[j]!= roadIDs[k] && isInArray (roadIDs[j],selectRoadIDs) && isInArray (roadIDs[k],selectRoadIDs)) {
  244. action.push (new WazeActionModifyConnection(roadIDs[j], node, roadIDs[k], true));
  245. }
  246. }
  247. }
  248. }
  249. if (action.length !=0) { W.model.actionManager.add (new WazeActionMultiAction(action));}
  250. //alert ("On va au bout");
  251. }
  252. }
  253.  
  254. function areTwice (myArray) {
  255. var myNewArray = [];
  256. if (myArray.length > 0) {
  257. for (var i = 0; i < myArray.length-1; i++) {
  258. for (var j = i+1; j < myArray.length; j++) {
  259. if (myArray [i] == myArray[j]) {
  260. myNewArray.push(myArray [i]);
  261. }
  262. }
  263. }
  264. return delete_multi_Ids(myNewArray);
  265. }
  266. else {
  267. return (myArray);
  268. }
  269. }
  270.  
  271. function Redo_RoundAbout (ev) {
  272. var selectedItems = W.selectionManager.getSelectedFeatures();
  273. var selectedGood = (selectedItems.length!=0);
  274. if (selectedGood) {
  275. var listRoadIds = [];
  276. if (selectedItems[0].model.attributes.junctionID !=null) { // si c'est un rdt , on selectionne tout le rdt
  277. var sel = selectedItems[0].model;
  278. var junc = W.model.junctions.objects[sel.attributes.junctionID];
  279. listRoadIds = junc.attributes.segIDs;
  280.  
  281. }
  282. else {
  283. for (var ii = 0; ii < selectedItems.length; ii++) { // sinon on prend tous les egments selectionnés
  284. var sel1 = selectedItems[ii].model;
  285. listRoadIds.push (sel1.getID());
  286. }
  287. }
  288.  
  289. var oldRdt = extract_rdt (listRoadIds);
  290. if (oldRdt.higherRank == false) {
  291. var action = [];
  292. for (var j = 0; j < oldRdt.listRoadIds.length; j++) {
  293. var seg1 = W.model.segments.objects[oldRdt.listRoadIds[j]];
  294. W.model.actionManager.add (new WazeActionDeleteSegment(seg1)); // ******* Delete old Roundabout
  295. }
  296. for (var i = 0; i < oldRdt.listAdjRoadIds.length; i++) {
  297. var seg = W.model.segments.objects[oldRdt.listAdjRoadIds[i].id];
  298. var newGeo = seg.geometry.clone();
  299. var index1, index2, nodeEnd;
  300. if (oldRdt.listAdjRoadIds[i].sideConnect == "A") {
  301. index1 =0; index2 =1;
  302. nodeEnd = W.model.nodes.objects [seg.attributes.toNodeID];
  303. }
  304. else {
  305. index1 = newGeo.components.length-1; index2 = newGeo.components.length-2;
  306. nodeEnd = W.model.nodes.objects [seg.attributes.fromNodeID];
  307. }
  308.  
  309. if (nodeEnd !=null && onScreen(nodeEnd) && nodeEnd.attributes.segIDs.length <2) {
  310. W.model.actionManager.add (new WazeActionUpdateObject(seg, {fwdDirection: true, revDirection: true}));} // dead-end is always two ways roads
  311. if (!seg.attributes.fwdDirection && !seg.attributes.revDirection) { // unknown roads are fixed to two ways roads
  312. W.model.actionManager.add (new WazeActionUpdateObject(seg, {fwdDirection: true, revDirection: true}));}
  313.  
  314. var deltaX = newGeo.components[index1].x - newGeo.components[index2].x;
  315. var deltaY = newGeo.components[index1].y - newGeo.components[index2].y;
  316. var angle = angleDeg (deltaX,deltaY);
  317. var meanExt = 0.10 * (oldRdt.dim.rx + oldRdt.dim.ry);
  318. newGeo.components[index1].x = newGeo.components[index1].x + meanExt* Math.cos(convertDegRad(angle));
  319. newGeo.components[index1].y = newGeo.components[index1].y + meanExt* Math.sin(convertDegRad(angle));
  320. newGeo.components[index1].calculateBounds();
  321. W.model.actionManager.add(new WazeActionUpdateSegmentGeometry (seg,seg.geometry,newGeo));
  322. }
  323.  
  324. var action1 = new WazeActionCreateRoundabout(oldRdt.dim); // créé le nouveau rdt sur les bases géométrique de l'ancien
  325. W.model.actionManager.add (action1);
  326. var rbtRoadIds = W.model.junctions.objects[action1.roundaboutSegments[0].attributes.junctionID].attributes.segIDs; //recup Id segments
  327. var newRdt = searchNewRdt (rbtRoadIds,oldRdt.primaryStreetID);
  328.  
  329. // var action2 = [];
  330. for (var k = 0; k < rbtRoadIds.length; k++) {
  331. var road = W.model.segments.objects[rbtRoadIds[k]];
  332. W.model.actionManager.add(new WazeActionUpdateObject(road, {
  333. roadType: newRdt.roadtype, level: oldRdt.level, lockRank: "0", primaryStreetID: oldRdt.primaryStreetID} ));
  334. }
  335. //Waze.model.actionManager.add(new WazeActionMultiAction(action2));
  336. select (rbtRoadIds);
  337. }
  338. else {
  339. alert ("Your ranking is not higher\nto redo this roundabout");
  340. }
  341. }
  342. else {
  343. alert ("Incorrect Selection : \n\nOne segment must be selected \nOr It is not Roundabout Segment");
  344. }
  345. }
  346.  
  347. function onScreen(obj){
  348. if (obj.geometry){
  349. return(W.map.getOLMap().getExtent().intersectsBounds(obj.geometry.getBounds()));}
  350. return false;
  351. }
  352.  
  353. function searchNewRdt (listRdtSegIds,StreetID) {
  354. var roadpriority = [];
  355. roadpriority [1] = 0; //"Streets"
  356. roadpriority [2] = 1; //"Primary Street"
  357. roadpriority [3] = 3; //"Freeways"
  358. roadpriority [4] = 2; //"Ramps"
  359. roadpriority [6] = 3; //"Major Highway"
  360. roadpriority [7] = 2; //"Minor Highway"
  361. roadpriority [8] = 0; //"Dirt roads"
  362. roadpriority [18] = 0; //"Railroad"
  363. roadpriority [19] = 0; //"Runway/Taxiway"
  364. roadpriority [20] = 0; //"Parking Lot Road"
  365. roadpriority [5] = 0; //"Walking Trails"
  366. roadpriority [10] = 0; //"Pedestrian Bw"
  367. roadpriority [16] = 0; //"Stairway"
  368. roadpriority [17] = 0; //"Private Road"
  369. roadpriority [21] = 0; //"Service Road"
  370.  
  371. var priorityToRoadtype = [];
  372. priorityToRoadtype [0] = 1; //"Streets"
  373. priorityToRoadtype [1] = 2; //"Primary Street"
  374. priorityToRoadtype [2] = 7; //"Minor Highway"
  375. priorityToRoadtype [3] = 6; //"Major Highway"
  376.  
  377. var compteur = [0,0,0,0]; //array for number of roads by type
  378. var listRdtNodeIds = [];
  379.  
  380. for (var i = 0; i < listRdtSegIds.length; i++) {
  381. var road1 = W.model.segments.objects[listRdtSegIds[i]];
  382. if (road1 != null) {
  383. listRdtNodeIds.push (road1.attributes.fromNodeID);
  384. listRdtNodeIds.push (road1.attributes.toNodeID);
  385. }
  386. }
  387. listRdtNodeIds = delete_multi_Ids (listRdtNodeIds);
  388.  
  389. var usedNodeIDs = [];
  390. usedNodeIDs.push.apply (usedNodeIDs,listRdtNodeIds);
  391. var rdt = {};
  392. var action = [];
  393. for (var j = 0; j <listRdtNodeIds.length; j++) { // Search connected Segments
  394. var node = W.model.nodes.objects[listRdtNodeIds[j]];
  395. if (node != null) {
  396. var nbSegs = node.attributes.segIDs.length;
  397. for (var kk = 0; kk < nbSegs;kk++) {
  398. var road = W.model.segments.objects[node.attributes.segIDs[kk]];
  399. if ((road != null) && (notInArray (road.getID(),listRdtSegIds))) {
  400. if (road.attributes.roadType == 3 ) {
  401. W.model.actionManager.add (new WazeActionUpdateObject(road, {roadType: 6}));} // Freeways are not allowed in roundabout
  402. if (notInArray(road.attributes.roadType,([1,2,3,4,6,7]))) {
  403. W.model.actionManager.add (new WazeActionUpdateObject(road, {roadType: 1}));} // Road type on roundabout should be at least "Street"
  404. if (road.attributes.primaryStreetID == null && StreetID != null) {
  405. W.model.actionManager.add(new WazeActionUpdateObject(road, {primaryStreetID: StreetID})); } // Unnamed Roads are named as the rdt
  406. if (notInArray(road.attributes.fromNodeID,usedNodeIDs) || notInArray(road.attributes.toNodeID,usedNodeIDs)) {
  407. compteur [roadpriority[road.attributes.roadType]] ++;
  408. usedNodeIDs.push (usedNodeIDs, road.attributes.fromNodeID);
  409. usedNodeIDs.push (usedNodeIDs, road.attributes.toNodeID);
  410. }
  411. }
  412. }
  413. }
  414. }
  415.  
  416. rdt.roadtype = priorityToRoadtype [0];
  417. var foundMax = false;
  418. for (var k = 3; k > 0; k --) {
  419. if (compteur[k] > 1) {
  420. rdt.roadtype = priorityToRoadtype [k];
  421. break;
  422. }
  423. else {
  424. compteur [k-1] = compteur[k-1] + compteur[k];
  425. }
  426. }
  427.  
  428. if (action.length !=0) {W.model.actionManager.add ( new WazeActionMultiAction(action));} // do modifications if there are
  429. return rdt;
  430. }
  431.  
  432. function extract_rdt (listIDs) {
  433. var rdt = {};
  434. rdt.listAdjRoadIds = [];
  435. rdt.higherRank = false;
  436. rdt.listRoadIds = listIDs;
  437. rdt.listNodeIds = [];
  438.  
  439. var xmin = 10000000000000;
  440. var ymin = 10000000000000;
  441. var xmax = -10000000000000;
  442. var ymax = -10000000000000;
  443. for (var i = 0; i<listIDs.length;i++) {
  444. var road = W.model.segments.objects[listIDs[i]];
  445. if (road != null) {
  446. rdt.listNodeIds.push (road.attributes.fromNodeID); //stocke les nodes
  447. rdt.listNodeIds.push (road.attributes.toNodeID);
  448. rdt.higherRank = rdt.higherRank || road.isLockedByHigherRank(); // stocke si on a les droits
  449. for (var j = 0; j < road.geometry.components.length;j++) { //extrait les dimensions du rdt
  450. var pt = road.geometry.components[j];
  451. xmin = Math.min(xmin,pt.x); xmax = Math.max(xmax,pt.x);
  452. ymin = Math.min(ymin,pt.y); ymax = Math.max(ymax,pt.y);
  453. }
  454. }
  455. }
  456. rdt.listNodeIds = delete_multi_Ids(rdt.listNodeIds); // elimine les noeuds en doublons
  457.  
  458. var ray_X = Math.min (parseInt(144),(xmax-xmin)/2);
  459. var ray_Y = Math.min (parseInt(144),(ymax-ymin)/2);
  460. if (Math.abs (ray_X - ray_Y) < (0.15 * ray_X)) { // if diam x near diam y => Circle with mean value
  461. rdt.dim = {rx: (ray_X+ray_Y)/2, ry: (ray_X+ray_Y)/2};}
  462. else {
  463. rdt.dim = {rx: ray_X, ry: ray_Y};}
  464. rdt.dim.center = {x:((xmin+xmax)/2),y:((ymin+ymax)/2)};
  465. rdt.dim.bounds = new OpenLayers.Bounds(
  466. rdt.dim.center.x - rdt.dim.rx, rdt.dim.center.y - rdt.dim.ry, rdt.dim.center.x+rdt.dim.rx, rdt.dim.center.y +rdt.dim.ry);
  467.  
  468. rdt.level = -5;
  469. var roadIDs =[];
  470. for (var i = 0; i <rdt.listNodeIds.length; i++) { // Search connected Segments
  471. var node = W.model.nodes.objects[rdt.listNodeIds[i]];
  472. if (node != null) {
  473. var nbSegs = node.attributes.segIDs.length;
  474. roadIDs = roadIDs.concat(node.attributes.segIDs); //collect roadsIds connect to rdt
  475. for (var jj=0; jj<nbSegs;jj++) {
  476. var road = W.model.segments.objects[node.attributes.segIDs[jj]];
  477. if ((road != null) && (notInArray (road.getID(),listIDs))) {
  478. rdt.higherRank = rdt.higherRank || road.isLockedByHigherRank(); // test if locked at higher rank
  479. rdt.level = Math.max (rdt.level,road.attributes.level +1); //calcule le future level
  480. if (isInArray (road.attributes.fromNodeID,rdt.listNodeIds)) {
  481. rdt.listAdjRoadIds.push ({id:road.getID(),sideConnect :"A"});
  482. }
  483. if (isInArray (road.attributes.toNodeID,rdt.listNodeIds)) {
  484. rdt.listAdjRoadIds.push ({id:road.getID(),sideConnect :"B"});
  485. }
  486. }
  487. }
  488. }
  489. }
  490.  
  491. // ************** Récupère la ville **********
  492. roadIDs = delete_multi_Ids(roadIDs);
  493. var cityIDs = [];
  494. var cityName = [];
  495. for (var i = 0; i <roadIDs.length; i++) {
  496. var sel = W.model.segments.objects[roadIDs[i]];
  497. var streetID = sel.attributes.primaryStreetID;
  498. if (streetID && W.model.streets.objects[streetID]) {
  499. var street = W.model.streets.objects[streetID];
  500. if (street.cityID && W.model.cities.objects[street.cityID]) {
  501. cityIDs.push(street.cityID);
  502. }
  503. }
  504. }
  505.  
  506. cityIDs = delete_multi_Ids(cityIDs);
  507. if (cityIDs.length ===1) {
  508. var city = W.model.cities.objects[cityIDs[0]];}
  509. else {
  510. var state_ID = W.model.cities.objects[cityIDs[0]].attributes.stateID;
  511. var country_ID = W.model.cities.objects[cityIDs[0]].attributes.countryID;
  512. var city = searchCity(country_ID, state_ID, "");
  513. }
  514. var primaryStreet = searchPrimaryStreet("",city);
  515. rdt.primaryStreetID = primaryStreet.getID();
  516. return rdt;
  517. }
  518.  
  519. function searchCity (country_ID, state_ID, cityName) {
  520. var state = W.model.states.objects[state_ID];
  521. var country = W.model.countries.objects[country_ID];
  522. var f = new WazeActionAddOrGetCity(state,country,cityName);
  523. W.model.actionManager.add(f);
  524. f.setModel();
  525. if (f.city.getID()<0) {myAlert ("Create new city: "+cityName+" in "+state.name);}
  526. return W.model.cities.objects[f.city.getID()];
  527. }
  528.  
  529. function searchPrimaryStreet (streetName,city) {
  530. var a = new WazeActionAddOrGetStreet(streetName,city,(streetName == ""));
  531. W.model.actionManager.add(a);
  532. a.setModel();
  533. if (a.street.getID()<0) {myAlert ("Create new street: "+city.attributes.name+" "+streetName);}
  534. return W.model.streets.objects[a.street.getID()];
  535. }
  536.  
  537. function Roads_to_Interchange(ev) {
  538. var foundSelectedSegment = false;
  539. var selectedItems = W.selectionManager.getSelectedFeatures();
  540. var selectedGood = (selectedItems.length>0);
  541. var roadIds = [];
  542. for (var i = 0; i<selectedItems.length;i++) { // Test if selection are segment
  543. var sel1 = selectedItems[i].model;
  544. selectedGood = ((selectedGood) && (sel1.type == "segment"));
  545. if ((selectedGood)&& (sel1.attributes.junctionID!=null)) { // if it is a roundabout we add all Rdt segs
  546. var jId = sel1.attributes.junctionID;
  547. var junc = W.model.junctions.objects[jId];
  548. roadIds.push.apply (roadIds,junc.segIDs); // we add all segment of the roundabout
  549. }
  550. if (selectedGood) { roadIds.push ( sel1.getID());} // stocke les segments
  551. }
  552. if ((selectedGood) &&( roadIds.length != 0)) {
  553. roadIds = delete_multi_Ids (roadIds); // delete double roads
  554. var totalPoints = [];
  555. var name;
  556. var leftEnv = [];
  557. var rightEnv = [];
  558. var typeLandmak;
  559. leftEnv.push ({x: 100000000000000,y:2000000000});
  560. var yMax = -100000000000;
  561.  
  562. for (var k = 0; k<roadIds.length;k++) {
  563. var sel = W.model.segments.objects[roadIds[k]];
  564.  
  565. if (name == null) {name = getStreet(sel).name;}
  566. if (typeLandmak == null) {
  567. switch (sel.attributes.roadType) {
  568. case 1: //"Streets"
  569. case 2: //"Primary Street"
  570. case 3: //"Freeways"
  571. case 4: //"Ramps"
  572. case 6: //"Major Highway"
  573. case 7: //"Minor Highway"
  574. //typeLandmak = ["JUNCTION_INTERCHANGE"]; break;// Jonction/interchange
  575. typeLandmak = "JUNCTION_INTERCHANGE"; break;// Jonction/interchange
  576. case 8: //"Dirt roads"
  577. case 18: //"Railroad"
  578. case 19: //"Runway/Taxiway"
  579. case 20: //"Parking Lot Road"
  580. typeLandmak = "PARKING_LOT"; break; // ParkingLot
  581. case 5: //"Walking Trails"
  582. case 10: //"Pedestrian Bw"
  583. case 16: //"Stairway"
  584. case 17: //"Private Road"
  585. case 21: //"Service Road"
  586. typeLandmak = "PARK"; break; // Park
  587. }
  588. }
  589.  
  590. for (var j = 0; j < sel.geometry.components.length;j++) {
  591. totalPoints.push (sel.geometry.components[j].clone());
  592. if (leftEnv[0].y > sel.geometry.components[j].y) { // Stocke le Y mini
  593. leftEnv[0] = sel.geometry.components[j].clone();
  594. rightEnv[0] = sel.geometry.components[j].clone();
  595. }
  596. if (sel.geometry.components[j].y > yMax) { yMax = sel.geometry.components[j].y;}
  597. }
  598. }
  599.  
  600. while ( rightEnv[rightEnv.length-1].y <yMax) { // traitement de la voie droite
  601. var anglemin = 190;
  602. for (var i = 0; i<totalPoints.length;i++) {
  603. if (totalPoints[i].y > rightEnv[rightEnv.length-1].y) {
  604. var deltaX = totalPoints[i].x - rightEnv[rightEnv.length-1].x;
  605. if (deltaX !=0) {
  606. var deltaY = totalPoints[i].y - rightEnv[rightEnv.length-1].y;
  607. var angle = angleDeg( deltaX , deltaY);
  608. if (angle < anglemin) {
  609. anglemin = angle;
  610. var iMin = i;
  611. }
  612. }
  613. }
  614. }
  615. rightEnv.push (totalPoints[iMin]);
  616. }
  617.  
  618. while ( leftEnv[leftEnv.length-1].y <yMax) { // traitement de la voie droite
  619. var anglemax = 0;
  620. for (var i = 0; i<totalPoints.length;i++) {
  621. if (totalPoints[i].y > leftEnv[leftEnv.length-1].y) {
  622. var deltaX = totalPoints[i].x - leftEnv[leftEnv.length-1].x;
  623. if (deltaX !=0) {
  624. var deltaY = totalPoints[i].y - leftEnv[leftEnv.length-1].y;
  625. var angle = angleDeg( deltaX , deltaY);
  626. if (angle > anglemax) {
  627. anglemax = angle;
  628. var iMax = i;
  629. }
  630. }
  631. }
  632. }
  633. leftEnv.push (totalPoints[iMax]);
  634. }
  635.  
  636. leftEnv.shift(); leftEnv.pop(); //On ote le premier et le dernier point( communs avec droite)
  637. rightEnv.push.apply (rightEnv,leftEnv.reverse ()); //on ajoute la partie Gauche
  638. var dummy = doLandmark (rightEnv,name,typeLandmak); // make the landmark
  639. alert("Successfully created Landmark");}
  640. else {
  641. alert("Incorrect Selection : \n\nOne segment must be selected \nOr It is not RoundAbout Segment");
  642. }
  643. }
  644.  
  645. function doLandmark (geometry,nameLandmak,typeLandmark) {
  646. var polyPoints = null;
  647. for (var i = 0; i<geometry.length;i++) {
  648. if (polyPoints == null) {
  649. polyPoints = [geometry[i]];
  650. var ri = new OpenLayers.Geometry.Point(geometry[i].x, geometry[i].y);
  651. polyPoints.push(ri);
  652. }
  653. else {
  654. var ri = new OpenLayers.Geometry.Point(geometry[i].x, geometry[i].y);
  655. polyPoints.push(ri);
  656. }
  657. }
  658. var polygon = new OpenLayers.Geometry.Polygon(new OpenLayers.Geometry.LinearRing(polyPoints));
  659. var landmark = new WazeFeatureVectorLandmark();
  660. landmark.geometry = polygon;
  661. landmark.attributes.name = nameLandmak;
  662. landmark.attributes.categories [0] = typeLandmark;
  663. var what = W.model.actionManager.add(new WazeActionAddLandmark(landmark));
  664. // activateLayer ("landmarks", true );
  665. return true;
  666. }
  667.  
  668. function Street_River (ev) {
  669. var selectedItems = W.selectionManager.getSelectedFeatures();
  670. var selectedGood = (selectedItems.length==1);
  671. var sel = selectedItems[0].model;
  672. selectedGood = selectedGood && (sel.type == "segment") && (sel.attributes.roadType != "18");
  673. if (selectedGood) {
  674. var offset = getDisplacement(); // valeur en mètres
  675. if (offset == null) {
  676. return;}
  677. var name = getStreet(sel).name;
  678. var points = StreetToLandmark (sel, offset);
  679. var dummy = doLandmark (points,name,"RIVER_STREAM"); // river
  680. alert("Successfully created a River Landmark");}
  681. else {
  682. alert("Incorrect Selection : \n\nOne segment must be selected \nOr It is not Street Segment");
  683. }
  684. }
  685.  
  686. function getDisplacement() {
  687. var scale = 1.44449796; // Scale mètres => coordonnées waze
  688. var width = prompt ("Enter new Width or leave it to old value ",defaultWidth);
  689. if (width == null) {
  690. return null; }
  691. else {
  692. if (width.match("m","g")) {
  693. width =parseInt(width);
  694. if (width < 1) {width = 1;} //minimum width equal to 1m
  695. if (width >100) {width = 100;} //maximum width equal to 100m
  696. defaultWidth=width+" m";
  697. return width * scale / 2;
  698. }
  699. if (width.match("ft","g")) {
  700. width =parseInt(width);
  701. if (width < 3) {width =3;} //minimum width equal to 3 ft
  702. if (width > 300) {width =300;} //maximum width equal to 300 ft
  703. defaultWidth=width+" ft";
  704. return width * 0.3048 * scale /2;
  705. }
  706. width=15;
  707. defaultWidth="15 m";
  708. return width * scale / 2;
  709. }
  710. }
  711.  
  712. function StreetToLandmark (seg,offset) {
  713. var decal = decalage (seg.geometry.components, offset);
  714. if (document.getElementById ('WME_SSTR_SmthRvr').checked == 1) {
  715. decal.dir = optGeometry (decal.dir);
  716. decal.sym = optGeometry (decal.sym);
  717. decal.dir = b_spline (decal.dir); // creation des B - splines X & Y
  718. decal.sym = b_spline (decal.sym);
  719. decal.dir = sup_unneed (decal.dir); // delete aligned points
  720. decal.sym = sup_unneed (decal.sym); // delete aligned points
  721. }
  722. decal.dir.push.apply (decal.dir,decal.sym.reverse()); // on rajoute le trajet retour
  723. return decal.dir;
  724. }
  725.  
  726. function sup_unneed (decal) {
  727. for (var phase = 0; phase < 3; phase ++) {
  728. var decal1 = [];
  729. decal1 [0] = decal [0];
  730. for (var i = 1; i< decal.length-2; i++) {
  731. if ((decal1[decal1.length-1].x != decal[i+1].x) && (decal[i+1].x != decal[i+2].x)) { // non vertical => can calculate Atan
  732. var angle1 = ((decal1[decal1.length-1].y - decal[i+1].y) / (decal1[decal1.length-1].x - decal[i+1].x));
  733. var angle2 = ((decal[i+1].y - decal[i+2].y) / (decal[i+1].x - decal[i+2].x));
  734. var length1 = longueur (decal1[decal1.length-1].x,decal1[decal1.length-1].y,decal[i+1].x,decal[i+1].y);
  735. if (testUnneed (angle1,angle2,length1,phase)) {
  736. decal1.push (decal[i+1]);
  737. }
  738. }
  739. else {
  740. decal1.push (decal[i+1]);
  741. }
  742. }
  743. decal1.push (decal[decal.length-1]);
  744. decal = decal1;
  745. }
  746. return decal1;
  747. }
  748.  
  749. function testUnneed (angle1,angle2,longueur,phase) {
  750. var deltaAngle = Math.abs (AtanDeg (angle1) - AtanDeg (angle2));
  751. switch (phase) {
  752. case 0: if ((deltaAngle < 45) && (longueur < 10)) {return false;}; break;
  753. case 1: if ((deltaAngle < 1 ) && (longueur >= 10) && (longueur < 250)) {return false;}; break;
  754. case 2: if ((deltaAngle < 2 ) && (longueur >= 10) && (longueur < 50 )) {return false;}; break;
  755. }
  756. return true;
  757. }
  758.  
  759. function optGeometry ( line) {
  760. var opt = [];
  761. opt[0] = line[0].clone();
  762. for (var i = 1; i< line.length; i++) {
  763. var deltaX = line[i].x-line[i-1].x;
  764. var deltaY = line[i].y-line[i-1].y;
  765. opt.push ({x: line[i-1].x + deltaX * 0.33, y: line[i-1].y + deltaY * 0.33}); // add 2 extra control points
  766. opt.push ({x: line[i-1].x + deltaX * 0.66, y: line[i-1].y + deltaY * 0.66});
  767. opt.push ({x: line[i].x, y: line[i].y});
  768. }
  769. return opt;
  770. }
  771.  
  772. function decalage (geom,offset) {
  773. var decal = {};
  774. decal.dir = []; // décalage d'un coté
  775. decal.sym = []; // décalage de l'autre
  776. decal.dir[0] = geom[0].clone();
  777. decal.sym[0] = geom[0].clone();
  778. if (Math.abs(geom[1].x - geom[0].x) < 0.1) {geom[1].x = geom[0].x+0.1;} // traitement de la verticalité
  779. var deltaX = geom[1].x - geom[0].x;
  780. var deltaY = geom[1].y - geom[0].y;
  781. var angle = Math.atan (deltaY/deltaX);
  782. decal.dir[0].x = geom[0].x - sign (deltaX) * offset * Math.sin (angle);
  783. decal.dir[0].y = geom[0].y + sign (deltaX) * offset * Math.cos (angle);
  784. decal.sym[0].x = geom[0].x + sign (deltaX) * offset * Math.sin (angle);
  785. decal.sym[0].y = geom[0].y - sign (deltaX) * offset * Math.cos (angle);
  786.  
  787. var aprev = deltaY / deltaX;
  788. var b = geom[0].y - aprev * geom[0].x; // y = ax+b
  789.  
  790. var off1 = sign(deltaX) * offset / Math.cos (angle);
  791. var bprev = b + off1; var bprev1 = b - off1;
  792. for (var i = 1; i < geom.length-1; i++) {
  793. 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é
  794. deltaX = geom[i+1].x - geom[i].x;
  795. deltaY = geom[i+1].y - geom[i].y;
  796. var anext = deltaY / deltaX;
  797. b = geom[i].y - anext * geom[i].x;
  798. angle = Math.atan (deltaY/deltaX);
  799. off1 = sign(deltaX) * offset / Math.cos (angle);
  800. var bnext = b + off1; var bnext1 = b - off1;
  801.  
  802. var x1 = -(bprev - bnext) / (aprev - anext);
  803. var x2 = -(bprev1 - bnext1) / (aprev - anext);
  804. decal.dir.push ({x: x1, y: (aprev * x1 + bprev)}); // décalage d'un coté
  805. decal.sym.push ({x: x2, y: (aprev * x2 + bprev1)}); // décalage de l'autre coté
  806.  
  807. aprev = anext;
  808. bprev = bnext; bprev1 = bnext1;
  809. }
  810. // derniers point
  811. decal.dir.push ({x: (geom[i].x - sign(deltaX) * offset * Math.sin (angle)),y: (geom[i].y + sign(deltaX) * offset * Math.cos (angle))});
  812. decal.sym.push ({x: (geom[i].x + sign(deltaX) * offset * Math.sin (angle)),y: (geom[i].y - sign(deltaX) * offset * Math.cos (angle))});
  813. return decal;
  814. }
  815.  
  816. function b_spline (ligne) {
  817. var ligne1 = [];
  818. ligne1 [0] = ligne [0];
  819. for (var j = 1; j < ligne.length-2;j++) {
  820. var t = 4; // nombre de sous-segments
  821. for (var i = 0; i < 1;i+=1/t) {
  822. 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;
  823. 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;
  824. ligne1.push ({x: (x1), y: (y1)});
  825. }
  826. }
  827. ligne1.push(ligne[ligne.length-1] );
  828. return ligne1;
  829. }
  830.  
  831. function getStreet(segment) {
  832. if (!segment.attributes.primaryStreetID)
  833. return null;
  834. var street = segment.model.streets.get(segment.attributes.primaryStreetID);
  835. return street;
  836. }
  837.  
  838. function select_same_type_roads(ev) {
  839. var selectedItems = W.selectionManager.getSelectedFeatures();
  840. var nbRoad = selectedItems.length;
  841. var selectedGood = true; // selection must have 1 or 2 items
  842. for (var i = 0; i<nbRoad;i++) { // Test if selection are segment
  843. var sel = selectedItems[i].model;
  844. selectedGood = ((selectedGood) && (sel.type == "segment"));
  845. }
  846.  
  847. if (selectedGood) {
  848. var Select_IDs =[]; //tableau de stockage des Routes electionnées
  849. for (var j = 0; j < nbRoad; j++) {
  850. var sel = selectedItems[j].model;
  851. if (sel.attributes.junctionID!=null) { // It's un roundabout
  852. var jId = sel.attributes.junctionID;
  853. var junc = W.model.junctions.objects[jId];
  854. Select_IDs.push.apply(Select_IDs,junc.segIDs);} // Add to pervious selected Ids
  855. else {
  856. var roadFrom = sel.attributes.fromNodeID;
  857. var nodeFrom = W.model.nodes.objects[roadFrom]; // recherche à partir du premier noeud
  858. var segList = searchRoad(nodeFrom,sel,"0");
  859. Select_IDs.push.apply(Select_IDs,segList.IDs); // Add to pervious selected Ids
  860. var roadTo = sel.attributes.toNodeID;
  861. var nodeTo = W.model.nodes.objects[roadTo]; // recherche à partir du deuxième noeud
  862. var segList = searchRoad(nodeTo,sel,"0");
  863. Select_IDs.push.apply(Select_IDs,segList.IDs); // Add to pervious selected Ids
  864. }
  865. }
  866. select (Select_IDs);
  867. }
  868. if (!selectedGood) { alert("You must select road(s)");}
  869. }
  870.  
  871. function Side_A(ev) {
  872. var selectedItems = W.selectionManager.getSelectedFeatures();
  873. var nbRoad = selectedItems.length;
  874. var sel = selectedItems[0].model;
  875. if ((nbRoad == 1) && (sel.type == "segment")) {
  876. var roadFrom = sel.attributes.fromNodeID;
  877. var nodeFrom = W.model.nodes.objects[roadFrom]; // recherche à partir du noeud A
  878. var segList = searchRoad(nodeFrom,sel,"0");
  879. select (segList.IDs);
  880. }
  881. else {
  882. alert ("One segment (and only one)\nmust be selected");
  883. }
  884. }
  885.  
  886. function Side_B(ev) {
  887. var selectedItems = W.selectionManager.getSelectedFeatures();
  888. var nbRoad = selectedItems.length;
  889. var sel = selectedItems[0].model;
  890. if ((nbRoad == 1) && (sel.type == "segment")) {
  891. var roadTo = sel.attributes.toNodeID;
  892. var nodeTo = W.model.nodes.objects[roadTo]; // recherche à partir du noeud A
  893. var segList = searchRoad(nodeTo,sel,"0");
  894. select (segList.IDs);}
  895. else {
  896. alert ("One segment (and only one)\nmust be selected");
  897. }
  898. }
  899.  
  900. function select_AB(ev) {
  901. var selectedItems = W.selectionManager.getSelectedFeatures();
  902. var nbRoad = selectedItems.length; // **** Validate selection *****
  903. var selectedGood = (nbRoad == 2); // selection must have 2 items
  904. if (selectedGood) {
  905. var sel = selectedItems[0].model;
  906. var sel1 = selectedItems[1].model;
  907. selectedGood = ((sel.type == "segment") && (sel1.type == "segment")); // Test if selection are segment
  908. selectedGood = ((selectedGood) && (sel.attributes.roadType == sel1.attributes.roadType)); // Test if selection have same road Type
  909. }
  910. if (selectedGood) {
  911. var lengthMin = 1000000;
  912. var goodTrip = [];
  913. var select1 = select_12(sel,sel1);
  914. if (select1[select1.length-1] == sel1.getID()) { // on a trouvé un chemin dans ce sens
  915. goodTrip = select1;
  916. lengthMin = lengthTrip (select1);
  917. }
  918. var select2 = select_12(sel1,sel);
  919.  
  920. if ((select2[select2.length-1] == sel.getID()) && (lengthTrip (select2) < lengthMin)){ // on a trouvé un chemin dans ce sens
  921. goodTrip = select2;
  922. lengthMin = lengthTrip (select2);
  923. }
  924. var nodeTrip1 = nodeFromTrip (select1); // ******* search for Common Nodes
  925. var nodeTrip2 = nodeFromTrip (select2);
  926. var CommonNode = [];
  927. for (var m = 0; m < nodeTrip1.length; m++) {
  928. if (isInArray (nodeTrip1[m],nodeTrip2)) {
  929. CommonNode.push (nodeTrip1[m]);
  930. }
  931. }
  932.  
  933. if (CommonNode.length !=0) {
  934. for (var i = 0; i < CommonNode.length; i++) {
  935. var select3 = [];
  936. var road = W.model.segments.objects[select1[0]];
  937. for (var j = 0; ((road.attributes.fromNodeID != CommonNode[i]) && (road.attributes.toNodeID != CommonNode[i])); j++) {
  938. select3.push (road.getID());
  939. road = W.model.segments.objects[select1[j]];
  940. }
  941. select3.push (road.getID());
  942. road = W.model.segments.objects[select2[0]];
  943. for (var k = 0; ((road.attributes.fromNodeID != CommonNode[i]) && (road.attributes.toNodeID != CommonNode[i])); k++) {
  944. select3.push (road.getID());
  945. road = W.model.segments.objects[select2[k]];
  946. }
  947. select3.push (road.getID());
  948. select3 = delete_multi_Ids (select3);
  949. if (lengthTrip (select3) <lengthMin) {
  950. goodTrip = select3;
  951. lengthMin = lengthTrip (goodTrip);
  952. }
  953. }
  954. }
  955.  
  956. if (lengthMin != 1000000) { // a path was found
  957. goodTrip = addRoundabout (goodTrip); // Add roundabout segments
  958. goodTrip = addAlternativePaths (goodTrip); // add alternative simple way like fork in roundabaout
  959. select (goodTrip);} // make the selection
  960. else {
  961. alert("No Path found");
  962. }
  963. }
  964. else { alert("You must select 2 roads \nwith the same type");
  965. }
  966. }
  967.  
  968. function addAlternativePaths (trip) {
  969. var alternativeSegs = [];
  970. var listNodeIDs = nodeFromTrip (trip); // list of nodesIds of the trip
  971. var road = W.model.segments.objects[trip[0]];
  972. var roadtype = road.attributes.roadType;
  973. for (var i = 0; i < listNodeIDs.length;i++) {
  974. var node = W.model.nodes.objects[listNodeIDs[i]];
  975. var nodeSegIdList = node.attributes.segIDs;
  976. for (var j = 0; j < nodeSegIdList.length;j++) {
  977. var road1 = W.model.segments.objects[nodeSegIdList[j]];
  978. if ((road1 != null) && (road1.attributes.roadType == roadtype) && (isInArray (road1.attributes.fromNodeID,listNodeIDs)) && (isInArray (road1.attributes.toNodeID,listNodeIDs))) {
  979. alternativeSegs.push (road1.getID());
  980. }
  981. }
  982. }
  983. if (alternativeSegs.length != 0 ) {
  984. trip.push.apply(trip,alternativeSegs);
  985. trip = delete_multi_Ids (trip);
  986. }
  987. return trip;
  988. }
  989.  
  990. function addRoundabout (trip) {
  991. var roundaboutSegs = [];
  992. for (var i = 0; i < trip.length;i++) {
  993. var road = W.model.segments.objects[trip[i]];
  994. if (road.attributes.junctionID!=null) { // It's un roundabout
  995. var jId = road.attributes.junctionID;
  996. var junc = W.model.junctions.objects[jId];
  997. roundaboutSegs.push.apply(roundaboutSegs,junc.attributes.segIDs); // prepare to add roundabout to select
  998. }
  999. }
  1000. if (roundaboutSegs.length != 0 ) {
  1001. trip.push.apply(trip,roundaboutSegs);
  1002. trip = delete_multi_Ids (trip);
  1003. }
  1004. return trip;
  1005. }
  1006.  
  1007. function nodeFromTrip (Trip) {
  1008. var node =[];
  1009. for (var i = 0; i < Trip.length; i++) {
  1010. var road = W.model.segments.objects[Trip[i]];
  1011. node.push (road.attributes.fromNodeID);
  1012. node.push (road.attributes.toNodeID);
  1013. }
  1014. node = delete_multi_Ids (node);
  1015. return node;
  1016. }
  1017.  
  1018. function lengthTrip (listRoadID) {
  1019. var length= 0;
  1020. for (var i = 0; i < listRoadID.length;i++) {
  1021. var road = W.model.segments.objects[listRoadID[i]];
  1022. length = length + road.attributes.length;
  1023. }
  1024. return length;
  1025. }
  1026.  
  1027. function select_12(startRoad,endRoad) {
  1028. var Select_IDs =[]; //tableau de stockage des Routes electionnées
  1029. var endRoadFrom;
  1030. var endRoadTo;
  1031. if (endRoad.attributes.fromNodeID != null) { // Validate node for End Road
  1032. endRoadFrom = W.model.nodes.objects[endRoad.attributes.fromNodeID];}
  1033. else {endRoadFrom = W.model.nodes.objects[endRoad.attributes.toNodeID];}
  1034. if (endRoad.attributes.toNodeID != null) {
  1035. endRoadTo = W.model.nodes.objects[endRoad.attributes.toNodeID];}
  1036. else {endRoadTo = W.model.nodes.objects[endRoad.attributes.fromNodeID];}
  1037. var node = choiceStartNode (startRoad,endRoadFrom,endRoadTo); // Choix du node de depart
  1038. var segList = searchRoad(node,startRoad,endRoad.getID());
  1039. Select_IDs.push.apply(Select_IDs,segList.IDs);
  1040. //alert (Select_IDs);
  1041. while ((segList.stop == "multiRoads") && (segList.roads.length >"1") && (Select_IDs.length < 50)) { // Manage jonctions with same type road
  1042. var BestNextNode = searchBestNextNode (segList.node, segList.roads, endRoad);
  1043. if ( BestNextNode.getID() != segList.node.getID() ) { // search road with best node
  1044. for (var i = 0; i < segList.roads.length;i++) {
  1045. var road = W.model.segments.objects[segList.roads[i]];
  1046. if ((BestNextNode.getID() == road.attributes.fromNodeID) || (BestNextNode.getID() == road.attributes.toNodeID)) {
  1047. var bestRoad = road;
  1048. }
  1049. }
  1050. var segList = searchRoad (BestNextNode, bestRoad, endRoad.getID());
  1051. Select_IDs.push.apply(Select_IDs, segList.IDs);}
  1052. else {
  1053. segList.stop = "none";
  1054. }
  1055. }
  1056. return (Select_IDs);
  1057. }
  1058.  
  1059. function searchBestNextNode (StartNode,listRoadID,endRoad) {
  1060. var EndNode1 = W.model.nodes.objects[endRoad.attributes.fromNodeID];
  1061. var EndNode2 = W.model.nodes.objects[endRoad.attributes.toNodeID];
  1062. if (distance(StartNode,EndNode2) > distance(StartNode,EndNode1)) { // determine de noeud de référence de fin
  1063. var EndNode = EndNode1;}
  1064. else {
  1065. var EndNode = EndNode2;
  1066. }
  1067. var angleEnd = angle(StartNode, EndNode);
  1068. var angleMin = 360;
  1069. var BestNode;
  1070. for (var i = 0; i < listRoadID.length;i++) {
  1071. var road = W.model.segments.objects[listRoadID[i]];
  1072. if (road.attributes.fromNodeID == StartNode.getID()) { // determine de noeud à tester pour la fin du segment
  1073. var node = W.model.nodes.objects[road.attributes.toNodeID];}
  1074. else {
  1075. var node = W.model.nodes.objects[road.attributes.fromNodeID];
  1076. }
  1077. var angle1 = Math.abs(angle (StartNode,node) - angleEnd);
  1078. if (angle1 > 180 ) { angle1= 360 - angle1;} // angle complémentaire
  1079. if ( angle1 < angleMin ) {
  1080. angleMin = angle1;
  1081. BestNode = node;
  1082. }
  1083. }
  1084. return BestNode;
  1085. }
  1086.  
  1087. // **** Math functions *****
  1088. function sign (x) {return (x < 0) ? (-1) : (1);}
  1089. function AtanDeg ( x) {return ( 180 * Math.atan (x) / Math.PI );}
  1090. function convertDegRad (angledeg) {return (Math.PI * (angledeg) / 180 );}
  1091. function angle (node1,node2) {
  1092. //var deltaX = (node2.geometry.x - node1.geometry.x);
  1093. //var deltaY = (node2.geometry.y - node1.geometry.y);
  1094. //return angleDeg (deltaX,deltaY);
  1095. return angleDeg ((node2.geometry.x - node1.geometry.x),(node2.geometry.y - node1.geometry.y));
  1096. }
  1097. function angleDeg (deltaX,deltaY) {
  1098. if (deltaX == 0) { return ( sign( deltaY ) * 90);}
  1099. if (deltaX > 0 ) { return (AtanDeg( deltaY / deltaX));}
  1100. else { return ((sign( deltaY )* 180) + AtanDeg( deltaY / deltaX));}
  1101. }
  1102. function longueur (x1,y1,x2,y2) {
  1103. return (Math.sqrt (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))));
  1104. }
  1105. // **********************
  1106.  
  1107. function select (Select_IDs) {
  1108. Select_IDs = delete_multi_Ids (Select_IDs) ; // suppression des doublons
  1109. var foundSegs =[];
  1110. for (var i = 0; i<Select_IDs.length;i++) {
  1111. foundSegs.push(W.model.segments.objects[Select_IDs[i]]); // créer la selection
  1112. }
  1113. //W.selectionManager.select(foundSegs);
  1114. W.selectionManager.setSelectedModels(foundSegs);
  1115. }
  1116.  
  1117. function delete_multi_Ids (myArray) {
  1118. var myNewArray = [];
  1119. if (myArray.length >0) {
  1120. myNewArray[0]= myArray [0];
  1121. for (var i = 0; i < myArray.length; i++) {
  1122. if (notInArray (myArray [i],myNewArray)) {
  1123. myNewArray.push(myArray [i]);
  1124. }
  1125. }
  1126. }
  1127. return myNewArray;
  1128. }
  1129.  
  1130. function minInArray (array) {
  1131. if (array.length > 0) {
  1132. var minimum = array [0];
  1133. for (var i = 1; i < array.length; i++) {
  1134. minimum = Math.min (minimum,array [i]);
  1135. }
  1136. return minimum;
  1137. }
  1138. else {return null;}
  1139. }
  1140.  
  1141. function isInArray (item,array) {return array.indexOf(item) !== -1;}
  1142. function notInArray (item,array) {return array.indexOf(item) === -1;}
  1143.  
  1144. function searchRoad(node,roadStart,roadEndID) {
  1145. var roadtype = roadStart.attributes.roadType;
  1146. var roadStartID = roadStart.getID();
  1147. var roadID = roadStartID;
  1148. var foundSegs = {}; // object for return parameters
  1149. foundSegs.IDs = [];
  1150. foundSegs.roads = []; //init array
  1151. foundSegs.stop = "none"; //init Stop cause
  1152. foundSegs.IDs.push(roadID);
  1153. var nbSeg = 1; //Number of searched segments
  1154. while ((nbSeg < 50) && (roadID != roadEndID)) {
  1155. var nodeSegIdList = node.attributes.segIDs; // list of road connected to node
  1156. var sameTypeRoad = [];
  1157. for (var i = 0; i < nodeSegIdList.length;i++) {
  1158. var segID = nodeSegIdList [i];
  1159. var seg1 =W.model.segments.objects[segID];
  1160. if (seg1 == null ) return foundSegs; // le segment n'est pas chargé en mémoire
  1161. else {
  1162. if ((seg1.attributes.roadType == roadtype) && (seg1.getID() != roadID)) {
  1163. sameTypeRoad.push(segID);
  1164. }
  1165. }
  1166. }
  1167.  
  1168. if (sameTypeRoad.length !=1) {
  1169. if (isInArray (roadEndID,sameTypeRoad)) { // End Road is in the fork
  1170. foundSegs.IDs.push(roadEndID); // We add it and go away
  1171. return foundSegs;
  1172. }
  1173. sameTypeRoad = validate (sameTypeRoad); // delete cul-de-sac
  1174. }
  1175. if (sameTypeRoad.length !=1) { // not an unique segment (0,2 or more)
  1176. foundSegs.stop = "multiRoads";
  1177. foundSegs.roads = sameTypeRoad;
  1178. foundSegs.node = node;
  1179. return foundSegs;} // on retourne le tableau d'Ids s
  1180. else {
  1181. var roadID = sameTypeRoad[0];
  1182. if (isInArray (roadID,foundSegs.IDs)) return foundSegs; // we are in a lopp : we go away
  1183. foundSegs.IDs.push(roadID);
  1184. nbSeg = nbSeg + 1;
  1185. var seg2 = W.model.segments.objects[roadID];
  1186. if (node.getID() == seg2.attributes.fromNodeID) { var nodeID = seg2.attributes.toNodeID;}
  1187. else { var nodeID = seg2.attributes.fromNodeID;}
  1188. var node = W.model.nodes.objects[nodeID];
  1189.  
  1190. if (node == null ) return foundSegs; // It's a cul-de-sac : we go away
  1191. }
  1192. }
  1193. return foundSegs;
  1194. }
  1195.  
  1196. function validate (sameTypeRoad) {
  1197. var myNewSameTypeRoad = [];
  1198. for (var i = 0; i < sameTypeRoad.length; i++) {
  1199. var sel = W.model.segments.objects[sameTypeRoad[i]];
  1200. if ((sel.attributes.fromNodeID !=null) && (sel.attributes.toNodeID!=null)) { //it is not a cul-de-sac
  1201. myNewSameTypeRoad.push (sameTypeRoad[i]);
  1202. }
  1203. }
  1204. return myNewSameTypeRoad;
  1205. }
  1206.  
  1207. function choiceStartNode (road1,node3,node4) {
  1208. var node1,node2;
  1209.  
  1210. if (road1.attributes.fromNodeID != null) { // test of cul-de-sac & change node if it is
  1211. node1 = W.model.nodes.objects[road1.attributes.fromNodeID];}
  1212. else { node1 = W.model.nodes.objects[road1.attributes.toNodeID];}
  1213. if (road1.attributes.toNodeID != null) {
  1214. node2 = W.model.nodes.objects[road1.attributes.toNodeID];}
  1215. else { node2 = W.model.nodes.objects[road1.attributes.fromNodeID];}
  1216.  
  1217. var nodeStart = node1;
  1218. var dist_min = distance (node1,node3);
  1219. var dist = distance (node1,node4);
  1220. if (dist < dist_min ) {dist_min=dist;}
  1221. dist = distance (node2,node3);
  1222. if (dist < dist_min ) { dist_min = dist; nodeStart = node2;}
  1223. dist = distance (node2,node4);
  1224. if (dist < dist_min ) { dist_min = dist; nodeStart = node2;}
  1225. return nodeStart;
  1226. }
  1227.  
  1228. function distance (node1 , node2) {
  1229. var dist = (node1.geometry.x - node2.geometry.x)*(node1.geometry.x - node2.geometry.x);
  1230. dist = dist + (node1.geometry.y - node2.geometry.y)*(node1.geometry.y - node2.geometry.y);
  1231. return Math.sqrt(dist);
  1232. }
  1233.  
  1234. function activateLayer (layerName, flag) {
  1235. if (flag == true || flag == false) {
  1236. var index = findLayerIndex (layerName);
  1237. // switch (layerName.toUpperCase()) {
  1238. // case "AERIALS": index = 0; break;
  1239. // case "CITIES": index = 1; break;
  1240. // case "GPS POINTS": index = 2; break;
  1241. // case "ROADS": index = 3; break;
  1242. // case "MAPCOMMENTS": index = 4; break;
  1243. // case "AREA MANAGERS": index = 8; break;
  1244. // case "LANDMARKS": index = 9; break;
  1245. // case "PLACES UPDATE": index = 10;break;
  1246. // case "JUNCTIONS": index = 11;break;
  1247. // case "SPEED CAMERAS": index = 14;break;
  1248. // case "MAP PROBLEMS": index = 16;break;
  1249. // case "UPDATE REQUESTS": index = 18;break;
  1250. // case "EDITABLE AREAS": index = 19;break;
  1251. // case "CLOSURES": index = 22;break;
  1252. // }
  1253. if (index != null) {
  1254. var layerID = W.map.getOLMap().controls[0].map.layers[index].id;
  1255. W.map.getOLMap().controls[0].map.getLayer(layerID).setVisibility(flag);
  1256. }
  1257. }
  1258. }
  1259.  
  1260. function findLayerIndex (layerName) {
  1261. var index ;
  1262. var layers = W.map.getOLMap().controls[0].map.layers;
  1263. for (var i = 0; i<layers.length; i++) {
  1264. if (layers[i].uniqueName && layers[i].uniqueName.toUpperCase() == layerName.toUpperCase()) {
  1265. index=i;
  1266. }
  1267. }
  1268. return index;
  1269. }
  1270.  
  1271. /* function activateLayer2 (layerName, flag) {
  1272. if (flag == true || flag == false) {
  1273. var index;
  1274. switch (layerName.toUpperCase()) {
  1275. case "AERIALS": index = 0; break;
  1276. case "CITIES": index = 1; break;
  1277. case "GPS POINTS": index = 2; break;
  1278. case "ROADS": index = 3; break;
  1279. case "MAPCOMMENTS": index = 4; break;
  1280. case "AREA MANAGERS": index = 8; break;
  1281. case "LANDMARKS": index = 9; break;
  1282. case "PLACES UPDATE": index = 10;break;
  1283. case "JUNCTIONS": index = 11;break;
  1284. case "SPEED CAMERAS": index = 14;break;
  1285. case "MAP PROBLEMS": index = 16;break;
  1286. case "UPDATE REQUESTS": index = 18;break;
  1287. case "EDITABLE AREAS": index = 19;break;
  1288. case "CLOSURES": index = 22;break;
  1289. }
  1290. if (index != null) {
  1291. var layerID = W.map.getOLMap().controls[0].map.layers[index].id;
  1292. W.map.getOLMap().controls[0].map.getLayer(layerID).setVisibility(flag);
  1293. }
  1294. }
  1295. }
  1296. */
  1297.  
  1298. function afficheObjet (objet) {
  1299. for (var e in objet) {alert("objet["+e+"] ="+ objet[e]+" !");}
  1300. }
  1301.  
  1302. function manage_WME_SSTR(ev) {
  1303.  
  1304. // $("#segment-edit-general").append(WME_SSTR_ALL); //repositionne le menu
  1305.  
  1306. put_WME_SSTR_button();
  1307.  
  1308. //alert("B");
  1309. if(document.getElementById('WME_SSTR_All') != null) {;
  1310. localStorage['WME_SSTR_enable'] = document.getElementById ('WME_SSTR_enable').checked == 1;
  1311. var road = [];
  1312. var selectedItems = W.selectionManager.getSelectedFeatures();
  1313. for (var i = 0; i<selectedItems.length;i++) {
  1314. var seg = selectedItems[i].model;
  1315. if (seg != null && seg.type == "segment") { road.push(seg);}
  1316. }
  1317. effaceMenu ();
  1318. if(document.getElementById ('WME_SSTR_enable').checked == 1) {
  1319. if (road.length == 1) {
  1320. document.getElementById ('WME_SSTR_Side').style.display = "inline";
  1321. document.getElementById ('WME_SSTR_River').style.display = "block";}
  1322. if (road.length >= 1) {
  1323. document.getElementById ('WME_SSTR').style.display = "inline";
  1324. document.getElementById ('WME_SSTR_Ldmk').style.display = "block";
  1325. if (road[0].attributes.junctionID !=null) {
  1326. document.getElementById ('WME_SSTR_Rdt').style.display = "block";
  1327. }
  1328. if (W.loginManager.user.normalizedLevel >= 3) {
  1329. document.getElementById ('WME_SSTR_CrgAds').style.display = "block";}
  1330. }
  1331. if (road.length == 2) {
  1332. document.getElementById ('WME_SSTR_12').style.display = "inline";
  1333. }
  1334. }
  1335. }
  1336. return;
  1337. }
  1338.  
  1339. function effaceMenu () {
  1340. document.getElementById ('WME_SSTR').style.display = "none";
  1341. document.getElementById ('WME_SSTR_Side').style.display = "none";
  1342. document.getElementById ('WME_SSTR_12').style.display = "none";
  1343. document.getElementById ('WME_SSTR_River').style.display = "none";
  1344. document.getElementById ('WME_SSTR_Ldmk').style.display = "none";
  1345. document.getElementById ('WME_SSTR_Rdt').style.display = "none";
  1346. document.getElementById ('WME_SSTR_CrgAds').style.display = "none";
  1347. }
  1348.  
  1349. function manageSmoothRiver () {
  1350. localStorage['WME_SSTR_Smth'] = document.getElementById ('WME_SSTR_SmthRvr').checked == 1;
  1351. return;
  1352. }
  1353.  
  1354. function init_WME_SSTR() {
  1355. if (localStorage['WME_SSTR_enable']=='true') { // restaure old Values (if exist)
  1356. document.getElementById ('WME_SSTR_enable').checked = 1;}
  1357. if (localStorage['WME_SSTR_Smth']=='true') {
  1358. document.getElementById ('WME_SSTR_SmthRvr').checked = 1;
  1359. }
  1360.  
  1361. // if (typeof(Waze.map) != "object" || typeof(require.modules) != "object") {
  1362. // myAlert("WME_SSTR : Waze.map not ready");
  1363. // setTimeout(init_WME_SSTR, 2001);}
  1364. // else {
  1365. //Waze.selectionManager.events.register("selectionchanged", null, manage_WME_SSTR);
  1366.  
  1367. W.selectionManager.events.register("selectionchanged", null, manage_WME_SSTR1);
  1368.  
  1369. // document.getElementById('WME_SSTR_enable').onclick = manage_WME_SSTR;
  1370. // document.getElementById('WME_SSTR_SmthRvr').onclick = manageSmoothRiver;
  1371. effaceMenu();
  1372. manage_WME_SSTR();
  1373. myAlert("WME_SSTR initialized");
  1374.  
  1375. console_log("Select Same Type Roads initialized");
  1376. //}
  1377. }
  1378.  
  1379. function manage_WME_SSTR1 () {
  1380. setTimeout(manage_WME_SSTR, 1001);
  1381. }
  1382.  
  1383. function myAlert (message) {
  1384. if (document.getElementById('search')!=null && !document.getElementById ('WME_JCB_AlertTxt')) { // verif (et réafffichage) de l'alerteBox
  1385. 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; "/>');
  1386. var myAlertTxt = $('<div id="WME_JCB_AlertTxt" style=" opacity : 1;display:inline;padding:0px 0px">City ID/');
  1387. myAlertBox.append(myAlertTxt);
  1388. $("#search").append(myAlertBox);
  1389. }
  1390. if (document.getElementById ('WME_JCB_AlertTxt')){
  1391. var myMessage = document.getElementById ('WME_JCB_AlertTxt').innerHTML;
  1392. var line = myMessage.split("<br>");
  1393. if (line.length==1 && line[0]==""){ line[0]= message;}
  1394. else { line.push (message);}
  1395. document.getElementById ('WME_JCB_AlertTxt').innerHTML = line.join ("<br>");
  1396. document.getElementById ('WME_JCB_AlertBox').style.display = "block";
  1397. setTimeout(function() {endAlert();}, 3750 + 500*Math.random());
  1398. }
  1399. }
  1400.  
  1401. function endAlert() {
  1402. var myMessage = document.getElementById ('WME_JCB_AlertTxt').innerHTML;
  1403. var line = myMessage.split("<br>");
  1404. line.shift();
  1405. document.getElementById ('WME_JCB_AlertTxt').innerHTML = line.join ("<br>");
  1406. if (line.length ==0){
  1407. document.getElementById ('WME_JCB_AlertBox').style.display = "none";
  1408. }
  1409. }
  1410.  
  1411. function console_log(msg) {
  1412. if (console) {
  1413. console.log(msg);}
  1414. }
  1415.  
  1416. }
  1417.  
  1418. selectSameTypeRoad();