WME Select Same Type Roads

This script add functionnality to select and modify roads

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

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