UROverview Plus (URO+)

Adds filtering and pop-up infobox for UR, MP and camera markers

当前为 2014-08-15 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name UROverview Plus (URO+)
  3. // @namespace http://greasemonkey.chizzum.com
  4. // @description Adds filtering and pop-up infobox for UR, MP and camera markers
  5. // @include https://*.waze.com/*editor*
  6. // @include https://editor-beta.waze.com/*
  7. // @grant none
  8. // @version 3.16
  9. // ==/UserScript==
  10.  
  11. function uroGlobals()
  12. {
  13. uroVersion = "3.16";
  14. uroCtrlsHidden = false;
  15. uroCurrentTab = 1;
  16. uroFID = -1;
  17. uroShownFID = -1;
  18. uroInhibitSave = true;
  19. uroPopupTimer = -2;
  20. uroPopupShown = false;
  21. uroSetupListeners = true;
  22. uroRootContainer = null;
  23. uroURvroot = null;
  24. uroMPvroot = null;
  25. uroMaskLayer = null;
  26. uroCamLayer = null;
  27. uroCustomMarkerFID = null;
  28.  
  29. uroURLayerIdx = null;
  30. uroProblemLayerIdx = null;
  31. uroMouseInPopup = false;
  32. uroURControlsIdx = null;
  33. uroProblemControlsIdx = null;
  34. uroMaskActive = false;
  35. uroAMLayerIdx = null;
  36.  
  37. uroNullCamLayer = false;
  38. uroNullOpenLayers = false;
  39. uroNullRootContainer = false;
  40. uroNullURLayer = false;
  41. uroNullProblemLayer = false;
  42. uroNullMapViewport = false;
  43. uroUserID = -1;
  44. uroURSCurrentCount = 0;
  45. uroURSPrevCount = 0;
  46. uroBetaEditor = false;
  47. uroWazeBitsPresent = 0;
  48. uroCamWatchObjects = new Array();
  49. uroCWLGroups = new Array();
  50. uroAMPosX = null;
  51. uroAMPosY = null;
  52. dteControlsIdx = -1;
  53. dteOldestFullDrive = new Date(0);
  54. dteEpoch = new Date(0);
  55. uroUserTabId = '';
  56.  
  57. // uroIcons
  58. // 0 = group collapse/group expand
  59. // 1 = addtogroup active/addtogroup idle
  60. // 2 = goto active/goto idle
  61. // 3 = normal/selected roadworks UR
  62. // 4 = normal/selected closure UR
  63. // 5 = normal/selected event UR
  64. // 6 = normal/selected closed roadworks UR
  65. // 7 = normal/selected closed closure UR
  66. // 8 = normal/selected closed event UR
  67. uroIcons =
  68. [
  69. ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94CAhYRIqo78SIAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAADtJREFUKM9j/P//PwNJgCQN////ZyFeGyMjIwMDAxMDiWAQamDB9Bb+kKTMBmICdxgFK64AxZKiSE3eAAOXFRnJRfN6AAAAAElFTkSuQmCC","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94CAhYRDHbt/O0AAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAE5JREFUKM+9UkEKACAMcmP//7IdgghqMQvytoOKTiMJCRKBZNRpZgbAIcIzsa5XJcgOB8Qaaz3nSt4chlLX3nb9OXRlL7cO2V83I1Dn3QDKfhshMqWScAAAAABJRU5ErkJggg=="],
  70. ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BGhYVKhKBubQAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAEZJREFUOMtjYBjygBHB/P8fjzJGIszCZQA+gxkYWIjTABPDdAkL8U7G7hIcYcDISEGYwDQSFyZM5AQckYA4F7CQZ8goQAYAMCsd/TxbqrwAAAAASUVORK5CYII=","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94DAw0tDee2t8AAAABPSURBVDjL7ZAxCgAgDAMT6cP6dH+mUwfBaugmeFMpbTgCPA9j6H2M7MidvCZlAadgADDlIXY7E1OVM5NtB+5kuZN4VDtpleIkVAOrhHxWJoJkNv2QAd51AAAAAElFTkSuQmCC"],
  71. ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BGhYfLAEN9AsAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAGdJREFUOMutk+EKACEIg7fD93/l3Y+uP5kmeYMgkH0NTUpCRw+acgBynHaCKsgBlpaIhDJQtQchaAtIBuNAlAQSV7OUwPYYGX2kL6Zi37hYYk6NU1ZPui/Y4XWeVsWSDpdkt8bftvEFOy0jJkeygWMAAAAASUVORK5CYII=","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94DAw0tFm3TfiwAAABySURBVDjLrZNRDsAgCEPp4r306HKy7sMsMRMckZH4ZfqoYEFSMnVJshYAME7aQRS0AOaR9C5UFe5AoRnsQCbAW4wFAklRlaNd1ipIrxHeRwKGZeuuNcEjK554J5x7lohNS+g+4d39Kyqug2jGyqnwtzTengM2Gxwa0GsAAAAASUVORK5CYII="],
  72. ["data:image/png;base64,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","data:image/png;base64,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"],
  73. ["data:image/png;base64,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","data:image/png;base64,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"],
  74. ["data:image/png;base64,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","data:image/png;base64,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"],
  75. ["data:image/png;base64,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","data:image/png;base64,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"],
  76. ["data:image/png;base64,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","data:image/png;base64,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"],
  77. ["data:image/png;base64,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","data:image/png;base64,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"]
  78. ];
  79. }
  80.  
  81.  
  82.  
  83.  
  84. function uroBootstrap()
  85. {
  86. var bGreasemonkeyServiceDefined = false;
  87. try {
  88. bGreasemonkeyServiceDefined = (typeof Components.interfaces.gmIGreasemonkeyService === "object");
  89. }
  90. catch (err) { /* Ignore */ }
  91. if (typeof unsafeWindow === "undefined" || ! bGreasemonkeyServiceDefined) {
  92. unsafeWindow = ( function () {
  93. var dummyElem = document.createElement('p');
  94. dummyElem.setAttribute('onclick', 'return window;');
  95. return dummyElem.onclick();
  96. }) ();
  97. }
  98. /* begin running the code! */
  99. uroInitialise();
  100. }
  101.  
  102.  
  103. function uroAddLog(logtext)
  104. {
  105. console.log('URO+: '+logtext);
  106. }
  107.  
  108. function uroGatherSettings(container)
  109. {
  110. var options = '';
  111. var urOptions = document.getElementById(container).getElementsByTagName('input');
  112. for (var optIdx=0;optIdx<urOptions.length;optIdx++)
  113. {
  114. var id = urOptions[optIdx].id;
  115. if((id.indexOf('_cb') == 0)||(id.indexOf('_text') == 0)||(id.indexOf('_input') == 0))
  116. {
  117. options += ':' + id;
  118. if(urOptions[optIdx].type == 'checkbox') options += ',' + urOptions[optIdx].checked.toString();
  119. else if((urOptions[optIdx].type == 'text')||(urOptions[optIdx].type == 'number')) options += ',' + urOptions[optIdx].value.toString();
  120. }
  121. }
  122. return options;
  123. }
  124.  
  125.  
  126. function uroGatherCamWatchList()
  127. {
  128. var liststr = '';
  129. for(var loop=0;loop<uroCamWatchObjects.length;loop++)
  130. {
  131. camObj = uroCamWatchObjects[loop];
  132. if((camObj.fid != undefined) && (camObj.persistent == true))
  133. {
  134. if(loop > 0) liststr += ':';
  135.  
  136. liststr += camObj.fid+',';
  137. liststr += camObj.watchLon+',';
  138. liststr += camObj.watchLat+',';
  139. liststr += camObj.watchType+',';
  140. liststr += camObj.watchAzymuth+',';
  141. liststr += camObj.watchSpeed+',';
  142. liststr += camObj.watchValidated+',';
  143. liststr += camObj.groupID+',';
  144. liststr += camObj.server;
  145. }
  146. }
  147. return liststr;
  148. }
  149.  
  150. function uroGatherCWLGroups()
  151. {
  152. var liststr = '';
  153. for(var loop=0;loop<uroCWLGroups.length;loop++)
  154. {
  155. groupObj = uroCWLGroups[loop];
  156. if(groupObj.groupID != -1)
  157. {
  158. if(loop > 0) liststr += ':';
  159.  
  160. liststr += groupObj.groupID+',';
  161. liststr += groupObj.groupName+',';
  162. liststr += groupObj.groupCollapsed;
  163. }
  164. }
  165. return liststr;
  166. }
  167.  
  168. function uroSaveSettings()
  169. {
  170. if(uroInhibitSave) return;
  171.  
  172. if (localStorage)
  173. {
  174. localStorage.UROverviewUROptions = uroGatherSettings('uroCtrlURs');
  175. localStorage.UROverviewMPOptions = uroGatherSettings('uroCtrlMPs');
  176. localStorage.UROverviewCameraOptions = uroGatherSettings('uroCtrlCameras');
  177. localStorage.UROverviewMiscOptions = uroGatherSettings('uroCtrlMisc');
  178. localStorage.UROverviewCamWatchList = uroGatherCamWatchList();
  179. localStorage.UROverviewCWLGroups = uroGatherCWLGroups();
  180. }
  181. }
  182.  
  183. function uroApplySettings(settings)
  184. {
  185. var options = settings.split(':');
  186. for(var optIdx=0;optIdx<options.length;optIdx++)
  187. {
  188. var fields = options[optIdx].split(',');
  189. if(fields[0].indexOf('_cb') == 0)
  190. {
  191. if(document.getElementById(fields[0]) != null) document.getElementById(fields[0]).checked = (fields[1] == 'true');
  192. }
  193. else if((fields[0].indexOf('_input') == 0)||(fields[0].indexOf('_text') == 0))
  194. {
  195. if(document.getElementById(fields[0]) != null) document.getElementById(fields[0]).value = fields[1];
  196. }
  197. }
  198. }
  199.  
  200.  
  201. function uroApplyCamWatchList()
  202. {
  203. var objects = localStorage.UROverviewCamWatchList.split(':');
  204. uroCamWatchObjects = new Array();
  205.  
  206. for(var objIdx=0;objIdx<objects.length;objIdx++)
  207. {
  208. var fields = objects[objIdx].split(',');
  209. // following two bits of code add in blank fields if the user has updated their copy of URO+ from an
  210. // older version which didn't include support for either of these field types
  211. // add default groupID field
  212. if(fields.length == 7)
  213. {
  214. fields.push(0);
  215. }
  216. // set default groupID value to 0 (no group)
  217. if(fields[7] == -1)
  218. {
  219. fields[7] = 0;
  220. }
  221.  
  222. // add default server field
  223. if(fields.length == 8)
  224. {
  225. fields.push('??');
  226. }
  227. // set default server value to unknown
  228. if(fields[8] == 0)
  229. {
  230. fields[8] = '??';
  231. }
  232.  
  233. uroCamWatchObjects.push(new uroCamWatchObj(true,fields[0],fields[1],fields[2],fields[3],fields[4],fields[5],fields[6],fields[7],fields[8]));
  234. }
  235. }
  236.  
  237. function uroApplyCWLGroups()
  238. {
  239. var objects = localStorage.UROverviewCWLGroups.split(':');
  240. uroCWLGroups = new Array();
  241.  
  242. for(var objIdx=0;objIdx<objects.length;objIdx++)
  243. {
  244. var fields = objects[objIdx].split(',');
  245. if(fields.length < 2)
  246. {
  247. fields.push(false);
  248. }
  249. uroCWLGroups.push(new uroCWLGroupObj(fields[0],fields[1],(fields[2] == 'true')));
  250. }
  251. }
  252.  
  253. function uroLoadSettings()
  254. {
  255. uroAddLog('loadSettings()');
  256. if (localStorage.UROverviewUROptions)
  257. {
  258. uroAddLog('recover UR tab settings');
  259. uroApplySettings(localStorage.UROverviewUROptions);
  260. }
  261. if (localStorage.UROverviewCameraOptions)
  262. {
  263. uroAddLog('recover camera tab settings');
  264. uroApplySettings(localStorage.UROverviewCameraOptions);
  265. }
  266.  
  267. if (localStorage.UROverviewMPOptions)
  268. {
  269. uroAddLog('recover MP tab settings');
  270. uroApplySettings(localStorage.UROverviewMPOptions);
  271. }
  272.  
  273. if (localStorage.UROverviewMiscOptions)
  274. {
  275. uroAddLog('recover misc tab settings');
  276. uroApplySettings(localStorage.UROverviewMiscOptions);
  277. }
  278. if(localStorage.UROverviewCWLGroups)
  279. {
  280. uroAddLog('recover CWL groups');
  281. uroApplyCWLGroups();
  282. }
  283. else
  284. {
  285. uroAddLog('set default CWL group');
  286. uroCWLGroups.push(new uroCWLGroupObj(0,'No group',false));
  287. }
  288.  
  289. if(localStorage.UROverviewCamWatchList)
  290. {
  291. uroAddLog('recover camera watchlist');
  292. uroApplyCamWatchList();
  293. uroGetCurrentCamWatchListObjects();
  294. }
  295. uroInhibitSave = false;
  296. }
  297.  
  298. function uroSettingsToText()
  299. {
  300. var txtSettings = '';
  301. uroSaveSettings();
  302. if (localStorage.UROverviewUROptions)
  303. {
  304. txtSettings += '[UROverviewUROptions][len=' + localStorage.UROverviewUROptions.length + ']' + localStorage.UROverviewUROptions + '[END]';
  305. }
  306. if (localStorage.UROverviewCameraOptions)
  307. {
  308. txtSettings += '[UROverviewCameraOptions][len=' + localStorage.UROverviewCameraOptions.length + ']' + localStorage.UROverviewCameraOptions + '[END]';
  309. }
  310. if (localStorage.UROverviewMPOptions)
  311. {
  312. txtSettings += '[UROverviewMPOptions][len=' + localStorage.UROverviewMPOptions.length + ']' + localStorage.UROverviewMPOptions + '[END]';
  313. }
  314. if (localStorage.UROverviewMiscOptions)
  315. {
  316. txtSettings += '[UROverviewMiscOptions][len=' + localStorage.UROverviewMiscOptions.length + ']' + localStorage.UROverviewMiscOptions + '[END]';
  317. }
  318. if (localStorage.UROverviewCamWatchList)
  319. {
  320. txtSettings += '[UROverviewCamWatchList][len=' + localStorage.UROverviewCamWatchList.length + ']' + localStorage.UROverviewCamWatchList + '[END]';
  321. }
  322. if (localStorage.UROverviewCWLGroups)
  323. {
  324. txtSettings += '[UROverviewCWLGroups][len=' + localStorage.UROverviewCWLGroups.length + ']' + localStorage.UROverviewCWLGroups + '[END]';
  325. }
  326. document.getElementById('_txtSettings').value = txtSettings;
  327. document.getElementById('_txtSettings').focus();
  328. document.getElementById('_txtSettings').select();
  329. }
  330.  
  331. function uroTextToSettings()
  332. {
  333. var txtSettings = '';
  334. txtSettings = document.getElementById('_txtSettings').value;
  335. if(txtSettings.indexOf('[END]') == -1) return;
  336. var subText = txtSettings.split('[END]');
  337. for(var i=0;i<subText.length;i++)
  338. {
  339. var bPos = subText[i].indexOf(']');
  340. if(bPos != -1)
  341. {
  342. var settingID = subText[i].substr(1,bPos-1);
  343. subText[i] = subText[i].substr(bPos+1);
  344. bPos = subText[i].indexOf(']');
  345. if(bPos != -1)
  346. {
  347. var settingLength = subText[i].substr(5,bPos-5);
  348. subText[i] = subText[i].substr(bPos+1);
  349. if(subText[i].length == settingLength)
  350. {
  351. if(settingID == 'UROverviewCamWatchList') localStorage.UROverviewCamWatchList = subText[i];
  352. if(settingID == 'UROverviewCWLGroups') localStorage.UROverviewCWLGroups = subText[i];
  353. if(settingID == 'UROverviewUROptions') localStorage.UROverviewUROptions = subText[i];
  354. if(settingID == 'UROverviewCameraOptions') localStorage.UROverviewCameraOptions = subText[i];
  355. if(settingID == 'UROverviewMPOptions') localStorage.UROverviewMPOptions = subText[i];
  356. if(settingID == 'UROverviewMiscOptions') localStorage.UROverviewMiscOptions = subText[i];
  357. }
  358. }
  359. }
  360. }
  361. uroLoadSettings();
  362. }
  363.  
  364. function uroClearSettingsText()
  365. {
  366. document.getElementById('_txtSettings').value = '';
  367. }
  368.  
  369.  
  370. function uroDateToDays(dateToConvert, ticksPerDay)
  371. {
  372. var dateNow = new Date();
  373. return Math.floor((dateNow.getTime() - dateToConvert) / 86400000);
  374. }
  375.  
  376. function uroGetURAge(urObj,ageType)
  377. {
  378. if(ageType == 0)
  379. {
  380. if((urObj.attributes.driveDate == null)||(urObj.attributes.driveDate == 0)) return -1;
  381. return uroDateToDays(urObj.attributes.driveDate, urObj.ONE_DAY);
  382. }
  383. else
  384. {
  385. if((urObj.attributes.resolvedOn == null)||(urObj.attributes.resolvedOn == 0)) return -1;
  386. return uroDateToDays(urObj.attributes.resolvedOn, 86400000);
  387. }
  388. }
  389.  
  390. function uroGetCameraAge(camObj, mode)
  391. {
  392. if(mode == 0)
  393. {
  394. if(camObj.attributes.updatedOn == null) return -1;
  395. return uroDateToDays(camObj.attributes.updatedOn, 86400000);
  396. }
  397. if(mode == 1)
  398. {
  399. if(camObj.attributes.createdOn == null) return -1;
  400. return uroDateToDays(camObj.attributes.createdOn, 86400000);
  401. }
  402. }
  403.  
  404. function uroGetCommentAge(commentObj)
  405. {
  406. if(commentObj.createdOn == null) return -1;
  407. return uroDateToDays(commentObj.createdOn, 86400000);
  408. }
  409.  
  410. function uroParseDaysAgo(days)
  411. {
  412. if(days == 0) return 'today';
  413. else if(days == 1) return '1 day ago';
  414. else return days+' days ago';
  415. }
  416.  
  417. function uroIsCameraSpeedValid(camObj)
  418. {
  419. // returns 1 if the entered speed converts correctly into a multiple of 10MPH
  420. // returns -1 if the entered speed does not convert correctly
  421. // returns 0 if no speed data is present, or if the entered speed is 0
  422. if(camObj.attributes.speed != null)
  423. {
  424. var speed = Math.round(camObj.attributes.speed /1.609);
  425. if(speed == 0) return 0;
  426. else if(speed % 10 == 0) return 1;
  427. else return -1;
  428. }
  429. else return 0;
  430. }
  431.  
  432.  
  433. function uroTypeCast(varin)
  434. {
  435. if(varin == "null") return null;
  436. if(typeof varin == "string") return parseInt(varin);
  437. return varin;
  438. }
  439.  
  440. function uroCWLGroupObj(groupID, groupName, groupCollapsed)
  441. {
  442. groupID = uroTypeCast(groupID);
  443. this.groupID = groupID;
  444. this.groupName = groupName;
  445. this.groupCount = 0;
  446. this.groupCollapsed = groupCollapsed;
  447. }
  448. function uroCamWatchObj(persistent, fid, lon, lat, type, azymuth, speed, validated, groupID, server)
  449. {
  450. fid = uroTypeCast(fid);
  451. lon = uroTruncate(uroTypeCast(lon));
  452. lat = uroTruncate(uroTypeCast(lat));
  453. type = uroTypeCast(type);
  454. azymuth = uroTruncate(uroTypeCast(azymuth)%360);
  455. speed = uroTruncate(uroTypeCast(speed));
  456. groupID = uroTypeCast(groupID);
  457. if(typeof validated == "string") validated = (validated == "true");
  458. if(typeof persistent == "string") persistent = (persistent == "true");
  459.  
  460. this.fid = fid;
  461. this.persistent = persistent;
  462. this.loaded = false;
  463. this.watchType = type;
  464. this.watchAzymuth = azymuth;
  465. this.watchSpeed = speed;
  466. this.watchValidated = validated;
  467. this.watchLat = lat;
  468. this.watchLon = lon;
  469. this.groupID = groupID;
  470. this.currentType = null;
  471. this.currentAzymuth = null;
  472. this.currentSpeed = null;
  473. this.currentValidated = null;
  474. this.currentLat = null;
  475. this.currentLon = null;
  476. this.server = server;
  477. }
  478.  
  479. function uroCamDataChanged(camidx)
  480. {
  481. camObj = uroCamWatchObjects[camidx];
  482. if(camObj.loaded == false) return false;
  483. if(camObj.currentType != camObj.watchType) return true;
  484. if(camObj.currentAzymuth != camObj.watchAzymuth) return true;
  485. if(camObj.currentSpeed != camObj.watchSpeed) return true;
  486. if(camObj.currentValidated != camObj.watchValidated) return true;
  487. if(camObj.currentLat != camObj.watchLat) return true;
  488. if(camObj.currentLon != camObj.watchLon) return true;
  489. return false;
  490. }
  491.  
  492. function uroAddCurrentCamWatchData(idx, lat, lon, type, azymuth, speed, validated, server)
  493. {
  494. camObj = uroCamWatchObjects[idx];
  495. camObj.loaded = true;
  496. camObj.currentType = type;
  497. camObj.currentAzymuth = uroTruncate(azymuth%360);
  498. camObj.currentSpeed = uroTruncate(speed);
  499. camObj.currentValidated = validated;
  500. camObj.currentLat = uroTruncate(lat);
  501. camObj.currentLon = uroTruncate(lon);
  502. camObj.server = server;
  503. return(uroCamDataChanged(idx));
  504. }
  505.  
  506. function uroIsCamOnWatchList(fid)
  507. {
  508. for(var loop=0;loop<uroCamWatchObjects.length;loop++)
  509. {
  510. if(uroCamWatchObjects[loop].fid == fid) return loop;
  511. }
  512. return -1;
  513. }
  514.  
  515. function uroAddCamToWatchList()
  516. {
  517. if(uroIsCamOnWatchList(uroShownFID) == -1)
  518. {
  519. camObj = wazeModel.cameras.objects[uroShownFID];
  520. uroCamWatchObjects.push(new uroCamWatchObj(true, uroShownFID, camObj.geometry.x, camObj.geometry.y, camObj.attributes.type, camObj.attributes.azymuth, camObj.attributes.speed, camObj.attributes.validated, 0, W.location.code));
  521. uroAddCurrentCamWatchData(uroCamWatchObjects.length-1, camObj.geometry.y, camObj.geometry.x, camObj.attributes.type, camObj.attributes.azymuth, camObj.attributes.speed, camObj.attributes.validated, W.location.code);
  522. uroAddLog('added camera '+uroShownFID+' to watchlist');
  523. uroCWLUpdateHTML();
  524. }
  525. }
  526.  
  527. function uroRemoveCamFromWatchList()
  528. {
  529. camidx = uroIsCamOnWatchList(uroShownFID);
  530. if(camidx != -1)
  531. {
  532. uroCamWatchObjects.splice(camidx,1);
  533. uroAddLog('removed camera '+uroShownFID+' from watchlist');
  534. uroCWLUpdateHTML();
  535. }
  536. }
  537.  
  538. function uroUpdateCamWatchList()
  539. {
  540. var camIdx = uroIsCamOnWatchList(uroShownFID);
  541. if(camIdx != -1)
  542. {
  543. var camObj = wazeModel.cameras.objects[uroShownFID];
  544. uroCamWatchObjects[camIdx].lon = camObj.geometry.x;
  545. uroCamWatchObjects[camIdx].lat = camObj.geometry.y;
  546. uroCamWatchObjects[camIdx].azymuth = camObj.attributes.azymuth;
  547. uroCamWatchObjects[camIdx].speed = camObj.attributes.speed;
  548. uroCamWatchObjects[camIdx].validated = camObj.attributes.validated;
  549. }
  550. }
  551.  
  552.  
  553. function uroClearCamWatchList()
  554. {
  555. if(confirm('Removing all cameras from the CWL cannot be undone\nAre you sure you want to do this?') == true)
  556. {
  557. uroCamWatchObjects = new Array();
  558. uroCWLUpdateHTML();
  559. }
  560. }
  561.  
  562. function uroTruncate(val)
  563. {
  564. if(val == null) return val;
  565. if(val < 0) return Math.ceil(val);
  566. return Math.floor(val);
  567. }
  568.  
  569.  
  570. function uroRetrieveCameras(lat, lon)
  571. {
  572. var camPos = new OpenLayers.LonLat();
  573. var camChanged = false;
  574. camPos.lon = lon;
  575. camPos.lat = lat;
  576. camPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
  577.  
  578. var camURL = 'https://' + document.location.host;
  579. camURL += Waze.Config.api_base;
  580. camURL += '/Features?language=en&cameras=true&bbox=';
  581. var latl = camPos.lat - 0.25;
  582. var latu = camPos.lat + 0.25;
  583. var lonl = camPos.lon - 0.25;
  584. var lonr = camPos.lon + 0.25;
  585. camURL += lonl+','+latl+','+lonr+','+latu;
  586. uroAddLog('retrieving camera data around '+camPos.lon+','+camPos.lat);
  587.  
  588. camReq = new XMLHttpRequest();
  589. camReq.open('GET',camURL,false);
  590. try
  591. {
  592. camReq.send();
  593. uroAddLog('response '+camReq.status+' received');
  594. if (camReq.status === 200)
  595. {
  596. camData = JSON.parse(camReq.responseText);
  597. for(var camIdx = 0; camIdx < camData.cameras.objects.length; camIdx++)
  598. {
  599. camObj = camData.cameras.objects[camIdx];
  600. var listIdx = uroIsCamOnWatchList(camObj.id);
  601. if(listIdx != -1)
  602. {
  603. camPos.lon = camObj.geometry.coordinates[0];
  604. camPos.lat = camObj.geometry.coordinates[1];
  605. camPos.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
  606. camPos.lon = uroTruncate(camPos.lon);
  607. camPos.lat = uroTruncate(camPos.lat);
  608. camChanged |= uroAddCurrentCamWatchData(listIdx, camPos.lat, camPos.lon, camObj.type, camObj.azymuth, camObj.speed, camObj.validated, W.location.code);
  609. }
  610. else if(camObj.validated == false)
  611. {
  612.  
  613. }
  614. }
  615. }
  616. else
  617. {
  618. uroAddLog('request failed (status != 200)');
  619. }
  620. }
  621. catch(err)
  622. {
  623. uroAddLog('camera load request failed (exception '+err+' caught)');
  624. }
  625. return camChanged;
  626. }
  627.  
  628.  
  629. function uroGetCurrentCamWatchListObjects()
  630. {
  631. var camChanged = false;
  632. var camsChanged = new Array();
  633. var camsDeleted = new Array();
  634. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  635. {
  636. camObj = uroCamWatchObjects[camidx];
  637. if((camObj.loaded == false) && ((camObj.server == W.location.code) || (camObj.server == '??')))
  638. {
  639. if(typeof wazeModel.cameras.objects[camObj.fid] == 'object')
  640. {
  641. if(wazeModel.cameras.objects[camObj.fid].state != "Delete")
  642. {
  643. wazeObj = wazeModel.cameras.objects[camObj.fid];
  644. camChanged |= uroAddCurrentCamWatchData(camidx, wazeObj.geometry.y, wazeObj.geometry.x, wazeObj.attributes.type, wazeObj.attributes.azymuth, wazeObj.attributes.speed, wazeObj.attributes.validated);
  645. }
  646. else
  647. {
  648. camChanged |= uroRetrieveCameras(camObj.watchLat, camObj.watchLon);
  649. }
  650. }
  651. else
  652. {
  653. camChanged |= uroRetrieveCameras(camObj.watchLat, camObj.watchLon);
  654. }
  655. }
  656. }
  657. if(camChanged)
  658. {
  659. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  660. {
  661. if(uroCamDataChanged(camidx))
  662. {
  663. camsChanged.push(uroCamWatchObjects[camidx]);
  664. }
  665. }
  666. }
  667.  
  668. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  669. {
  670. camObj = uroCamWatchObjects[camidx];
  671. if((camObj.loaded == false) && (camObj.server == W.location.code))
  672. {
  673. camsDeleted.push(camObj);
  674. }
  675. }
  676.  
  677. if((camsChanged.length > 0) || (camsDeleted.length > 0))
  678. {
  679. var alertStr = 'Camera WatchList Alert!!!\r\n';
  680. for(var camidx=0;camidx<camsChanged.length;camidx++)
  681. {
  682. alertStr += 'Camera ID '+camsChanged[camidx].fid+' in group "'+uroFindCWLGroupByIdx(camsChanged[camidx].groupID)+'" has been changed\r\n';
  683. }
  684. for(var camidx=0;camidx<camsDeleted.length;camidx++)
  685. {
  686. alertStr += 'Camera ID '+camsDeleted[camidx].fid+' in group "'+uroFindCWLGroupByIdx(camsDeleted[camidx].groupID)+'" has been deleted\r\n';
  687. }
  688. alert(alertStr);
  689. }
  690. }
  691.  
  692. function uroClearDeletedCameras()
  693. {
  694. for(var camidx=uroCamWatchObjects.length-1;camidx>=0;camidx--)
  695. {
  696. if(uroCamWatchObjects[camidx].loaded == false)
  697. {
  698. uroShownFID = uroCamWatchObjects[camidx].fid;
  699. uroRemoveCamFromWatchList();
  700. }
  701. }
  702. }
  703.  
  704. function uroRescanCamWatchList()
  705. {
  706. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  707. {
  708. uroCamWatchObjects[camidx].loaded = false;
  709. }
  710. uroGetCurrentCamWatchListObjects();
  711. uroCWLUpdateHTML();
  712. }
  713.  
  714.  
  715. function uroGotoCam()
  716. {
  717. var camidx = this.id.substr(13);
  718. var camPos = new OpenLayers.LonLat();
  719. camPos.lon = uroCamWatchObjects[camidx].watchLon;
  720. camPos.lat = uroCamWatchObjects[camidx].watchLat;
  721. wazeMap.setCenter(camPos,4);
  722. wazeMap.layers[uroCamLayer].setVisibility(true);
  723. return false;
  724. }
  725.  
  726. function uroSetCamGroup()
  727. {
  728. var camidx = this.id.substr(13);
  729. return false;
  730. }
  731.  
  732. function uroHighlightCWLEntry()
  733. {
  734. this.style.backgroundColor = '#FFFFAA';
  735. return false;
  736. }
  737.  
  738. function uroUnhighlightCWLEntry()
  739. {
  740. var camidx = this.id.substr(8);
  741. var changed = uroCamDataChanged(camidx);
  742. var deleted = (uroCamWatchObjects[camidx].loaded == false);
  743.  
  744. if(uroCamWatchObjects[camidx].server != W.location.code) this.style.backgroundColor = '#A0A0A0';
  745. else if(changed) this.style.backgroundColor = '#AAAAFF';
  746. else if(deleted) this.style.backgroundColor = '#FFAAAA';
  747. else this.style.backgroundColor = '#FFFFFF';
  748. return false;
  749. }
  750.  
  751. function uroCWLIconHighlight()
  752. {
  753. iconType = this.id.substr(11,1);
  754. this.src = uroIcons[iconType][0];
  755. return false;
  756. }
  757.  
  758. function uroCWLIconLowlight()
  759. {
  760. iconType = this.id.substr(11,1);
  761. this.src = uroIcons[iconType][1];
  762. return false;
  763. }
  764.  
  765. function uroRemoveFromCWL()
  766. {
  767. uroShownFID = uroCamWatchObjects[this.id.substr(18)].fid;
  768. uroRemoveCamFromWatchList();
  769. }
  770.  
  771.  
  772. function uroSetCamGroups()
  773. {
  774. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  775. {
  776. camObj = uroCamWatchObjects[camidx];
  777. camGroup = parseInt(document.getElementById("_uroGroupSelect-"+camidx).value);
  778. camObj.groupID = camGroup;
  779. }
  780. }
  781.  
  782.  
  783. function uroPopulateCWLGroupSelect()
  784. {
  785. selector = document.getElementById('_uroCWLGroupSelect');
  786. while(selector.options.length > 0)
  787. {
  788. selector.options.remove(0);
  789. }
  790. for(var loop=0;loop<uroCWLGroups.length;loop++)
  791. {
  792. groupObj = uroCWLGroups[loop];
  793. if(groupObj.groupID != -1)
  794. {
  795. selector.options.add(new Option(groupObj.groupName,groupObj.groupID));
  796. }
  797. }
  798. }
  799.  
  800. function uroGetNextCWLGroupID()
  801. {
  802. var nextID = 1;
  803. for(var loop=0;loop<uroCWLGroups.length;loop++)
  804. {
  805. if(uroCWLGroups[loop].groupID >= nextID)
  806. {
  807. nextID = uroCWLGroups[loop].groupID + 1;
  808. }
  809. }
  810. return nextID;
  811. }
  812.  
  813. function uroFindCWLGroupByName(groupName)
  814. {
  815. var groupID = -1;
  816. for(var loop=0;loop<uroCWLGroups.length;loop++)
  817. {
  818. if((uroCWLGroups[loop].groupName == groupName) && (uroCWLGroups[loop].groupID != -1))
  819. {
  820. groupID = uroCWLGroups[loop].groupID;
  821. break;
  822. }
  823. }
  824. return groupID;
  825. }
  826.  
  827. function uroFindCWLGroupByIdx(groupIdx)
  828. {
  829. var groupName = '';
  830. for(var loop=0;loop<uroCWLGroups.length;loop++)
  831. {
  832. if(uroCWLGroups[loop].groupID == groupIdx)
  833. {
  834. groupName = uroCWLGroups[loop].groupName;
  835. break;
  836. }
  837. }
  838. return groupName;
  839. }
  840.  
  841. function uroAddCWLGroup()
  842. {
  843. var groupID = uroGetNextCWLGroupID();
  844. var groupName = document.getElementById('_uroCWLGroupEntry').value;
  845. if(uroFindCWLGroupByName(groupName) == -1)
  846. {
  847. uroCWLGroups.push(new uroCWLGroupObj(groupID,groupName,false));
  848. uroPopulateCWLGroupSelect();
  849. }
  850. }
  851.  
  852. function uroRemoveCWLGroup()
  853. {
  854. selector = document.getElementById('_uroCWLGroupSelect');
  855. var groupID = parseInt(selector.selectedOptions[0].value);
  856. if(groupID == 0) return false; // prevent deletion of the default group
  857. for(var loop=0;loop<uroCamWatchObjects.length;loop++)
  858. {
  859. cwObj = uroCamWatchObjects[loop];
  860. if(cwObj.groupID == groupID)
  861. {
  862. cwObj.groupID = 0;
  863. }
  864. }
  865. for(var loop=0;loop<uroCWLGroups.length;loop++)
  866. {
  867. groupObj = uroCWLGroups[loop];
  868. if(groupObj.groupID == groupID)
  869. {
  870. groupObj.groupID = -1;
  871. }
  872. }
  873. uroCWLUpdateHTML();
  874. }
  875.  
  876. function uroAssignCameraToGroup()
  877. {
  878. var camidx = this.id.substr(13);
  879. selector = document.getElementById('_uroCWLGroupSelect');
  880. uroCamWatchObjects[camidx].groupID = parseInt(selector.selectedOptions[0].value);
  881. uroCWLUpdateHTML();
  882. return false;
  883. }
  884.  
  885. function uroAddBtnEvl(btnID, evlType, evlFunction)
  886. {
  887. btnObj = document.getElementById(btnID);
  888. if(btnObj != null)
  889. {
  890. btnObj.addEventListener(evlType, evlFunction, true);
  891. }
  892. }
  893.  
  894. function uroCWLGroupCollapseExpand()
  895. {
  896. var groupidx = this.id.substr(18);
  897. if(uroCWLGroups[groupidx].groupCollapsed == true) uroCWLGroups[groupidx].groupCollapsed = false;
  898. else uroCWLGroups[groupidx].groupCollapsed = true;
  899. uroCWLUpdateHTML();
  900. return false;
  901. }
  902.  
  903. function uroCWLUpdateHTML()
  904. {
  905. var camTypes = new Array("","","Speed", "Dummy", "Red Light");
  906. var selectedGroup = 0;
  907. iHTML = '';
  908. if(document.getElementById('_uroCWLGroupSelect') != null)
  909. {
  910. selectedGroup = document.getElementById('_uroCWLGroupSelect').selectedIndex;
  911. }
  912.  
  913. iHTML = '<br><b>Camera Watchlist:</b><br><br>';
  914. iHTML += '<div id="_uroCWLCamList" style="height:65%;overflow:auto;">';
  915. for(var groupidx=0;groupidx<uroCWLGroups.length;groupidx++)
  916. {
  917. var groupObj = uroCWLGroups[groupidx];
  918. iHTML += '<div id="_uroCWLGroup-'+groupidx+'">';
  919. if(groupObj.groupCollapsed == true)
  920. {
  921. iHTML += '<img src="'+uroIcons[0][1]+'" id="_uroCWLGroupState-'+groupidx+'">';
  922. }
  923. else
  924. {
  925. iHTML += '<img src="'+uroIcons[0][0]+'" id="_uroCWLGroupState-'+groupidx+'">';
  926. }
  927. iHTML += '<b>'+groupObj.groupName+'</b><br>';
  928. groupObj.groupCount = 0;
  929. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  930. {
  931. camObj = uroCamWatchObjects[camidx];
  932. if(camObj.groupID == groupObj.groupID)
  933. {
  934. groupObj.groupCount++;
  935. var changed = uroCamDataChanged(camidx);
  936. var deleted = (camObj.loaded == false);
  937. iHTML += '<div id="_uroCWL-'+camidx+'" style="padding:3px;border-width:2px;border-style:solid;border-color:#FFFFFF;background-color:';
  938. if(camObj.server != W.location.code) iHTML += '#A0A0A0;';
  939. else if(changed) iHTML += '#AAAAFF;';
  940. else if(deleted) iHTML += '#FFAAAA;';
  941. else iHTML += '#FFFFFF;';
  942. if(groupObj.groupCollapsed == true) iHTML += 'display:none;">';
  943. else iHTML += 'display:block;">';
  944.  
  945. iHTML += 'ID: '+camObj.fid;
  946. iHTML += ' ('+camObj.server+')';
  947. iHTML += ' Type: '+camTypes[camObj.watchType];
  948. if(camObj.server != W.location.code)
  949. {
  950. iHTML += '<br><i>Not on this server</i>';
  951. }
  952. else if(deleted)
  953. {
  954. iHTML += '<br>DELETED';
  955. }
  956. else if(changed)
  957. {
  958. if(camObj.currentType != camObj.watchType)
  959. {
  960. iHTML += '<br>&nbsp;&nbsp;Type changed';
  961. iHTML += ' ('+camObj.watchType+' to '+camObj.currentType+')';
  962. }
  963. if(camObj.currentAzymuth != camObj.watchAzymuth)
  964. {
  965. iHTML += '<br>&nbsp;&nbsp;Azimuth changed';
  966. iHTML += ' ('+camObj.watchAzymuth+' to '+camObj.currentAzymuth+')';
  967. }
  968. if(camObj.currentSpeed != camObj.watchSpeed)
  969. {
  970. iHTML += '<br>&nbsp;&nbsp;Speed changed';
  971. iHTML += ' ('+camObj.watchSpeed+' to '+camObj.currentSpeed+')';
  972. }
  973. if(camObj.currentValidated != camObj.watchValidated)
  974. {
  975. iHTML += '<br>&nbsp;&nbsp;Approval state changed';
  976. iHTML += ' ('+camObj.watchValidated+' to '+camObj.currentValidated+')';
  977. }
  978. if(camObj.currentLat != camObj.watchLat)
  979. {
  980. iHTML += '<br>&nbsp;&nbsp;Latitude changed';
  981. iHTML += ' ('+camObj.watchLat+' to '+camObj.currentLat+')';
  982. }
  983. if(camObj.currentLon != camObj.watchLon)
  984. {
  985. iHTML += '<br>&nbsp;&nbsp;Longitude changed';
  986. iHTML += ' ('+camObj.watchLon+' to '+camObj.currentLon+')';
  987. }
  988. }
  989. if(camObj.server == W.location.code)
  990. {
  991. iHTML += '&nbsp;<img id="_uroCWLIcon1-'+camidx+'" src="'+uroIcons[1][1]+'">';
  992. iHTML += '&nbsp;<img id="_uroCWLIcon2-'+camidx+'" src="'+uroIcons[2][1]+'">';
  993. }
  994. iHTML += '</div>';
  995. }
  996. }
  997. iHTML += '</div>';
  998. }
  999. iHTML += '</div><div id="_uroCWLControls">';
  1000. iHTML += '<hr>Group control:<br>';
  1001. iHTML += '<select id="_uroCWLGroupSelect" style="width:40%;height:22px;"></select>&nbsp;<input type="button" id="_btnCWLGroupDel" value="Delete group"><br>';
  1002. iHTML += '<input type="text" id="_uroCWLGroupEntry" style="width:40%;height:22px;">&nbsp;<input type="button" id="_btnCWLGroupAdd" value="Add group">';
  1003. iHTML += '<hr><input type="button" id="_btnRescanCamWatchList" value="Rescan">';
  1004. iHTML += '&nbsp;|&nbsp;<input type="button" id="_btnRemoveDeletedCameras" value="Remove deleted">';
  1005. iHTML += '&nbsp;|&nbsp;<input type="button" id="_btnClearCamWatchList" value="Remove all">';
  1006. iHTML += '</div>';
  1007. uroCamWatchlist.innerHTML = iHTML;
  1008. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  1009. {
  1010. document.getElementById("_uroCWL-"+camidx).onmouseover = uroHighlightCWLEntry;
  1011. document.getElementById("_uroCWL-"+camidx).onmouseleave = uroUnhighlightCWLEntry;
  1012.  
  1013. if(camObj.server == W.location.code)
  1014. {
  1015. document.getElementById("_uroCWLIcon1-"+camidx).onmouseover = uroCWLIconHighlight;
  1016. document.getElementById("_uroCWLIcon1-"+camidx).onmouseleave = uroCWLIconLowlight;
  1017. document.getElementById("_uroCWLIcon1-"+camidx).onclick = uroAssignCameraToGroup;
  1018.  
  1019. document.getElementById("_uroCWLIcon2-"+camidx).onmouseover = uroCWLIconHighlight;
  1020. document.getElementById("_uroCWLIcon2-"+camidx).onmouseleave = uroCWLIconLowlight;
  1021. document.getElementById("_uroCWLIcon2-"+camidx).onclick = uroGotoCam;
  1022. }
  1023. }
  1024. uroAddBtnEvl('_btnClearCamWatchList', 'click', uroClearCamWatchList);
  1025. uroAddBtnEvl('_btnRemoveDeletedCameras', 'click', uroClearDeletedCameras);
  1026. uroAddBtnEvl('_btnRescanCamWatchList', 'click', uroRescanCamWatchList);
  1027. uroAddBtnEvl('_btnCWLGroupDel', 'click', uroRemoveCWLGroup);
  1028. uroAddBtnEvl('_btnCWLGroupAdd', 'click', uroAddCWLGroup);
  1029. if(document.getElementById('_uroCWLGroupSelect') != null)
  1030. {
  1031. uroAddLog('populating CWL group list');
  1032. uroPopulateCWLGroupSelect();
  1033. selector = document.getElementById('_uroCWLGroupSelect');
  1034. if(selectedGroup >= selector.length)
  1035. {
  1036. selectedGroup = 0;
  1037. }
  1038. selector.selectedIndex = selectedGroup;
  1039. }
  1040.  
  1041. for(var groupidx=0;groupidx<uroCWLGroups.length;groupidx++)
  1042. {
  1043. if(uroCWLGroups[groupidx].groupCount == 0)
  1044. {
  1045. document.getElementById('_uroCWLGroup-'+groupidx).style.display = 'none';
  1046. }
  1047. else
  1048. {
  1049. document.getElementById('_uroCWLGroupState-'+groupidx).onclick = uroCWLGroupCollapseExpand;
  1050. }
  1051. }
  1052. }
  1053.  
  1054.  
  1055. function uroIsOnIgnoreList(fid)
  1056. {
  1057. if(sessionStorage.UROverview_FID_IgnoreList.indexOf('fid:'+fid) == -1) return false;
  1058. else return true;
  1059. }
  1060.  
  1061. function uroEnableIgnoreListControls()
  1062. {
  1063. var btnState = false;
  1064. if(sessionStorage.UROverview_FID_IgnoreList == '')
  1065. {
  1066. btnState = true;
  1067. }
  1068. document.getElementById('_btnUndoLastHide').disabled = btnState;
  1069. document.getElementById('_btnClearSessionHides').disabled = btnState;
  1070. uroFilterURMarkers();
  1071. }
  1072.  
  1073. function uroAddToIgnoreList()
  1074. {
  1075. if(!uroIsOnIgnoreList(uroShownFID))
  1076. {
  1077. sessionStorage.UROverview_FID_IgnoreList += 'fid:'+uroShownFID;
  1078. uroAddLog('added fid '+uroShownFID+' to ignore list');
  1079. uroAddLog(sessionStorage.UROverview_FID_IgnoreList);
  1080. document.getElementById('_btnUndoLastHide').disabled = false;
  1081. document.getElementById('_btnClearSessionHides').disabled = false;
  1082. uroDiv.style.visibility = 'hidden';
  1083. uroEnableIgnoreListControls();
  1084. wazeMap.events.register("mousemove", null, uroFilterURMarkers5);
  1085. }
  1086. return false;
  1087. }
  1088.  
  1089. function uroRemoveFromIgnoreList(fid)
  1090. {
  1091. var ignorelist = sessionStorage.UROverview_FID_IgnoreList;
  1092. var fidpos = ignorelist.indexOf('fid:'+fid);
  1093. if(fidpos != -1)
  1094. {
  1095. var preFID = ignorelist.slice(0,fidpos);
  1096. ignorelist = ignorelist.slice(fidpos+1);
  1097. fidpos = ignorelist.indexOf('fid:');
  1098. if(fidpos == -1) ignorelist = '';
  1099. else ignorelist = ignorelist.slice(fidpos);
  1100. sessionStorage.UROverview_FID_IgnoreList = preFID + ignorelist;
  1101. uroAddLog('removed fid '+fid+' from ignore list');
  1102. uroAddLog(sessionStorage.UROverview_FID_IgnoreList);
  1103. uroEnableIgnoreListControls();
  1104. }
  1105. }
  1106.  
  1107. function uroRemoveLastAddedIgnore()
  1108. {
  1109. var ignorelist = sessionStorage.UROverview_FID_IgnoreList;
  1110. var fidpos = ignorelist.lastIndexOf('fid:');
  1111. if(fidpos != -1)
  1112. {
  1113. ignorelist = ignorelist.slice(0,fidpos);
  1114. sessionStorage.UROverview_FID_IgnoreList = ignorelist;
  1115. uroAddLog('removed last fid from ignore list');
  1116. uroAddLog(sessionStorage.UROverview_FID_IgnoreList);
  1117. uroEnableIgnoreListControls();
  1118. }
  1119. }
  1120.  
  1121. function uroRemoveAllIgnores()
  1122. {
  1123. sessionStorage.UROverview_FID_IgnoreList = '';
  1124. uroEnableIgnoreListControls();
  1125. }
  1126.  
  1127.  
  1128. function uroKeywordPresent(desc, keyword)
  1129. {
  1130. if(document.getElementById('_cbCaseInsensitive').checked == true) re = RegExp(keyword,'i');
  1131. else re = RegExp(keyword);
  1132. if(desc.search(re) == -1) return false;
  1133. else return true;
  1134. }
  1135.  
  1136.  
  1137. function uroMaskTest()
  1138. {
  1139. if(wazeMap.layers[uroMaskLayer].div == null)
  1140. {
  1141. if(uroMaskActive == false)
  1142. {
  1143. uroAddLog('mask layer not found');
  1144. uroMaskActive = true;
  1145. }
  1146. return true;
  1147. }
  1148. if(wazeMap.layers[uroMaskLayer].div.innerHTML.indexOf('fill="black"') != -1)
  1149. {
  1150. if(uroMaskActive == false)
  1151. {
  1152. uroAddLog('mask layer active');
  1153. uroMaskActive = true;
  1154. }
  1155. return true;
  1156. }
  1157. uroMaskActive = false;
  1158. return false;
  1159. }
  1160.  
  1161.  
  1162. function uroRefreshUpdateRequestSessions()
  1163. {
  1164. var idList = [];
  1165. for (var urID in wazeModel.mapUpdateRequests.objects)
  1166. {
  1167. if(wazeModel.updateRequestSessions.objects[urID] == null) idList.push(urID);
  1168. }
  1169. if(idList.length > 0)
  1170. {
  1171. uroAddLog('grabbing updateRequestSessions with IDs '+idList);
  1172. wazeModel.updateRequestSessions.get(idList);
  1173. }
  1174. }
  1175.  
  1176. function uroURHasMyComments(fid)
  1177. {
  1178. var nComments = wazeModel.updateRequestSessions.objects[fid].comments.length;
  1179. if(nComments == 0) return false;
  1180.  
  1181. for(var cidx=0; cidx<nComments; cidx++)
  1182. {
  1183. if(wazeModel.updateRequestSessions.objects[fid].comments[cidx].userID == uroUserID) return true;
  1184. }
  1185. return false;
  1186. }
  1187. function uroAddCommentMarkers(urID, hasMyComments, nComments)
  1188. {
  1189. var useDefaultMarker = false;
  1190. if((document.getElementById('_cbNativeConvoMarkers').checked) && (uroBetaEditor == false)) useDefaultMarker = true;
  1191. if((document.getElementById('_cbNativeBetaConvoMarkers').checked) && (uroBetaEditor == true)) useDefaultMarker = true;
  1192. var divElem = document.getElementById(wazeMap.layers[uroURLayerIdx].id);
  1193. if(divElem.childNodes.length > 0)
  1194. {
  1195. for(var nodeIdx = 0; nodeIdx < divElem.childNodes.length; nodeIdx++)
  1196. {
  1197. if(divElem.childNodes[nodeIdx].getAttribute("data-id") == urID)
  1198. {
  1199. var divHTML = divElem.childNodes[nodeIdx].innerHTML;
  1200. if(divHTML.indexOf('customMarker_') == -1)
  1201. {
  1202. divHTML = '';
  1203. }
  1204. if(document.getElementById('_cbCommentCount').checked)
  1205. {
  1206. divHTML += '<div style="position:absolute;top:-9px;left:-11px;pointer-events:none;">';
  1207. divHTML += '<img src="https://www.chizzum.com/greasemonkey/images/ur_comment_count.png">';
  1208. divHTML += '</div>';
  1209. divHTML += '<div style="position:absolute;top:-6px;left:-';
  1210. if(nComments < 10) divHTML += '0';
  1211. else if(nComments < 100) divHTML += '3';
  1212. else divHTML += '6';
  1213. divHTML += 'px;font-size:11px;;pointer-events:none;">'+nComments+'</div>';
  1214. }
  1215.  
  1216. if(useDefaultMarker == false)
  1217. {
  1218. divHTML += '<div style="position:absolute;top:-9px;left:18px;pointer-events:none;">';
  1219. if(hasMyComments) divHTML += '<img src="https://www.chizzum.com/greasemonkey/images/ur_own_comment_marker.png">';
  1220. else divHTML += '<img src="https://www.chizzum.com/greasemonkey/images/ur_comment_marker.png">';
  1221. divHTML += '</div>';
  1222. wazeMap.layers[uroURLayerIdx].markers[urID].icon.imageDiv.classList.remove("has-comments")
  1223. }
  1224. else
  1225. {
  1226. wazeMap.layers[uroURLayerIdx].markers[urID].icon.imageDiv.classList.add("has-comments")
  1227. }
  1228.  
  1229. divElem.childNodes[nodeIdx].innerHTML = divHTML;
  1230. return;
  1231. }
  1232. }
  1233. }
  1234. }
  1235.  
  1236.  
  1237. function uroAddCustomMarkers(urID,customType)
  1238. {
  1239. var useCustomMarkers = false;
  1240.  
  1241. if(customType == 0) useCustomMarkers = (document.getElementById('_cbCustomRoadworksMarkers').checked);
  1242. if(customType == 1) useCustomMarkers = (document.getElementById('_cbCustomConstructionMarkers').checked);
  1243. if(customType == 2) useCustomMarkers = (document.getElementById('_cbCustomClosuresMarkers').checked);
  1244. if(customType == 3) useCustomMarkers = (document.getElementById('_cbCustomEventsMarkers').checked);
  1245. var divElem = document.getElementById(wazeMap.layers[uroURLayerIdx].id);
  1246. if(divElem.childNodes.length > 0)
  1247. {
  1248. for(var nodeIdx = 0; nodeIdx < divElem.childNodes.length; nodeIdx++)
  1249. {
  1250. if(divElem.childNodes[nodeIdx].getAttribute("data-id") == urID)
  1251. {
  1252. var divHTML = '';
  1253. if(useCustomMarkers == true)
  1254. {
  1255. divHTML += '<div id="customMarker_'+urID+'" style="position:absolute;pointer-events:none;">';
  1256. customType = uroGetCustomMarkerIdx(customType);
  1257. if(W.model.updateRequestSessions.objects[urID].open == false) customType += 3;
  1258. divHTML += '<img src="'+uroIcons[customType][0]+'">';
  1259. divHTML += '</div>';
  1260. }
  1261. divElem.childNodes[nodeIdx].innerHTML = divHTML;
  1262. return;
  1263. }
  1264. }
  1265. }
  1266. }
  1267.  
  1268. function uroChangeCustomMarkers(urID,isHighlighted,customType)
  1269. {
  1270. if(document.getElementById('customMarker_'+urID) != null)
  1271. {
  1272. if(W.model.updateRequestSessions.objects[urID].open == false) customType += 3;
  1273.  
  1274. if(isHighlighted == true)
  1275. {
  1276. document.getElementById('customMarker_'+urID).innerHTML = '<img src="'+uroIcons[customType][1]+'">';
  1277. }
  1278. else
  1279. {
  1280. document.getElementById('customMarker_'+urID).innerHTML = '<img src="'+uroIcons[customType][0]+'">';
  1281. }
  1282. }
  1283. }
  1284.  
  1285.  
  1286. function uroFilterURMarkers()
  1287. {
  1288. var mapviewport = document.getElementsByClassName("olMapViewport")[0];
  1289. if(mapviewport == null)
  1290. {
  1291. if(uroNullMapViewport == false)
  1292. {
  1293. uroAddLog('caught null mapviewport');
  1294. uroNullMapViewport = true;
  1295. }
  1296. return;
  1297. }
  1298. uroNullMapViewport = false;
  1299. if(document.getElementById('_cbWhiteBackground').checked)
  1300. {
  1301. mapviewport.style.backgroundColor = "#FFFFFF";
  1302. }
  1303. else
  1304. {
  1305. mapviewport.style.backgroundColor = "#555555";
  1306. }
  1307. if(document.getElementById('_cbHideAMLayer').checked)
  1308. {
  1309. wazeMap.layers[uroAMLayerIdx].setOpacity(0);
  1310. }
  1311. else
  1312. {
  1313. wazeMap.layers[uroAMLayerIdx].setOpacity(1);
  1314. }
  1315. if(uroMaskTest() == true) return;
  1316.  
  1317. var camLayer = document.getElementById(uroRootContainer+'_svgRoot');
  1318. if(camLayer == null)
  1319. {
  1320. if(uroNullCamLayer == false)
  1321. {
  1322. uroAddLog('caught null camLayer');
  1323. uroNullCamLayer = true;
  1324. }
  1325. return;
  1326. }
  1327. uroNullCamLayer = false;
  1328.  
  1329. uroRefreshUpdateRequestSessions();
  1330.  
  1331. for (var uroCamObj in wazeModel.cameras.objects)
  1332. {
  1333. var uroCam = wazeModel.cameras.objects[uroCamObj];
  1334. var uroCamStyle = 'visible';
  1335. if(wazeModel.users.objects[uroCam.attributes.createdBy] != null)
  1336. {
  1337. var uroCamCreator = wazeModel.users.objects[uroCam.attributes.createdBy].userName;
  1338. var uroCamCreatorRank = wazeModel.users.objects[uroCam.attributes.createdBy].rank;
  1339. }
  1340. else
  1341. {
  1342. var uroCamCreator = '';
  1343. var uroCamCreatorRank = -1;
  1344. }
  1345. if(wazeModel.users.objects[uroCam.attributes.updatedBy] != null)
  1346. {
  1347. var uroCamUpdater = wazeModel.users.objects[uroCam.attributes.updatedBy].userName;
  1348. var uroCamUpdaterRank = wazeModel.users.objects[uroCam.attributes.updatedBy].rank;
  1349. }
  1350. else
  1351. {
  1352. var uroCamUpdater = '';
  1353. var uroCamUpdaterRank = -1;
  1354. }
  1355.  
  1356. var uroCamApproved = uroCam.attributes.validated;
  1357. var uroCamType = uroCam.attributes.type;
  1358.  
  1359.  
  1360. if(document.getElementById('_cbShowOnlyMyCams').checked == true)
  1361. {
  1362. if((uroUserID != uroCam.attributes.createdBy)&&(uroUserID != uroCam.attributes.updatedBy)) uroCamStyle = 'hidden';
  1363. }
  1364.  
  1365. if((document.getElementById('_cbShowWorldCams').checked == false) || (document.getElementById('_cbShowUSACams').checked == false) || (document.getElementById('_cbShowNonWorldCams').checked == false))
  1366. {
  1367. var posWorld = uroCamCreator.indexOf('world_');
  1368. var posUSA = uroCamCreator.indexOf('usa_');
  1369.  
  1370. if((document.getElementById('_cbShowWorldCams').checked == false) && (posWorld == 0)) uroCamStyle = 'hidden';
  1371. if((document.getElementById('_cbShowUSACams').checked == false) && (posUSA == 0)) uroCamStyle = 'hidden';
  1372. if((document.getElementById('_cbShowNonWorldCams').checked == false) && (posWorld != 0) && (posUSA != 0)) uroCamStyle = 'hidden';
  1373. }
  1374.  
  1375. if((document.getElementById('_cbShowApprovedCams').checked == false) || (document.getElementById('_cbShowNonApprovedCams').checked == false))
  1376. {
  1377. if((document.getElementById('_cbShowApprovedCams').checked == false) && (uroCamApproved == true)) uroCamStyle = 'hidden';
  1378. if((document.getElementById('_cbShowNonApprovedCams').checked == false) && (uroCamApproved == false)) uroCamStyle = 'hidden';
  1379. }
  1380.  
  1381. if((document.getElementById('_cbShowNonApprovedCams').checked == true) && (uroCamApproved == false))
  1382. {
  1383. if(((document.getElementById('_cbShowOlderCreatedNonApproved').checked == true)) && (uroGetCameraAge(uroCam,1) <= document.getElementById('_inputCameraMinCreatedDays').value)) uroCamStyle = 'hidden';
  1384. if(((document.getElementById('_cbShowOlderUpdatedNonApproved').checked == true)) && (uroGetCameraAge(uroCam,0) <= document.getElementById('_inputCameraMinUpdatedDays').value)) uroCamStyle = 'hidden';
  1385. }
  1386.  
  1387. if((document.getElementById('_cbShowSpeedCams').checked == false) || (document.getElementById('_cbShowRedLightCams').checked == false) || (document.getElementById('_cbShowDummyCams').checked == false))
  1388. {
  1389. if((document.getElementById('_cbShowSpeedCams').checked == false) && (uroCamType == 2)) uroCamStyle = 'hidden';
  1390. if((document.getElementById('_cbShowRedLightCams').checked == false) && (uroCamType == 4)) uroCamStyle = 'hidden';
  1391. if((document.getElementById('_cbShowDummyCams').checked == false) && (uroCamType == 3)) uroCamStyle = 'hidden';
  1392. }
  1393.  
  1394. if(document.getElementById('_cbShowSpeedCams').checked == true)
  1395. {
  1396. if((document.getElementById('_cbShowIfMPHSpeedSet').checked == false) && (uroIsCameraSpeedValid(uroCam) == 1)) uroCamStyle = 'hidden';
  1397. if((document.getElementById('_cbShowIfNoSpeedSet').checked == false) && (uroIsCameraSpeedValid(uroCam) == 0)) uroCamStyle = 'hidden';
  1398. if((document.getElementById('_cbShowIfKPHSpeedSet').checked == false) && (uroIsCameraSpeedValid(uroCam) == -1)) uroCamStyle = 'hidden';
  1399. }
  1400.  
  1401. if(document.getElementById('_cbHideCreatedByMe').checked == true)
  1402. {
  1403. if(uroUserID == uroCam.attributes.createdBy) uroCamStyle = 'hidden';
  1404. }
  1405. if((document.getElementById('_cbHideCreatedByRank0').checked == true) && (uroCamCreatorRank == 0)) uroCamStyle = 'hidden';
  1406. if((document.getElementById('_cbHideCreatedByRank1').checked == true) && (uroCamCreatorRank == 1)) uroCamStyle = 'hidden';
  1407. if((document.getElementById('_cbHideCreatedByRank2').checked == true) && (uroCamCreatorRank == 2)) uroCamStyle = 'hidden';
  1408. if((document.getElementById('_cbHideCreatedByRank3').checked == true) && (uroCamCreatorRank == 3)) uroCamStyle = 'hidden';
  1409. if((document.getElementById('_cbHideCreatedByRank4').checked == true) && (uroCamCreatorRank == 4)) uroCamStyle = 'hidden';
  1410. if((document.getElementById('_cbHideCreatedByRank5').checked == true) && (uroCamCreatorRank == 5)) uroCamStyle = 'hidden';
  1411.  
  1412. if(document.getElementById('_cbHideUpdatedByMe').checked == true)
  1413. {
  1414. if(uroUserID == uroCam.attributes.updatedBy) uroCamStyle = 'hidden';
  1415. }
  1416. if((document.getElementById('_cbHideUpdatedByRank0').checked == true) && (uroCamUpdaterRank == 0)) uroCamStyle = 'hidden';
  1417. if((document.getElementById('_cbHideUpdatedByRank1').checked == true) && (uroCamUpdaterRank == 1)) uroCamStyle = 'hidden';
  1418. if((document.getElementById('_cbHideUpdatedByRank2').checked == true) && (uroCamUpdaterRank == 2)) uroCamStyle = 'hidden';
  1419. if((document.getElementById('_cbHideUpdatedByRank3').checked == true) && (uroCamUpdaterRank == 3)) uroCamStyle = 'hidden';
  1420. if((document.getElementById('_cbHideUpdatedByRank4').checked == true) && (uroCamUpdaterRank == 4)) uroCamStyle = 'hidden';
  1421. if((document.getElementById('_cbHideUpdatedByRank5').checked == true) && (uroCamUpdaterRank == 5)) uroCamStyle = 'hidden';
  1422.  
  1423. if((document.getElementById('_cbHideCWLCams').checked == true) && (uroIsCamOnWatchList(uroCam.fid) != -1)) uroCamStyle = 'hidden';
  1424.  
  1425. var uroCamGeometryID = uroCam.geometry.id;
  1426. if(camLayer.getElementById(uroCamGeometryID) != null)
  1427. {
  1428. camLayer.getElementById(uroCamGeometryID).style.visibility = uroCamStyle;
  1429. }
  1430. }
  1431.  
  1432. for (var urobj in wazeModel.mapUpdateRequests.objects)
  1433. {
  1434. var ureq = wazeModel.mapUpdateRequests.objects[urobj];
  1435. var urStyle = 'visible';
  1436. var cryosphere_link = false;
  1437. var wazeauto_ur = false;
  1438. var ukroadworks_ur = false;
  1439. var construction_ur = false;
  1440. var closure_ur = false;
  1441. var event_ur = false;
  1442. var hasMyComments = false;
  1443. var nComments = 0;
  1444. var commentDaysOld = -1;
  1445.  
  1446. var desc = '';
  1447. if(ureq.attributes.description != null) desc = ureq.attributes.description;
  1448. var ureqID = null;
  1449. if(ureq.fid == null) ureqID = ureq.attributes.id;
  1450. else ureqID = ureq.fid;
  1451.  
  1452. // check UR against current session ignore list...
  1453. if(uroIsOnIgnoreList(ureqID)) urStyle = 'hidden';
  1454.  
  1455. // check against closed/not identified filtering if enabled...
  1456. if(document.getElementById('_cbFilterSolved').checked == true)
  1457. {
  1458. if(ureq.attributes.resolution == 0) urStyle = 'hidden';
  1459. }
  1460. if(document.getElementById('_cbFilterUnidentified').checked == true)
  1461. {
  1462. if(ureq.attributes.resolution == 1) urStyle = 'hidden';
  1463. }
  1464. if((ureq.attributes.resolvedOn != null) && (document.getElementById('_cbFilterClosedUR').checked == true))
  1465. {
  1466. urStyle = 'hidden';
  1467. }
  1468.  
  1469. if(urStyle == 'visible')
  1470. {
  1471. // check UR against keyword filtering if enabled...
  1472. if(document.getElementById('_cbURDescriptionMustBePresent').checked == true)
  1473. {
  1474. if(desc == '') urStyle = 'hidden';
  1475. }
  1476. if(document.getElementById('_cbURDescriptionMustBeAbsent').checked == true)
  1477. {
  1478. if(desc != '') urStyle = 'hidden';
  1479. }
  1480. if(document.getElementById('_cbEnableKeywordMustBePresent').checked == true)
  1481. {
  1482. if(!uroKeywordPresent(desc,document.getElementById('_textKeywordPresent').value)) urStyle = 'hidden';
  1483. }
  1484. if(document.getElementById('_cbEnableKeywordMustBeAbsent').checked == true)
  1485. {
  1486. if(uroKeywordPresent(desc,document.getElementById('_textKeywordAbsent').value)) urStyle = 'hidden';
  1487. }
  1488. }
  1489.  
  1490. if(urStyle == 'visible')
  1491. {
  1492. // do age-based filtering if enabled
  1493. if(document.getElementById('_cbEnableMinAgeFilter').checked == true)
  1494. {
  1495. if(uroGetURAge(ureq,0) < document.getElementById('_inputFilterMinDays').value) urStyle = 'hidden';
  1496. }
  1497. if(document.getElementById('_cbEnableMaxAgeFilter').checked == true)
  1498. {
  1499. if(uroGetURAge(ureq,0) > document.getElementById('_inputFilterMaxDays').value) urStyle = 'hidden';
  1500. }
  1501. }
  1502. if(urStyle == 'visible')
  1503. {
  1504. // do comments/following filtering
  1505. if(wazeModel.updateRequestSessions.objects[ureqID] != null)
  1506. {
  1507. nComments = wazeModel.updateRequestSessions.objects[ureqID].comments.length;
  1508. var commentDaysOld = -1;
  1509. if(document.getElementById('_cbEnableMinCommentsFilter').checked == true)
  1510. {
  1511. if(nComments < document.getElementById('_inputFilterMinComments').value) urStyle = 'hidden';
  1512. }
  1513. if(document.getElementById('_cbEnableMaxCommentsFilter').checked == true)
  1514. {
  1515. if(nComments > document.getElementById('_inputFilterMaxComments').value) urStyle = 'hidden';
  1516. }
  1517. if(nComments > 0)
  1518. {
  1519. var reporterIsLastCommenter = false;
  1520. if(wazeModel.updateRequestSessions.objects[ureqID].comments[nComments-1].userID == -1) reporterIsLastCommenter = true;
  1521. if(document.getElementById('_cbHideIfReporterLastCommenter').checked == true)
  1522. {
  1523. if(reporterIsLastCommenter == true) urStyle = 'hidden';
  1524. }
  1525. else if(document.getElementById('_cbHideIfReporterNotLastCommenter').checked == true)
  1526. {
  1527. if(reporterIsLastCommenter == false) urStyle = 'hidden';
  1528. }
  1529. hasMyComments = uroURHasMyComments(ureqID);
  1530. if(hasMyComments == false)
  1531. {
  1532. if(document.getElementById('_cbHideAnyComments').checked == true) urStyle = 'hidden';
  1533. if(document.getElementById('_cbHideIfNotLastCommenter').checked == true) urStyle = 'hidden';
  1534. }
  1535. else
  1536. {
  1537. if(document.getElementById('_cbHideMyComments').checked == true) urStyle = 'hidden';
  1538. var userIsLastCommenter = false;
  1539. if(wazeModel.updateRequestSessions.objects[ureqID].comments[nComments-1].userID == uroUserID) userIsLastCommenter = true;
  1540. if(document.getElementById('_cbHideIfLastCommenter').checked == true)
  1541. {
  1542. if(userIsLastCommenter == true) urStyle = 'hidden';
  1543. }
  1544. else if(document.getElementById('_cbHideIfNotLastCommenter').checked == true)
  1545. {
  1546. if(userIsLastCommenter == false) urStyle = 'hidden';
  1547. }
  1548. }
  1549. commentDaysOld = uroGetCommentAge(wazeModel.updateRequestSessions.objects[ureqID].comments[nComments-1]);
  1550. if((document.getElementById('_cbEnableCommentAgeFilter').checked == true) && (commentDaysOld != -1))
  1551. {
  1552. if(document.getElementById('_inputFilterCommentDays').value < commentDaysOld) urStyle = 'hidden';
  1553. }
  1554. if((document.getElementById('_cbEnableCommentAgeFilter2').checked == true) && (commentDaysOld != -1))
  1555. {
  1556. if(document.getElementById('_inputFilterCommentDays2').value > commentDaysOld) urStyle = 'hidden';
  1557. }
  1558. }
  1559. if(wazeModel.updateRequestSessions.objects[ureqID].isFollowing == true)
  1560. {
  1561. if(document.getElementById('_cbHideMyFollowed').checked == true) urStyle = 'hidden';
  1562. }
  1563. else
  1564. {
  1565. if(document.getElementById('_cbHideMyUnfollowed').checked == true) urStyle = 'hidden';
  1566. }
  1567. }
  1568. }
  1569.  
  1570. if(urStyle == 'visible')
  1571. {
  1572. // for type-based filtering, we need to handle Petrol Station Checker URs first - these (currently)
  1573. // appear as URs of either general error or undefined type, and so can't be detected just by type alone.
  1574. if(desc.indexOf('cryosphere') != -1)
  1575. {
  1576. cryosphere_link = true;
  1577. }
  1578. // Waze automatic URs are next - these always (?) get inserted as General Error URs, so we can't filter
  1579. // them by type either.
  1580. else if(desc.indexOf('Waze Automatic:') != -1)
  1581. {
  1582. wazeauto_ur = true;
  1583. }
  1584. var customType = uroGetCustomType(ureqID);
  1585. if(customType == 0) ukroadworks_ur = true;
  1586. else if(customType == 1) construction_ur = true;
  1587. else if(customType == 2) closure_ur = true;
  1588. else if(customType == 3) event_ur = true;
  1589.  
  1590. if(cryosphere_link == true)
  1591. {
  1592. if(document.getElementById('_cbFilterCryosphere').checked == true) urStyle = 'hidden';
  1593. }
  1594. else if(wazeauto_ur == true)
  1595. {
  1596. if(document.getElementById('_cbFilterWazeAuto').checked == true) urStyle = 'hidden';
  1597. }
  1598. else if(ukroadworks_ur == true)
  1599. {
  1600. if(document.getElementById('_cbFilterRoadworks').checked == true) urStyle = 'hidden';
  1601. }
  1602. else if(construction_ur == true)
  1603. {
  1604. if(document.getElementById('_cbFilterConstruction').checked == true) urStyle = 'hidden';
  1605. }
  1606. else if(closure_ur == true)
  1607. {
  1608. if(document.getElementById('_cbFilterClosure').checked == true) urStyle = 'hidden';
  1609. }
  1610. else if(event_ur == true)
  1611. {
  1612. if(document.getElementById('_cbFilterEvent').checked == true) urStyle = 'hidden';
  1613. }
  1614.  
  1615. else if(ureq.attributes.type == 6)
  1616. {
  1617. if(document.getElementById('_cbFilterIncorrectTurn').checked == true) urStyle = 'hidden';
  1618. }
  1619. else if(ureq.attributes.type == 7)
  1620. {
  1621. if (document.getElementById('_cbFilterIncorrectAddress').checked == true) urStyle = 'hidden';
  1622. }
  1623. else if(ureq.attributes.type == 8)
  1624. {
  1625. if(document.getElementById('_cbFilterIncorrectRoute').checked == true) urStyle = 'hidden';
  1626. }
  1627. else if(ureq.attributes.type == 9)
  1628. {
  1629. if(document.getElementById('_cbFilterMissingRoundabout').checked == true) urStyle = 'hidden';
  1630. }
  1631. else if(ureq.attributes.type == 10)
  1632. {
  1633. if(document.getElementById('_cbFilterGeneralError').checked == true) urStyle = 'hidden';
  1634. }
  1635. else if(ureq.attributes.type == 11)
  1636. {
  1637. if(document.getElementById('_cbFilterTurnNotAllowed').checked == true) urStyle = 'hidden';
  1638. }
  1639. else if(ureq.attributes.type == 12)
  1640. {
  1641. if(document.getElementById('_cbFilterIncorrectJunction').checked == true) urStyle = 'hidden';
  1642. }
  1643. else if(ureq.attributes.type == 13)
  1644. {
  1645. if(document.getElementById('_cbFilterMissingBridgeOverpass').checked == true) urStyle = 'hidden';
  1646. }
  1647. else if(ureq.attributes.type == 14)
  1648. {
  1649. if(document.getElementById('_cbFilterWrongDrivingDirection').checked == true) urStyle = 'hidden';
  1650. }
  1651. else if(ureq.attributes.type == 15)
  1652. {
  1653. if(document.getElementById('_cbFilterMissingExit').checked == true) urStyle = 'hidden';
  1654. }
  1655. else if(ureq.attributes.type == 16)
  1656. {
  1657. if(document.getElementById('_cbFilterMissingRoad').checked == true) urStyle = 'hidden';
  1658. }
  1659. else if(ureq.attributes.type == 18)
  1660. {
  1661. if(document.getElementById('_cbFilterMissingLandmark').checked == true) urStyle = 'hidden';
  1662. }
  1663. else if(ureq.attributes.type == 19)
  1664. {
  1665. if(document.getElementById('_cbFilterBlockedRoad').checked == true) urStyle = 'hidden';
  1666. }
  1667. else if(document.getElementById('_cbFilterUndefined').checked == true) urStyle = 'hidden';
  1668. if(document.getElementById('_cbInvertURFilter').checked == true)
  1669. {
  1670. if(urStyle == 'hidden') urStyle = 'visible';
  1671. else urStyle = 'hidden';
  1672. }
  1673. }
  1674. wazeMap.layers[uroURLayerIdx].markers[urobj].icon.imageDiv.style.visibility = urStyle;
  1675. if(urStyle != 'hidden')
  1676. {
  1677. if(ukroadworks_ur == true) uroAddCustomMarkers(ureqID,0);
  1678. if(construction_ur == true) uroAddCustomMarkers(ureqID,1);
  1679. if(closure_ur == true) uroAddCustomMarkers(ureqID,2);
  1680. if(event_ur == true) uroAddCustomMarkers(ureqID,3);
  1681. if(nComments > 0)
  1682. {
  1683. uroAddCommentMarkers(ureqID, hasMyComments, nComments);
  1684. }
  1685. }
  1686. }
  1687. for (var urobj in wazeModel.problems.objects)
  1688. {
  1689. var problem = wazeModel.problems.objects[urobj];
  1690. var problemStyle = 'visible';
  1691.  
  1692. // check problem against current session ignore list...
  1693. if(uroIsOnIgnoreList(problem.fid)) problemStyle = 'hidden';
  1694.  
  1695. // check against closed/not identified filtering if enabled...
  1696. var problem_marker_img = '';
  1697. if(problem.geometry.id != null)
  1698. {
  1699. if(document.getElementById(problem.geometry.id) != null)
  1700. {
  1701. problem_marker_img = document.getElementById(problem.geometry.id).href.baseVal;
  1702. if(document.getElementById('_cbMPFilterSolved').checked == true)
  1703. {
  1704. if(problem_marker_img.indexOf('_solved') != -1) problemStyle = 'hidden';
  1705. }
  1706. if(document.getElementById('_cbMPFilterUnidentified').checked == true)
  1707. {
  1708. if(problem_marker_img.indexOf('_rejected') != -1) problemStyle = 'hidden';
  1709. }
  1710. }
  1711. }
  1712. if((problem.attributes.resolvedOn != null) && (document.getElementById('_cbMPFilterClosed').checked == true))
  1713. {
  1714. problemStyle = 'hidden';
  1715. }
  1716. if(problemStyle == 'visible')
  1717. {
  1718. if(problem.attributes.problemType == 101)
  1719. {
  1720. if(document.getElementById('_cbMPFilterDrivingDirectionMismatch').checked == true) problemStyle = 'hidden';
  1721. }
  1722. else if(problem.attributes.problemType == 102)
  1723. {
  1724. if(document.getElementById('_cbMPFilterMissingJunction').checked == true) problemStyle = 'hidden';
  1725. }
  1726. else if(problem.attributes.problemType == 103)
  1727. {
  1728. if(document.getElementById('_cbMPFilterMissingRoad').checked == true) problemStyle = 'hidden';
  1729. }
  1730. else if(problem.attributes.problemType == 104)
  1731. {
  1732. if(document.getElementById('_cbMPFilterCrossroadsJunctionMissing').checked == true) problemStyle = 'hidden';
  1733. }
  1734. else if(problem.attributes.problemType == 105)
  1735. {
  1736. if(document.getElementById('_cbMPFilterRoadTypeMismatch').checked == true) problemStyle = 'hidden';
  1737. }
  1738. else if(problem.attributes.problemType == 106)
  1739. {
  1740. if(document.getElementById('_cbMPFilterRestrictedTurn').checked == true) problemStyle = 'hidden';
  1741. }
  1742. else if(document.getElementById('_cbMPFilterUnknownProblem').checked == true) problemStyle = 'hidden';
  1743. if(document.getElementById('_cbInvertMPFilter').checked == true)
  1744. {
  1745. if(problemStyle == 'hidden') problemStyle = 'visible';
  1746. else problemStyle = 'hidden';
  1747. }
  1748. if(problem.attributes.weight <= 3)
  1749. {
  1750. if(document.getElementById('_cbMPFilterLowSeverity').checked == true) problemStyle = 'hidden';
  1751. }
  1752. else if(problem.attributes.weight <= 7)
  1753. {
  1754. if(document.getElementById('_cbMPFilterMediumSeverity').checked == true) problemStyle = 'hidden';
  1755. }
  1756. else if(document.getElementById('_cbMPFilterHighSeverity').checked == true) problemStyle = 'hidden';
  1757. }
  1758. wazeMap.layers[uroProblemLayerIdx].markers[urobj].icon.imageDiv.style.visibility = problemStyle;
  1759. }
  1760.  
  1761. for (var urobj in wazeModel.turnProblems.objects)
  1762. {
  1763. var problem = wazeModel.turnProblems.objects[urobj];
  1764. var problemStyle = 'visible';
  1765.  
  1766. // check problem against current session ignore list...
  1767. if(uroIsOnIgnoreList(problem.fid)) problemStyle = 'hidden';
  1768.  
  1769. // check against closed/not identified filtering if enabled...
  1770. var problem_marker_img = '';
  1771. if(problem.geometry.id != null)
  1772. {
  1773. if(document.getElementById(problem.geometry.id) != null)
  1774. {
  1775. problem_marker_img = document.getElementById(problem.geometry.id).href.baseVal;
  1776. if(document.getElementById('_cbMPFilterSolved').checked == true)
  1777. {
  1778. if(problem_marker_img.indexOf('_solved') != -1) problemStyle = 'hidden';
  1779. }
  1780. if(document.getElementById('_cbMPFilterUnidentified').checked == true)
  1781. {
  1782. if(problem_marker_img.indexOf('_rejected') != -1) problemStyle = 'hidden';
  1783. }
  1784. }
  1785. }
  1786.  
  1787. if((problem.attributes.resolvedOn != null) && (document.getElementById('_cbMPFilterClosed').checked == true))
  1788. {
  1789. problemStyle = 'hidden';
  1790. }
  1791. if(document.getElementById('_cbMPFilterTurnProblem').checked == true) problemStyle = 'hidden';
  1792. if(document.getElementById('_cbInvertMPFilter').checked == true)
  1793. {
  1794. if(problemStyle == 'hidden') problemStyle = 'visible';
  1795. else problemStyle = 'hidden';
  1796. }
  1797. wazeMap.layers[uroProblemLayerIdx].markers[urobj].icon.imageDiv.style.visibility = problemStyle;
  1798. }
  1799. }
  1800.  
  1801.  
  1802. function uroFilterURMarkers2a()
  1803. {
  1804. uroAddLog('catch UR layer change');
  1805. uroFilterURMarkers();
  1806. }
  1807. function uroFilterURMarkers2b()
  1808. {
  1809. uroAddLog('catch UR layer add');
  1810. uroFilterURMarkers();
  1811. }
  1812. function uroFilterURMarkers2c()
  1813. {
  1814. uroAddLog('catch UR layer remove');
  1815. uroFilterURMarkers();
  1816. }
  1817. function uroFilterURMarkers3a()
  1818. {
  1819. uroAddLog('catch camera layer change');
  1820. uroFilterURMarkers();
  1821. }
  1822. function uroFilterURMarkers3b()
  1823. {
  1824. uroAddLog('catch camera layer add');
  1825. uroFilterURMarkers();
  1826. }
  1827. function uroFilterURMarkers3c()
  1828. {
  1829. uroAddLog('catch camera layer remove');
  1830. uroFilterURMarkers();
  1831. }
  1832. function uroFilterURMarkers4a()
  1833. {
  1834. uroAddLog('catch problems layer change');
  1835. uroFilterURMarkers();
  1836. }
  1837. function uroFilterURMarkers4b()
  1838. {
  1839. uroAddLog('catch problems layer add');
  1840. uroFilterURMarkers();
  1841. }
  1842. function uroFilterURMarkers4c()
  1843. {
  1844. uroAddLog('catch problems layer remove');
  1845. uroFilterURMarkers();
  1846. }
  1847. function uroFilterURMarkers5()
  1848. {
  1849. uroAddLog('catch mouse move');
  1850. wazeMap.events.unregister('mousemove',null,uroFilterURMarkers5);
  1851. uroFilterURMarkers();
  1852. }
  1853.  
  1854.  
  1855. function uroDeleteObject()
  1856. {
  1857. uroAddLog('delete camera ID '+uroShownFID);
  1858. if(wazeModel.cameras.objects[uroShownFID] == null)
  1859. {
  1860. uroAddLog('camera object not found...');
  1861. return false;
  1862. }
  1863.  
  1864. uroRemoveCamFromWatchList();
  1865.  
  1866. deleteAction = new Waze.Action.DeleteObject(wazeModel.cameras.objects[uroShownFID], null);
  1867. wazeModel.actionManager.add(deleteAction);
  1868. uroExitPopup();
  1869. return false;
  1870. }
  1871.  
  1872.  
  1873. function uroGetUserNameAndRank(userID)
  1874. {
  1875. var userName;
  1876. var userLevel;
  1877. if(wazeModel.users.objects[userID] != undefined)
  1878. {
  1879. userName = wazeModel.users.objects[userID].userName;
  1880. userLevel = wazeModel.users.objects[userID].rank + 1;
  1881. }
  1882. else
  1883. {
  1884. userName = userID;
  1885. userLevel = '?';
  1886. }
  1887. return userName + ' (' + userLevel + ')';
  1888. }
  1889.  
  1890.  
  1891. function uroGetCustomMarkerIdx(customType)
  1892. {
  1893. if(customType == 0) return 3;
  1894. if(customType == 1) return 3;
  1895. if(customType == 2) return 4;
  1896. if(customType == 3) return 5;
  1897. return -1;
  1898. }
  1899.  
  1900. function uroGetCustomType(idSrc)
  1901. {
  1902. var ureq = wazeModel.mapUpdateRequests.objects[idSrc];
  1903. var desc = '';
  1904. if(ureq.attributes.description != null)
  1905. {
  1906. desc = ureq.attributes.description;
  1907. if(desc.indexOf('[ROADWORKS]') != -1) return 0;
  1908. if(desc.indexOf('[CONSTRUCTION]') != -1) return 1;
  1909. if(desc.indexOf('[CLOSURE]') != -1) return 2;
  1910. if(desc.indexOf('[EVENT]') != -1) return 3;
  1911. }
  1912. return -1;
  1913. }
  1914.  
  1915.  
  1916. function uroFormatRestriction(restObj)
  1917. {
  1918. var retval = '<tr>';
  1919. retval += '<td style="text-align:center;">';
  1920. if((restObj.days & 1) == 1) retval += 'S';
  1921. else retval += '-';
  1922. retval += '</td><td style="text-align:center;">';
  1923. if((restObj.days & 2) == 2) retval += 'M';
  1924. else retval += '-';
  1925. retval += '</td><td style="text-align:center;">';
  1926. if((restObj.days & 4) == 4) retval += 'T';
  1927. else retval += '-';
  1928. retval += '</td><td style="text-align:center;">';
  1929. if((restObj.days & 8) == 8) retval += 'W';
  1930. else retval += '-';
  1931. retval += '</td><td style="text-align:center;">';
  1932. if((restObj.days & 16) == 16) retval += 'T';
  1933. else retval += '-';
  1934. retval += '</td><td style="text-align:center;">';
  1935. if((restObj.days & 32) == 32) retval += 'F';
  1936. else retval += '-';
  1937. retval += '</td><td style="text-align:center;">';
  1938. if((restObj.days & 64) == 64) retval += 'S';
  1939. else retval += '-';
  1940. retval += '</td><td>';
  1941. if(restObj.fromDate == null) retval += 'All dates';
  1942. else retval += restObj.fromDate+' to '+restObj.toDate;
  1943. retval += '</td><td>';
  1944.  
  1945. if(restObj.allDay == true) retval += 'All day';
  1946. else retval += restObj.fromTime+' to '+restObj.toTime;
  1947. retval += '</td><td>';
  1948. if(restObj.allVehicleTypes == restObj.vehicleTypes) retval += 'All vehicles';
  1949. else retval += 'Some vehicles';
  1950. retval += '</td><td>';
  1951. retval += restObj.description;
  1952. retval += '</td></tr>';
  1953. return retval;
  1954. }
  1955.  
  1956. function uroNewLookHighlightedItemsCheck(e)
  1957. {
  1958. if(uroMaskTest() == true) return;
  1959.  
  1960. if(OpenLayers == null)
  1961. {
  1962. if(uroNullOpenLayers == false)
  1963. {
  1964. uroAddLog('caught null OpenLayers');
  1965. uroNullOpenLayers = true;
  1966. }
  1967. return;
  1968. }
  1969. uroNullOpenLayers = false;
  1970.  
  1971. var rc = document.getElementById(uroRootContainer);
  1972. if(rc == null)
  1973. {
  1974. if(uroNullRootContainer == false)
  1975. {
  1976. uroAddLog('caught null rootContainer');
  1977. uroNullRootContainer = true
  1978. }
  1979. return;
  1980. }
  1981. uroNullRootContainer = false;
  1982. if(wazeMap.layers[uroURLayerIdx] == null)
  1983. {
  1984. if(uroNullURLayer == false)
  1985. {
  1986. uroAddLog('caught null UR layer');
  1987. uroNullURLayer = true;
  1988. }
  1989. return;
  1990. }
  1991. uroNullURLayer = false;
  1992.  
  1993. if(wazeMap.layers[uroProblemLayerIdx] == null)
  1994. {
  1995. if(uroNullProblemLayer == false)
  1996. {
  1997. uroAddLog('caught null problem layer');
  1998. uroNullProblemLayer = true;
  1999. }
  2000. return;
  2001. }
  2002. uroNullProblemLayer = false;
  2003.  
  2004. var mouseX = e.pageX - document.getElementById('map').getBoundingClientRect().left;
  2005. var mouseY = e.pageY - document.getElementById('map').getBoundingClientRect().top;
  2006. var currentItems = rc.getElementsByTagName('g');
  2007.  
  2008. var result = '';
  2009. var rw;
  2010. var rh;
  2011. var doPopUp = false;
  2012. var popup_loc = new OpenLayers.LonLat(0,0);
  2013. var objHasIgnoreLink = false;
  2014. var objHasDeleteLink = false;
  2015.  
  2016. var uroPopupX = mouseX + document.getElementById('sidebar').clientWidth + 10;
  2017. var uroPopupY = mouseY + document.getElementsByClassName('waze-header')[0].clientHeight + 10;
  2018. var objHasIgnoreLink = false;
  2019. var objHasDeleteLink = false;
  2020. var objHasAddWatchLink = false;
  2021. var objHasRemoveWatchLink = false;
  2022. var objHasUpdateWatchLink = false;
  2023.  
  2024. // popup for segment restrictions
  2025. if(document.getElementById('_cbInhibitSegPopup').checked == false)
  2026. {
  2027. for(var slIdx=0; slIdx < W.map.segmentLayer.features.length; slIdx++)
  2028. {
  2029. if(W.map.segmentLayer.features[slIdx].renderIntent == 'highlight')
  2030. {
  2031. if(W.map.segmentLayer.features[slIdx].fid == null) segObj = W.map.segmentLayer.features[slIdx].model;
  2032. else segObj = W.map.segmentLayer.features[slIdx];
  2033. result += '<table cellpadding=4 border=1>';
  2034. if(segObj.attributes.fwdRestrictions.length > 0)
  2035. {
  2036. doPopUp = true;
  2037. result += '<tr><td colspan=11><b>A-B restrictions:</b></td></tr>';
  2038. for(var idx = 0; idx < segObj.attributes.fwdRestrictions.length; idx++)
  2039. {
  2040. restObj = segObj.attributes.fwdRestrictions[idx];
  2041. result += uroFormatRestriction(restObj);
  2042. }
  2043. }
  2044. if (segObj.attributes.revRestrictions.length > 0)
  2045. {
  2046. doPopUp = true;
  2047. result += '<tr><td colspan=11><b>B-A restrictions:</b></td></tr>';
  2048. for(var idx = 0; idx < segObj.attributes.revRestrictions.length; idx++)
  2049. {
  2050. restObj = segObj.attributes.revRestrictions[idx];
  2051. result += uroFormatRestriction(restObj);
  2052. }
  2053. }
  2054. result += '</table>';
  2055. if(doPopUp == true)
  2056. {
  2057. if(segObj.attributes.id == null) uroFID = segObj.id;
  2058. else uroFID = segObj.attributes.id;
  2059. }
  2060. break;
  2061. }
  2062. }
  2063. }
  2064.  
  2065. // popup for landmarks
  2066. if((doPopUp == false) && (document.getElementById('_cbInhibitLandmarkPopup').checked == false))
  2067. {
  2068. for(var llFeatureIdx=0; llFeatureIdx < W.map.landmarkLayer.features.length; llFeatureIdx++)
  2069. {
  2070. if(W.map.landmarkLayer.features[llFeatureIdx].renderIntent == 'highlight')
  2071. {
  2072. if(W.map.landmarkLayer.features[llFeatureIdx].fid == null) venueObj = W.map.landmarkLayer.features[llFeatureIdx].model;
  2073. else venueObj = W.map.landmarkLayer.features[llFeatureIdx];
  2074. result += '<b>';
  2075. if(venueObj.attributes.name == '') result += 'Unnamed landmark';
  2076. else result += venueObj.attributes.name;
  2077. result += '</b><br>';
  2078. for(var idx = 0; idx < venueObj.attributes.categories.length; idx++)
  2079. {
  2080. result += I18n.translations[I18n.locale].venues.categories[venueObj.attributes.categories[idx]] + '<br>';
  2081. }
  2082. doPopUp = true;
  2083. if(venueObj.attributes.id == null) uroFID = venueObj.id;
  2084. else uroFID = venueObj.attributes.id;
  2085. break;
  2086. }
  2087. }
  2088. }
  2089.  
  2090. // look for URs and problems
  2091. if(doPopUp == false)
  2092. {
  2093. var idSrc = null;
  2094. var divIdx = -1;
  2095. var isUR = false;
  2096. var isProblem = false;
  2097. var isTurnProb = false;
  2098.  
  2099. if(document.getElementById('_cbInhibitURPopup').checked == false)
  2100. {
  2101. for(var marker in wazeMap.layers[uroURLayerIdx].markers)
  2102. {
  2103. markerObj = wazeMap.layers[uroURLayerIdx].markers[marker];
  2104. markerImg = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-image");
  2105. markerPos = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-position");
  2106. markerPos = markerPos.split(' ');
  2107. markerPos = parseInt(markerPos[1].substr(0,markerPos[1].length-2));
  2108.  
  2109. var hovered = false;
  2110. // fix for new WME - what possessed the Waze programmers to place the highlighted icon imagery at
  2111. // seemingly random offsets within the iconstrip, rather than having them all grouped neatly together
  2112. // as in previous versions of WME, is yet another design decision that seems to have been made purely
  2113. // for the sake of changing stuff around, rather than for any obviously good reason...
  2114. if(markerImg.indexOf('problems-se224ab677e.png') != -1)
  2115. {
  2116. if((markerPos == -40) || (markerPos == -160) || (markerPos == -200) || (markerPos == -240)) hovered = true;
  2117. }
  2118. else
  2119. {
  2120. if(markerPos > -200) hovered = true;
  2121. }
  2122. if(hovered == true)
  2123. {
  2124. var idSrc = markerObj.id;
  2125. isUR = true;
  2126. uroAddLog('hover over UR ID '+idSrc);
  2127. if(idSrc != uroCustomMarkerFID)
  2128. {
  2129. if(uroCustomMarkerFID != null)
  2130. {
  2131. var customIdx = uroGetCustomMarkerIdx(uroGetCustomType(uroCustomMarkerFID));
  2132. uroChangeCustomMarkers(uroCustomMarkerFID,false,customIdx);
  2133. uroCustomMarkerFID = null;
  2134. }
  2135. var customIdx = uroGetCustomMarkerIdx(uroGetCustomType(idSrc));
  2136. if(customIdx != -1)
  2137. {
  2138. uroCustomMarkerFID = idSrc;
  2139. uroChangeCustomMarkers(idSrc,hovered,customIdx);
  2140. }
  2141. }
  2142. break;
  2143. }
  2144. }
  2145. if((idSrc == null) && (uroCustomMarkerFID != null))
  2146. {
  2147. var customIdx = uroGetCustomMarkerIdx(uroGetCustomType(uroCustomMarkerFID));
  2148. uroChangeCustomMarkers(uroCustomMarkerFID,false, customIdx);
  2149. uroCustomMarkerFID = null;
  2150. }
  2151. }
  2152. if((isUR == false) && (document.getElementById('_cbInhibitMPPopup').checked == false))
  2153. {
  2154. var hovered = false;
  2155. for(var marker in wazeMap.layers[uroProblemLayerIdx].markers)
  2156. {
  2157. markerObj = wazeMap.layers[uroProblemLayerIdx].markers[marker];
  2158. markerImg = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-image");
  2159. markerPos = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-position");
  2160. markerPos = markerPos.split(' ');
  2161. markerPos = parseInt(markerPos[1].substr(0,markerPos[1].length-2));
  2162. if(markerImg.indexOf('problems-se224ab677e.png') != -1)
  2163. {
  2164. if((markerPos == -320) || (markerPos == -560) || (markerPos == -520) || (markerPos == -440)) hovered = true;
  2165. }
  2166. else
  2167. {
  2168. if(markerPos > -200) hovered = true;
  2169. }
  2170. if(hovered == true)
  2171. {
  2172. var idSrc = null;
  2173. if(markerObj.model.fid == null) idSrc = markerObj.id;
  2174. else idSrc = markerObj.model.fid;
  2175. isProblem = true;
  2176. uroAddLog('hover over problem ID '+idSrc);
  2177.  
  2178. break;
  2179. }
  2180. }
  2181. }
  2182. if (idSrc != null)
  2183. {
  2184. if(isUR) var ureq = wazeModel.mapUpdateRequests.objects[idSrc];
  2185. else if(isProblem)
  2186. {
  2187. var ureq = wazeModel.problems.objects[idSrc];
  2188. if(ureq == undefined)
  2189. {
  2190. var ureq = wazeModel.turnProblems.objects[idSrc];
  2191. if(ureq != undefined) isTurnProb = true;
  2192. }
  2193. }
  2194. var ureqID = null;
  2195. if(ureq.fid == null) ureqID = ureq.attributes.id;
  2196. else ureqID = ureq.fid;
  2197. uroFID = ureqID;
  2198. doPopUp = true;
  2199. }
  2200. else
  2201. {
  2202. uroFID = -1;
  2203. }
  2204.  
  2205. if((uroFID != uroShownFID) && (uroFID != -1))
  2206. {
  2207. if(isUR)
  2208. {
  2209. uroAddLog('building popup for UR '+idSrc);
  2210. result = '<b>Update Request ('+idSrc+'): ' + I18n.translations[I18n.locale].update_requests.types[ureq.attributes.type] + '</b><br>';
  2211. if(ureq.attributes.description != null)
  2212. {
  2213. var desc = ureq.attributes.description;
  2214. if(desc != "null")
  2215. {
  2216. var linkStartPos = desc.indexOf('http://');
  2217. if(linkStartPos == -1) linkStartPos = desc.indexOf('https://');
  2218. if(linkStartPos != -1)
  2219. {
  2220. var descPreLink = desc.slice(0,linkStartPos);
  2221. var descURL = desc.slice(linkStartPos);
  2222. var linkEndPos = descURL.indexOf(' ');
  2223. var descPostLink = '';
  2224. if(linkEndPos != -1)
  2225. {
  2226. descPostLink = descURL.slice(linkEndPos);
  2227. descURL = descURL.slice(0,linkEndPos);
  2228. }
  2229. var linkTarget = '';
  2230. if(descURL.indexOf('cryosphere') != -1) linkTarget = '_cryosphere';
  2231. else if(descURL.indexOf('waze.com') != -1) linkTarget = '_wazeUR';
  2232. desc = descPreLink + '<a target="'+linkTarget+'" href="'+descURL+'">here</a>' + descPostLink;
  2233. }
  2234. result += desc + '<br>';
  2235. }
  2236. }
  2237.  
  2238. var uroDaysOld = uroGetURAge(ureq,0);
  2239. if(uroDaysOld != -1)
  2240. {
  2241. result += '<i>Submitted ' + uroParseDaysAgo(uroDaysOld) + ' ';
  2242. if(ureq.attributes.guestUserName != null)
  2243. {
  2244. result += 'via Livemap';
  2245. if(ureq.attributes.guestUserName != '')
  2246. {
  2247. result += ' by '+ureq.attributes.guestUserName;
  2248. }
  2249. }
  2250. result += '</i>';
  2251. }
  2252. if(ureq.attributes.resolvedOn != null)
  2253. {
  2254. var uroDaysResolved = uroGetURAge(ureq,1);
  2255. if(uroDaysResolved != -1)
  2256. {
  2257. result += '<br><i>Closed ' + uroParseDaysAgo(uroDaysResolved) + ' ';
  2258. if(ureq.attributes.resolvedBy != null)
  2259. {
  2260. result += ' by '+uroGetUserNameAndRank(ureq.attributes.resolvedBy);
  2261. }
  2262. result += '</i>';
  2263. }
  2264. }
  2265. if(wazeModel.updateRequestSessions.objects[ureqID] != null)
  2266. {
  2267. var hasMyComments = uroURHasMyComments(ureqID);
  2268. var nComments = wazeModel.updateRequestSessions.objects[ureqID].comments.length;
  2269. result += '<br>' + nComments + ' comment';
  2270. if(nComments != 1) result += 's';
  2271. if((hasMyComments == false) && (nComments > 0)) result += ' (none by me)';
  2272. if(nComments > 0)
  2273. {
  2274. var commentDaysOld = uroGetCommentAge(wazeModel.updateRequestSessions.objects[ureqID].comments[nComments-1]);
  2275. if(commentDaysOld != -1)
  2276. {
  2277. result += ', last update '+uroParseDaysAgo(commentDaysOld);
  2278. }
  2279. }
  2280. }
  2281. }
  2282. else if(isProblem)
  2283. {
  2284. uroAddLog('building popup for problem '+idSrc);
  2285. if(isTurnProb) result = '<b>Turn Problem ('+idSrc+'): ' + I18n.translations[I18n.locale].problems.types["turn"].title;
  2286. else
  2287. {
  2288. result = '<b>Map Problem ('+idSrc+'): ';
  2289. if(I18n.translations[I18n.locale].problems.types[ureq.attributes.problemType] == undefined) result += 'Unknown problem type ('+ureq.attributes.problemType+')';
  2290. else result += I18n.translations[I18n.locale].problems.types[ureq.attributes.problemType].title;
  2291. }
  2292. result += '</b><br>';
  2293. if(ureq.attributes.resolvedOn != null)
  2294. {
  2295. var uroDaysResolved = uroGetURAge(ureq,1);
  2296. if(uroDaysResolved != -1)
  2297. {
  2298. result += '<br><i>Closed ' + uroParseDaysAgo(uroDaysResolved) + ' ';
  2299. if(ureq.attributes.resolvedBy != null)
  2300. {
  2301. result += ' by '+uroGetUserNameAndRank(ureq.attributes.resolvedBy);
  2302. }
  2303. result += '</i>';
  2304. }
  2305. }
  2306. }
  2307.  
  2308. // add "open new WME tab" link
  2309. var urPos=new OpenLayers.LonLat(ureq.geometry.x,ureq.geometry.y);
  2310. urPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
  2311. var urLink = document.location.href;
  2312. if(urLink.indexOf('&layers') != -1)
  2313. {
  2314. var urLayers = urLink.substr(urLink.indexOf('&layers'));
  2315. if(urLayers.indexOf('&show') != -1) urLayers = urLayers.substr(0,urLayers.indexOf('&show'));
  2316. }
  2317. else var urLayers = '';
  2318. urLink = urLink.substr(0,urLink.indexOf('?zoom'));
  2319. if(isUR) urLink += '?zoom=5&lat='+urPos.lat+'&lon='+urPos.lon+urLayers+'&showur='+idSrc+'&endshow';
  2320. else if(isTurnProb) urLink += '?zoom=5&lat='+urPos.lat+'&lon='+urPos.lon+urLayers+'&showturn='+idSrc+'&endshow';
  2321. else if(isProblem) urLink += '?zoom=5&lat='+urPos.lat+'&lon='+urPos.lon+urLayers+'&showproblem='+idSrc+'&endshow';
  2322. result += '<hr><ul><li><a href="'+urLink+'" target="_urTab">Open in new WME tab</a>';
  2323. // add "open new livemap tab" link
  2324. var lmLink = null;
  2325. if(document.getElementsByClassName("waze-header-menu").length == 0)
  2326. {
  2327. uroAddLog('Livemap link in livemap element');
  2328. lmLink = document.getElementById('livemap').href;
  2329. }
  2330. else
  2331. {
  2332. uroAddLog('Livemap link in header menu, locating...');
  2333. var menuItems = document.getElementsByClassName("waze-header-menu")[0];
  2334. for(var miloop = 0; miloop<menuItems.childElementCount; miloop++)
  2335. {
  2336. if(menuItems.children[miloop].innerHTML.indexOf('livemap') != -1)
  2337. {
  2338. uroAddLog('found link in menu entry '+miloop);
  2339. lmLink = menuItems.children[miloop].getElementsByTagName('a')[0].href;
  2340. uroAddLog(lmLink);
  2341. }
  2342. }
  2343. }
  2344. if(lmLink != null)
  2345. {
  2346. var zpos = lmLink.indexOf('?');
  2347. if(zpos > -1) lmLink = lmLink.substr(0,zpos);
  2348. lmLink += '?zoom=17&lat='+urPos.lat+'&lon='+urPos.lon+'&layers=BTTTT';
  2349. result += '<li><a href="'+lmLink+'" target="_lmTab">Open in new livemap tab</a>';
  2350. }
  2351. // add "ignore for this session" link
  2352. result += '<li><a href="#" id="_addtoignore">Hide for this session</a></ul>';
  2353. objHasIgnoreLink = true;
  2354. }
  2355. }
  2356. // look for cameras
  2357. if((doPopUp == false) && (document.getElementById('_cbInhibitCamPopup').checked == false))
  2358. {
  2359. for(var clFeatureIdx = 0; clFeatureIdx < W.map.camerasLayer.features.length; clFeatureIdx++)
  2360. {
  2361. if(W.map.camerasLayer.features[clFeatureIdx].renderIntent == 'highlight')
  2362. {
  2363. if(W.map.camerasLayer.features[clFeatureIdx].fid == null) ureq = W.map.camerasLayer.features[clFeatureIdx].model;
  2364. else ureq = W.map.camerasLayer.features[clFeatureIdx];
  2365.  
  2366. var ureqID = null;
  2367. if(ureq.fid == null) ureqID = ureq.attributes.id;
  2368. else ureqID = ureq.fid;
  2369. // test isSelected() so that we only do overview data on cameras that are being hovered over
  2370. if(ureq.isSelected() == false)
  2371. {
  2372. doPopUp = true;
  2373. uroFID = ureqID;
  2374. uroAddLog('generating popup for camera '+uroFID);
  2375. result += '<b>Camera: ' + ureq.TYPES[ureq.attributes.type] + '</b><br>';
  2376. result += 'ID: '+uroFID+'<br>';
  2377. result += 'Created by ';
  2378. if(wazeModel.users.get(ureq.attributes.createdBy) != null)
  2379. {
  2380. userID = ureq.attributes.createdBy;
  2381. result += uroGetUserNameAndRank(userID);
  2382. }
  2383. else result += 'unknown';
  2384. result += ', ';
  2385. var camAge = uroGetCameraAge(ureq,1);
  2386. if(camAge != -1)
  2387. {
  2388. result += uroParseDaysAgo(camAge);
  2389. }
  2390. else result += 'unknown days ago';
  2391.  
  2392. result += '<br>Updated by ';
  2393. if(wazeModel.users.get(ureq.attributes.updatedBy) != null)
  2394. {
  2395. userID = ureq.attributes.updatedBy;
  2396. userName = wazeModel.users.objects[userID].userName;
  2397. userLevel = wazeModel.users.objects[userID].rank + 1;
  2398. result += userName + ' (' + userLevel + ')';
  2399. }
  2400. else result += 'unknown';
  2401. result += ', ';
  2402. var camAge = uroGetCameraAge(ureq,0);
  2403. if(camAge != -1)
  2404. {
  2405. result += uroParseDaysAgo(camAge);
  2406. }
  2407. else result += 'unknown days ago';
  2408. result += '<br>Speed data: ';
  2409. if(ureq.attributes.speed != null)
  2410. {
  2411. result += ureq.attributes.speed + 'km/h';
  2412. var speedInMPH = Math.round(ureq.attributes.speed / 1.609);
  2413. result += ' (' + speedInMPH + 'mph';
  2414. if((speedInMPH % 10) != 0) result += ' - not valid?';
  2415. result += ')</i>';
  2416. }
  2417. else result += 'unknown';
  2418.  
  2419. var uid = wazeModel.loginManager.getLoggedInUser().id;
  2420. result += '<hr><ul>';
  2421. if(uroIsCamOnWatchList(uroFID) != -1)
  2422. {
  2423. result += '<li><a href="#" id="_updatewatchlist">Update watchlist entry</a>';
  2424. result += '<li><a href="#" id="_removefromwatchlist">Remove from watchlist</a>';
  2425. objHasUpdateWatchLink = true;
  2426. objHasRemoveWatchLink = true;
  2427. }
  2428. else
  2429. {
  2430. result += '<li><a href="#" id="_addtowatchlist">Add to watchlist</a>';
  2431. objHasAddWatchLink = true;
  2432. }
  2433.  
  2434. if(ureq.attributes.permissions != 0)
  2435. {
  2436. result += '<li><a href="#" id="_deleteobject">Delete Camera</a>';
  2437. objHasDeleteLink = true;
  2438. }
  2439. result += '</ul>';
  2440. }
  2441. break;
  2442. }
  2443. }
  2444. }
  2445.  
  2446. if(doPopUp == true)
  2447. {
  2448. if(uroFID != uroShownFID)
  2449. {
  2450. uroAddLog('FID mismatch, show popup: '+uroFID+'/'+uroShownFID);
  2451. uroShownFID = uroFID;
  2452. uroPopupShown = false;
  2453. }
  2454.  
  2455. if(uroPopupShown == false)
  2456. {
  2457. uroAddLog('display popup at '+uroPopupX+','+uroPopupY);
  2458. uroPopupShown = true;
  2459. uroDiv.innerHTML = result;
  2460. if((uroFID != -1) && (objHasIgnoreLink == true))
  2461. {
  2462. document.getElementById('_addtoignore').addEventListener('click', uroAddToIgnoreList, true);
  2463. }
  2464. if(objHasDeleteLink == true)
  2465. {
  2466. document.getElementById('_deleteobject').addEventListener('click', uroDeleteObject, true);
  2467. }
  2468. if(objHasRemoveWatchLink == true)
  2469. {
  2470. document.getElementById('_removefromwatchlist').addEventListener('click', uroRemoveCamFromWatchList, true);
  2471. }
  2472. if(objHasAddWatchLink == true)
  2473. {
  2474. document.getElementById('_addtowatchlist').addEventListener('click', uroAddCamToWatchList, true);
  2475. }
  2476. if(objHasUpdateWatchLink == true)
  2477. {
  2478. document.getElementById('_updatewatchlist').addEventListener('click', uroUpdateCamWatchList, true);
  2479. }
  2480. rw = parseInt(uroDiv.clientWidth);
  2481. rh = parseInt(uroDiv.clientHeight);
  2482.  
  2483. if(rw > (window.innerWidth / 2)) rw = (window.innerWidth / 2);
  2484. if(rh > (window.innerHeight / 2)) rh = (window.innerHeight / 2);
  2485.  
  2486. if((uroPopupX + rw) > window.innerWidth)
  2487. {
  2488. uroPopupX = window.innerWidth - (rw + 50);
  2489. if(uroPopupX < 0) uroPopupX = 0;
  2490. }
  2491. if((uroPopupY + rh) > window.innerHeight)
  2492. {
  2493. uroPopupY = window.innerHeight - (rh + 50);
  2494. if(uroPopupY < 0) uroPopupY = 0;
  2495. }
  2496.  
  2497. uroDiv.style.top = uroPopupY+'px';
  2498. uroDiv.style.left = uroPopupX+'px';
  2499. uroDiv.clientWidth = rw+'px';
  2500. uroDiv.clientHeight = rh+'px';
  2501. uroDiv.style.visibility = 'visible';
  2502. }
  2503. uroPopupTimer = -1;
  2504. }
  2505. else
  2506. {
  2507. if(uroPopupTimer == -1)
  2508. {
  2509. uroPopupTimer = 2;
  2510. }
  2511. }
  2512.  
  2513. if(uroPopupTimer > 0)
  2514. {
  2515. if(uroMouseInPopup == false)
  2516. {
  2517. uroPopupTimer--;
  2518. }
  2519. }
  2520. if(uroPopupTimer == 0)
  2521. {
  2522. uroDiv.style.visibility = 'hidden';
  2523. uroPopupShown = false;
  2524. uroPopupTimer = -2;
  2525. uroShownFID = -1;
  2526. }
  2527. }
  2528.  
  2529. function uroRestyleWMETabs()
  2530. {
  2531. var navTabs = document.getElementById(uroUserTabId).children[1].children;
  2532. for(var loop = 0; loop<navTabs.length; loop++)
  2533. {
  2534. navTabs[loop].children[0].style.padding = "4px";
  2535. }
  2536. setTimeout(uroRestyleWMETabs,1000);
  2537. }
  2538.  
  2539. function uroExclusiveCB()
  2540. {
  2541. cbChecked = document.getElementById(this.id).checked;
  2542. if(cbChecked == true)
  2543. {
  2544. if(this.id == '_cbHideMyComments') document.getElementById('_cbHideAnyComments').checked = false;
  2545. if(this.id == '_cbHideAnyComments') document.getElementById('_cbHideMyComments').checked = false;
  2546. if(this.id == '_cbHideIfLastCommenter') document.getElementById('_cbHideIfNotLastCommenter').checked = false;
  2547. if(this.id == '_cbHideIfNotLastCommenter') document.getElementById('_cbHideIfLastCommenter').checked = false;
  2548. if(this.id == '_cbHideIfReporterLastCommenter') document.getElementById('_cbHideIfReporterNotLastCommenter').checked = false;
  2549. if(this.id == '_cbHideIfReporterNotLastCommenter') document.getElementById('_cbHideIfReporterLastCommenter').checked = false;
  2550. }
  2551. }
  2552.  
  2553.  
  2554. function uroGetAMs(e)
  2555. {
  2556. var amList = '';
  2557. if(wazeMap.layers[uroAMLayerIdx].getVisibility() == true)
  2558. {
  2559. var mouseX = e.pageX - document.getElementById('map').getBoundingClientRect().left;
  2560. var mouseY = e.pageY - document.getElementById('map').getBoundingClientRect().top - document.getElementById('toolbar').clientHeight;
  2561. var mousePixel = new OL.Pixel(mouseX, mouseY);
  2562. var mousePoint = W.map.getLonLatFromPixel(mousePixel).toPoint();
  2563.  
  2564. for(var amObj in W.model.managedAreas.objects)
  2565. {
  2566. if(W.model.managedAreas.objects[amObj].geometry.containsPoint(mousePoint))
  2567. {
  2568. if(amList != '') amList += ', ';
  2569. amList += uroGetUserNameAndRank(W.model.managedAreas.objects[amObj].userID);
  2570. }
  2571. }
  2572. if(amList == '')
  2573. {
  2574. amList = 'none';
  2575. }
  2576. amList = "<b>Area Managers:</b> "+amList;
  2577. }
  2578. document.getElementById("uroAMList").innerHTML = amList;
  2579. }
  2580.  
  2581.  
  2582. function uroTenthSecondTick()
  2583. {
  2584. if(uroSetupListeners)
  2585. {
  2586. if(loginManager.isLoggedIn())
  2587. {
  2588. uroSetupListeners = false;
  2589. // filter markers when the marker objects are modified (this happens whenever WME needs to load fresh marker data
  2590. // due to having panned/zoomed the map beyond the extents of the previously loaded data)
  2591. wazeModel.mapUpdateRequests.events.register("objectschanged", null, uroFilterURMarkers2a);
  2592. wazeModel.mapUpdateRequests.events.register("objectsadded", null, uroFilterURMarkers2b);
  2593. wazeModel.mapUpdateRequests.events.register("objectsremoved", null, uroFilterURMarkers2c);
  2594. wazeModel.cameras.events.register("objectschanged", null, uroFilterURMarkers3a);
  2595. wazeModel.cameras.events.register("objectsadded", null, uroFilterURMarkers3b);
  2596. wazeModel.cameras.events.register("objectsremoved", null, uroFilterURMarkers3c);
  2597. wazeModel.problems.events.register("objectschanged", null, uroFilterURMarkers4a);
  2598. wazeModel.problems.events.register("objectsadded", null, uroFilterURMarkers4b);
  2599. wazeModel.problems.events.register("objectsremoved", null, uroFilterURMarkers4c);
  2600.  
  2601. var userTabs = document.getElementById(uroUserTabId);
  2602. var navTabs = uroTimbonesGetElementsByClassName('nav-tabs', userTabs)[0];
  2603. var tabContent = uroTimbonesGetElementsByClassName('tab-content', userTabs)[0];
  2604. newtabUR = document.createElement('li');
  2605. newtabUR.innerHTML = '<a href="#sidepanel-uroverview" data-toggle="tab">URO+</a>';
  2606. navTabs.appendChild(newtabUR);
  2607. uroControls.id = "sidepanel-uroverview";
  2608. uroControls.className = "tab-pane";
  2609. tabContent.appendChild(uroControls);
  2610.  
  2611. document.getElementById('_btnUndoLastHide').addEventListener("click", uroRemoveLastAddedIgnore, true);
  2612. document.getElementById('_btnClearSessionHides').addEventListener("click", uroRemoveAllIgnores, true);
  2613. uroEnableIgnoreListControls();
  2614.  
  2615. document.getElementById('_btnClearCamWatchList').addEventListener("click", uroClearCamWatchList, true);
  2616. document.getElementById('_btnSettingsToText').addEventListener("click", uroSettingsToText, true);
  2617. document.getElementById('_btnTextToSettings').addEventListener("click", uroTextToSettings, true);
  2618. document.getElementById('_btnClearSettingsText').addEventListener("click", uroClearSettingsText, true);
  2619.  
  2620. document.getElementById("_linkSelectUserRequests").onclick = uroShowURTab;
  2621. document.getElementById("_linkSelectMapProblems").onclick = uroShowMPTab;
  2622. document.getElementById("_linkSelectCameras").onclick = uroShowCameraTab;
  2623. document.getElementById("_linkSelectMisc").onclick = uroShowMiscTab;
  2624. document.getElementById("_linkSelectCWL").onclick = uroShowCamWatchlistTab;
  2625. document.getElementById('_cbHideMyComments').onclick = uroExclusiveCB;
  2626. document.getElementById('_cbHideAnyComments').onclick = uroExclusiveCB;
  2627. document.getElementById('_cbHideIfLastCommenter').onclick = uroExclusiveCB;
  2628. document.getElementById('_cbHideIfNotLastCommenter').onclick = uroExclusiveCB;
  2629. document.getElementById('_cbHideIfReporterLastCommenter').onclick = uroExclusiveCB;
  2630. document.getElementById('_cbHideIfReporterNotLastCommenter').onclick = uroExclusiveCB;
  2631.  
  2632. uroAddLog('finalise onload');
  2633. uroLoadSettings();
  2634. uroNewLookCheckDetailsRequest();
  2635. if(document.getElementById('_cbEnableDTE').checked)
  2636. {
  2637. if(dteControlsIdx != -1) dteSetNewTabLength();
  2638. else
  2639. {
  2640. uroAddLog('ERROR - archive panel not found!');
  2641. document.getElementById(uroUserTabId).style.display = '';
  2642. }
  2643. }
  2644. if(document.getElementById('_cbEnableSRS').checked)
  2645. {
  2646. selectionManager.events.register("selectionchanged", null, srsCheckSidePanel);
  2647. uroAddLog('added SRS event handler');
  2648. }
  2649.  
  2650. // filter markers as and when the map is moved
  2651. wazeMap.events.register("move", null, uroFilterURMarkers);
  2652. wazeMap.events.register("mousemove", null, uroGetAMs);
  2653. wazeMap.events.register("mousemove", null, uroNewLookHighlightedItemsCheck);
  2654. uroSetStyles(uroCtrlURs);
  2655. uroSetStyles(uroCtrlMPs);
  2656. uroSetStyles(uroCtrlCameras);
  2657. uroSetStyles(uroCtrlMisc);
  2658. uroSetStyles(uroCamWatchlist);
  2659.  
  2660. uroShowURTab();
  2661. uroRestyleWMETabs();
  2662. uroUserID = loginManager.getLoggedInUser().id;
  2663. uroFilterURMarkers();
  2664. uroInitiateRefreshAMObjects();
  2665. }
  2666. }
  2667. else
  2668. {
  2669. uroURSCurrentCount = Object.keys(wazeModel.updateRequestSessions.objects).length;
  2670. if(uroURSCurrentCount != uroURSPrevCount)
  2671. {
  2672. uroFilterURMarkers();
  2673. uroURSPrevCount = uroURSCurrentCount;
  2674. }
  2675. }
  2676. }
  2677.  
  2678. function uroToggleURCtrls()
  2679. {
  2680. uroCtrlsHidden = !uroCtrlsHidden;
  2681. if (!uroCtrlsHidden)
  2682. {
  2683. document.getElementById('_hideUCCtrl').innerHTML = "hide";
  2684. if(uroCurrentTab == 1) uroShowURTab();
  2685. else if(uroCurrentTab == 2) uroShowMPTab();
  2686. else if(uroCurrentTab == 3) uroShowCameraTab();
  2687. else if(uroCurrentTab == 4) uroShowCamWatchlistTab();
  2688. else if(uroCurrentTab == 5) uroShowMiscTab();
  2689. }
  2690. else
  2691. {
  2692. document.getElementById('_hideUCCtrl').innerHTML = "show";
  2693. document.getElementById('uroCtrlURs').style.display = 'none';
  2694. document.getElementById('uroCtrlMPs').style.display = 'none';
  2695. document.getElementById('uroCtrlCameras').style.display = 'none';
  2696. document.getElementById('uroCtrlMisc').style.display = 'none';
  2697. document.getElementById('uroCamWatchlist').style.display = 'none';
  2698. }
  2699.  
  2700. return false;
  2701. }
  2702.  
  2703. function uroActiveTab(_id)
  2704. {
  2705. var e = document.getElementById(_id);
  2706. e.style.backgroundColor = "aliceblue";
  2707. e.style.borderTop = "1px solid";
  2708. e.style.borderLeft = "1px solid";
  2709. e.style.borderRight = "1px solid";
  2710. e.style.borderBottom = "0px solid";
  2711. }
  2712.  
  2713. function uroInactiveTab(_id)
  2714. {
  2715. var e = document.getElementById(_id);
  2716. e.style.backgroundColor = "white";
  2717. e.style.borderTop = "0px solid";
  2718. e.style.borderLeft = "0px solid";
  2719. e.style.borderRight = "0px solid";
  2720. e.style.borderBottom = "1px solid";
  2721. }
  2722.  
  2723.  
  2724. function uroInactiveAllTabs()
  2725. {
  2726. uroInactiveTab("_tabSelectCameras");
  2727. uroInactiveTab("_tabSelectMapProblems");
  2728. uroInactiveTab("_tabSelectMisc");
  2729. uroInactiveTab("_tabSelectUserRequests");
  2730. uroInactiveTab("_tabSelectCWL");
  2731. if(!uroCtrlsHidden)
  2732. {
  2733. document.getElementById('uroCtrlURs').style.display = 'none';
  2734. document.getElementById('uroCtrlMPs').style.display = 'none';
  2735. document.getElementById('uroCtrlCameras').style.display = 'none';
  2736. document.getElementById('uroCtrlMisc').style.display = 'none';
  2737. document.getElementById('uroCamWatchlist').style.display = 'none';
  2738. }
  2739. }
  2740.  
  2741. function uroShowURTab()
  2742. {
  2743. uroInactiveAllTabs();
  2744. uroActiveTab("_tabSelectUserRequests");
  2745. uroCurrentTab = 1;
  2746. if(!uroCtrlsHidden) document.getElementById('uroCtrlURs').style.display = 'block';
  2747. return false;
  2748. }
  2749.  
  2750.  
  2751. function uroShowMPTab()
  2752. {
  2753. uroInactiveAllTabs();
  2754. uroActiveTab("_tabSelectMapProblems");
  2755. uroCurrentTab = 2;
  2756. if(!uroCtrlsHidden) document.getElementById('uroCtrlMPs').style.display = 'block';
  2757. return false;
  2758. }
  2759.  
  2760.  
  2761. function uroShowCameraTab()
  2762. {
  2763. uroInactiveAllTabs();
  2764. uroActiveTab("_tabSelectCameras");
  2765. uroCurrentTab = 3;
  2766. if(!uroCtrlsHidden) document.getElementById('uroCtrlCameras').style.display = 'block';
  2767. return false;
  2768. }
  2769.  
  2770. function uroShowCamWatchlistTab()
  2771. {
  2772. uroInactiveAllTabs();
  2773. uroActiveTab("_tabSelectCWL");
  2774. uroCurrentTab = 4;
  2775. if(!uroCtrlsHidden) document.getElementById('uroCamWatchlist').style.display = 'block';
  2776. uroCWLUpdateHTML();
  2777. return false;
  2778. }
  2779. function uroShowMiscTab()
  2780. {
  2781. uroInactiveAllTabs();
  2782. uroActiveTab("_tabSelectMisc");
  2783. uroCurrentTab = 5;
  2784. if(!uroCtrlsHidden) document.getElementById('uroCtrlMisc').style.display = 'block';
  2785. return false;
  2786. }
  2787.  
  2788.  
  2789. function uroTimbonesGetElementsByClassName(classname, node) {
  2790. if(!node) node = document.getElementsByTagName("body")[0];
  2791. var a = [];
  2792. var re = new RegExp('\\b' + classname + '\\b');
  2793. var els = node.getElementsByTagName("*");
  2794. for (var i=0,j=els.length; i<j; i++)
  2795. if (re.test(els[i].className)) a.push(els[i]);
  2796. return a;
  2797. }
  2798.  
  2799. function uroNewLookCheckDetailsRequest()
  2800. {
  2801. var thisurl = document.location.href;
  2802. var doRetry = true;
  2803. showurpos = thisurl.indexOf('&showur=');
  2804. showproblempos = thisurl.indexOf('&showproblem=');
  2805. showturnpos = thisurl.indexOf('&showturn=');
  2806. endmarkerpos = thisurl.indexOf('&endshow');
  2807. if(endmarkerpos != -1)
  2808. {
  2809. if(showurpos != -1)
  2810. {
  2811. showurpos += 8;
  2812. uroAddLog('showur tab opened');
  2813. var urID = thisurl.substr(showurpos,endmarkerpos-showurpos);
  2814. uroAddLog(' UR ID = '+urID);
  2815. if(wazeMap.layers[uroURLayerIdx].markers == null)
  2816. {
  2817. uroAddLog('wazeMap.layers not loaded, retrying...');
  2818. }
  2819. else
  2820. {
  2821. for(var marker in wazeMap.layers[uroURLayerIdx].markers)
  2822. {
  2823. markerObj = wazeMap.layers[uroURLayerIdx].markers[marker];
  2824. if (urID == markerObj.model.fid)
  2825. {
  2826. doRetry = false;
  2827. markerObj.icon.imageDiv.click();
  2828. }
  2829. }
  2830. }
  2831. }
  2832.  
  2833. else if((showproblempos != -1) || (showturnpos != -1))
  2834. {
  2835. if(showproblempos != -1)
  2836. {
  2837. showproblempos += 13;
  2838. uroAddLog('showproblem tab opened');
  2839. var urID = thisurl.substr(showproblempos,endmarkerpos-showproblempos);
  2840. uroAddLog(' problem ID = '+urID);
  2841. }
  2842. else
  2843. {
  2844. showturnpos += 10;
  2845. uroAddLog('showturn tab opened');
  2846. var urID = thisurl.substr(showturnpos,endmarkerpos-showturnpos);
  2847. uroAddLog(' turn problem ID = '+urID);
  2848. }
  2849. if(wazeMap.layers[uroProblemLayerIdx].markers == null)
  2850. {
  2851. uroAddLog('wazeMap.layers not loaded, retrying...');
  2852. }
  2853. else
  2854. {
  2855. for(var marker in wazeMap.layers[uroProblemLayerIdx].markers)
  2856. {
  2857. markerObj = wazeMap.layers[uroProblemLayerIdx].markers[marker];
  2858. if (urID == markerObj.model.fid)
  2859. {
  2860. doRetry = false;
  2861. markerObj.icon.imageDiv.click();
  2862. }
  2863. }
  2864. }
  2865. }
  2866. }
  2867.  
  2868. if(doRetry) setTimeout(uroNewLookCheckDetailsRequest,500);
  2869. }
  2870.  
  2871.  
  2872. function uroSetStyles(obj)
  2873. {
  2874. obj.style.fontSize = '12px';
  2875. obj.style.lineHeight = '100%';
  2876. obj.style.overflow = 'auto';
  2877. obj.style.height = (window.innerHeight * 0.55) + 'px';
  2878. }
  2879.  
  2880.  
  2881. function uroWazeBits()
  2882. {
  2883. uroAddLog('adding WazeBits...');
  2884. if((uroWazeBitsPresent & 0x01) == 0)
  2885. {
  2886. if(typeof unsafeWindow.wazeMap != "undefined")
  2887. {
  2888. uroAddLog(' wazeMap OK');
  2889. wazeMap = unsafeWindow.wazeMap;
  2890. uroWazeBitsPresent |= 0x01;
  2891. }
  2892. else if(typeof unsafeWindow.W != "undefined")
  2893. {
  2894. if(typeof unsafeWindow.W.controller != "undefined")
  2895. {
  2896. if(typeof unsafeWindow.W.controller.map != "undefined")
  2897. {
  2898. uroAddLog(' wazeMap OK');
  2899. wazeMap = unsafeWindow.W.controller.map;
  2900. uroWazeBitsPresent |= 0x01;
  2901. }
  2902. }
  2903. }
  2904. }
  2905. if((uroWazeBitsPresent & 0x02) == 0)
  2906. {
  2907. if(typeof unsafeWindow.wazeModel != "undefined")
  2908. {
  2909. uroAddLog(' wazeModel OK');
  2910. wazeModel = unsafeWindow.wazeModel;
  2911. uroWazeBitsPresent |= 0x02;
  2912. }
  2913. else if(typeof unsafeWindow.W != "undefined")
  2914. {
  2915. if(typeof unsafeWindow.W.controller != "undefined")
  2916. {
  2917. if(typeof unsafeWindow.W.controller.model != "undefined")
  2918. {
  2919. uroAddLog(' wazeModel OK');
  2920. wazeModel = unsafeWindow.W.controller.model;
  2921. uroWazeBitsPresent |= 0x02;
  2922. }
  2923. }
  2924. }
  2925. }
  2926. if((uroWazeBitsPresent & 0x04) == 0)
  2927. {
  2928. if(typeof unsafeWindow.loginManager != "undefined")
  2929. {
  2930. uroAddLog(' loginManager OK');
  2931. loginManager = unsafeWindow.loginManager;
  2932. uroWazeBitsPresent |= 0x04;
  2933. }
  2934. else if(typeof unsafeWindow.W != "undefined")
  2935. {
  2936. if(typeof unsafeWindow.W.app != "undefined")
  2937. {
  2938. if(typeof unsafeWindow.W.app.loginManager != "undefined")
  2939. {
  2940. uroAddLog(' loginManager OK');
  2941. loginManager = unsafeWindow.W.app.loginManager;
  2942. uroWazeBitsPresent |= 0x04;
  2943. }
  2944. }
  2945. }
  2946. }
  2947. if((uroWazeBitsPresent & 0x08) == 0)
  2948. {
  2949. if(typeof unsafeWindow.selectionManager != "undefined")
  2950. {
  2951. uroAddLog(' selectionManager OK');
  2952. selectionManager = unsafeWindow.selectionManager;
  2953. uroWazeBitsPresent |= 0x08;
  2954. }
  2955. else if(typeof unsafeWindow.W != "undefined")
  2956. {
  2957. if(typeof unsafeWindow.W.geometryEditing != "undefined")
  2958. {
  2959. if(typeof unsafeWindow.W.geometryEditing.selectionManager != "undefined")
  2960. {
  2961. uroAddLog(' selectionManager OK');
  2962. selectionManager = unsafeWindow.W.geometryEditing.selectionManager;
  2963. uroWazeBitsPresent |= 0x08;
  2964. }
  2965. }
  2966. }
  2967. }
  2968. if((uroWazeBitsPresent & 0x10) == 0)
  2969. {
  2970. if(typeof unsafeWindow.OpenLayers != "undefined")
  2971. {
  2972. uroAddLog(' OpenLayers OK');
  2973. OpenLayers = unsafeWindow.OpenLayers;
  2974. uroWazeBitsPresent |= 0x10;
  2975. }
  2976. }
  2977. if((uroWazeBitsPresent & 0x20) == 0)
  2978. {
  2979. if(typeof unsafeWindow.Waze != "undefined")
  2980. {
  2981. uroAddLog(' Waze OK');
  2982. Waze = unsafeWindow.Waze;
  2983. uroWazeBitsPresent |= 0x20;
  2984. }
  2985. }
  2986. if((uroWazeBitsPresent & 0x40) == 0)
  2987. {
  2988. if(document.getElementById('user-tabs') != null)
  2989. {
  2990. uroUserTabId = 'user-tabs';
  2991. uroAddLog(' user-tabs OK');
  2992. uroWazeBitsPresent |= 0x40;
  2993. }
  2994. else if(document.getElementById('user-info') != null)
  2995. {
  2996. uroUserTabId = 'user-info';
  2997. uroAddLog(' user-info OK');
  2998. uroWazeBitsPresent |= 0x40;
  2999. }
  3000. }
  3001. if((uroWazeBitsPresent & 0x80) == 0)
  3002. {
  3003. if(document.getElementById('sidepanel-drives') != null)
  3004. {
  3005. uroAddLog(' sidepanel-drives OK');
  3006. uroWazeBitsPresent |= 0x80;
  3007. }
  3008. }
  3009.  
  3010. if(uroWazeBitsPresent != 0xFF) setTimeout(uroWazeBits,250);
  3011. else if(loginManager.isLoggedIn() == false)
  3012. {
  3013. uroAddLog('Waiting for user log-in...');
  3014. setTimeout(uroWazeBits,1000);
  3015. }
  3016. else
  3017. {
  3018. uroAddLog('All WazeBits present and correct...');
  3019. uroControls.appendChild(uroCtrlURs);
  3020. uroControls.appendChild(uroCtrlMPs);
  3021. uroControls.appendChild(uroCtrlCameras);
  3022. uroControls.appendChild(uroCamWatchlist);
  3023. uroControls.appendChild(uroCtrlMisc);
  3024. uroControls.appendChild(uroCtrlHides);
  3025. uroControls.appendChild(uroAMList);
  3026.  
  3027. uroCtrlURs.onclick = uroFilterURMarkers;
  3028. uroCtrlMPs.onclick = uroFilterURMarkers;
  3029. uroCtrlCameras.onclick = uroFilterURMarkers;
  3030. uroCtrlMisc.onclick = uroFilterURMarkers;
  3031.  
  3032. for(i=0;i<wazeMap.layers.length;i++)
  3033. {
  3034. if(wazeMap.layers[i].uniqueName == 'update_requests') uroURLayerIdx = i;
  3035. if(wazeMap.layers[i].uniqueName == 'problems') uroProblemLayerIdx = i;
  3036. if(wazeMap.layers[i].name == 'Spotlight') uroMaskLayer = i;
  3037. if(wazeMap.layers[i].uniqueName == 'speed_cameras')
  3038. {
  3039. uroCamLayer = i;
  3040. }
  3041. if(wazeMap.layers[i].name.indexOf('Waze.Control.SelectHighlightFeature') != -1) uroRootContainer = wazeMap.layers[i].div.id;
  3042. if(wazeMap.layers[i].uniqueName == 'area_managers') uroAMLayerIdx = i;
  3043. }
  3044.  
  3045. for(i=0;i<wazeMap.controls.length;i++)
  3046. {
  3047. if(wazeMap.controls[i].CLASS_NAME == 'Waze.View.ArchivePanel') dteControlsIdx = i;
  3048. else if(wazeMap.controls[i].CLASS_NAME == 'Waze.Control.Archive') dteControlsIdx = i;
  3049.  
  3050. if(wazeMap.controls[i].id != null)
  3051. {
  3052. if(wazeMap.controls[i].id.indexOf('UpdateRequests') != -1) uroURControlsIdx = i;
  3053. if(wazeMap.controls[i].id.indexOf('MapProblems') != -1) uroProblemControlsIdx = i;
  3054. }
  3055. }
  3056. uroAddLog('UR layer at idx '+uroURLayerIdx);
  3057. uroAddLog('Problem layer at idx '+uroProblemLayerIdx);
  3058. uroAddLog('uroMaskLayer at idx '+uroMaskLayer);
  3059. uroAddLog('Camera layer at idx '+uroCamLayer);
  3060. uroAddLog('AM layer at idx '+uroAMLayerIdx);
  3061. uroAddLog('uroRootContainer = '+uroRootContainer);
  3062.  
  3063. uroDiv.addEventListener("mouseover", uroEnterPopup, false);
  3064. uroDiv.addEventListener("mouseout", uroExitPopup, false);
  3065.  
  3066. if(sessionStorage.UROverview_FID_IgnoreList == null) sessionStorage.UROverview_FID_IgnoreList = '';
  3067. if(sessionStorage.UROverview_FID_WatchList == null) sessionStorage.UROverview_FID_WatchList = '';
  3068.  
  3069. setInterval(uroTenthSecondTick,100);
  3070. }
  3071. }
  3072.  
  3073. function uroEnterPopup()
  3074. {
  3075. uroMouseInPopup = true;
  3076. }
  3077.  
  3078. function uroExitPopup()
  3079. {
  3080. uroMouseInPopup = false;
  3081. }
  3082.  
  3083. function uroInitialise()
  3084. {
  3085. uroGlobals();
  3086. if(document.URL.indexOf('editor-beta') != -1) uroBetaEditor = true;
  3087.  
  3088. // create a new div to display the UR details floaty-box
  3089. uroDiv = document.createElement('div');
  3090. uroDiv.id = "uroDiv";
  3091. uroDiv.style.position = 'absolute';
  3092. uroDiv.style.visibility = 'hidden';
  3093. uroDiv.style.top = '0';
  3094. uroDiv.style.left = '0';
  3095. uroDiv.style.zIndex = 100;
  3096. uroDiv.style.backgroundColor = 'aliceblue';
  3097. uroDiv.style.borderWidth = '3px';
  3098. uroDiv.style.borderStyle = 'ridge';
  3099. uroDiv.style.borderRadius = '10px';
  3100. uroDiv.style.boxShadow = '5px 5px 10px Silver';
  3101. uroDiv.style.padding = '4px';
  3102. document.body.appendChild(uroDiv);
  3103.  
  3104.  
  3105. uroControls = document.createElement('section');
  3106. uroControls.style.fontSize = '12px';
  3107. uroControls.id = 'uroControls';
  3108. if(navigator.userAgent.indexOf('Chrome') == -1)
  3109. {
  3110. var updateURL = 'https://greasyfork.org/scripts/1952-uroverview-plus-uro';
  3111. }
  3112. else
  3113. {
  3114. var updateURL = 'https://chrome.google.com/webstore/detail/uroverview/amdamgkgchnbaopmphhjapmjcdghdphi';
  3115. }
  3116. tabbyHTML = '<b><a href="'+updateURL+'" target="_blank">UROverview Plus</a></b> '+uroVersion;
  3117. tabbyHTML += '<p><table border=0 width="100%"><tr>';
  3118. tabbyHTML += '<td valign="center" align="center" id="_tabSelectUserRequests"><a href="#" id="_linkSelectUserRequests" style="text-decoration:none;font-size:12px">URs</a></td>';
  3119. tabbyHTML += '<td valign="center" align="center" id="_tabSelectMapProblems"><a href="#" id="_linkSelectMapProblems" style="text-decoration:none;font-size:12px">MPs</a></td>';
  3120. tabbyHTML += '<td valign="center" align="center" id="_tabSelectCameras"><a href="#" id="_linkSelectCameras" style="text-decoration:none;font-size:12px">Cams</a></td>';
  3121. tabbyHTML += '<td valign="center" align="center" id="_tabSelectCWL"><a href="#" id="_linkSelectCWL" style="text-decoration:none;font-size:12px">CWL</a></td>';
  3122. tabbyHTML += '<td valign="center" align="center" id="_tabSelectMisc"><a href="#" id="_linkSelectMisc" style="text-decoration:none;font-size:12px">Misc</a></td>';
  3123. tabbyHTML += '</tr></table>';
  3124. uroControls.innerHTML = tabbyHTML;
  3125.  
  3126.  
  3127. uroCtrlURs = document.createElement('p');
  3128. uroCtrlMPs = document.createElement('p');
  3129. uroCtrlCameras = document.createElement('p');
  3130. uroCamWatchlist = document.createElement('p');
  3131. uroCtrlMisc = document.createElement('p');
  3132. uroAMList = document.createElement('div');
  3133. uroCtrlHides = document.createElement('div');
  3134.  
  3135. // UR controls tab
  3136. uroCtrlURs.id = "uroCtrlURs";
  3137. uroCtrlURs.innerHTML = '<br>';
  3138.  
  3139. uroCtrlURs.innerHTML += '<b>Hide URs by type:</b><br>';
  3140. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterWazeAuto">Waze Automatic</input><br>';
  3141. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectTurn">Incorrect turn</input><br>';
  3142. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectAddress">Incorrect address</input><br>';
  3143. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectRoute">Incorrect route</input><br>';
  3144. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingRoundabout">Missing roundabout</input><br>';
  3145. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterGeneralError">General error</input><br>';
  3146. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterTurnNotAllowed">Turn not allowed</input><br>';
  3147. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectJunction">Incorrect junction</input><br>';
  3148. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingBridgeOverpass">Missing bridge overpass</input><br>';
  3149. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterWrongDrivingDirection">Wrong driving direction</input><br>';
  3150. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingExit">Missing exit</input><br>';
  3151. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingRoad">Missing road</input><br>';
  3152. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterBlockedRoad">Blocked road</input><br>';
  3153. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingLandmark">Missing Landmark</input><br>';
  3154. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterUndefined">Undefined</input><br>';
  3155.  
  3156. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<i>Specially tagged types</i><br>';
  3157. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterCryosphere">Petrol Station Checker</input><br>';
  3158. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterRoadworks">[ROADWORKS]</input><br>';
  3159. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterConstruction">[CONSTRUCTION]</input><br>';
  3160. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterClosure">[CLOSURE]</input><br>';
  3161. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterEvent">[EVENT]</input><br><br>';
  3162. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbInvertURFilter">Invert operation of type filters?</input><br>';
  3163. uroCtrlURs.innerHTML += '<br><b>Hide closed/solved/unidentified URs:</b><br>';
  3164. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterClosedUR">Closed</input><br>';
  3165. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterSolved">Solved</input><br>';
  3166. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterUnidentified">Not identified</input><br><br>';
  3167.  
  3168.  
  3169. uroCtrlURs.innerHTML += '<br><b>Filter URs by age of submission:</b><br>';
  3170. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMinAgeFilter">Hide URs less than </input>';
  3171. uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMinDays"> days old<br>';
  3172. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMaxAgeFilter">Hide URs more than </input>';
  3173. uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMaxDays"> days old<br>';
  3174.  
  3175. uroCtrlURs.innerHTML += '<br><b>Filter URs by description text:</b><br>';
  3176. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURDescriptionMustBePresent">Hide</input> or ';
  3177. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURDescriptionMustBeAbsent">show</input> URs with no description<br>';
  3178. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableKeywordMustBePresent">Hide URs not including </input>';
  3179. uroCtrlURs.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textKeywordPresent"><br>';
  3180. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableKeywordMustBeAbsent">Hide URs including </input>';
  3181. uroCtrlURs.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textKeywordAbsent"><br>';
  3182. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbCaseInsensitive">Case-insensitive matches?</input><br>';
  3183. uroCtrlURs.innerHTML += '<br><b>Hide URs by comments/following:</b><br>';
  3184. uroCtrlURs.innerHTML += '<i>With comments from me?</i><br>';
  3185. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyComments">Yes </input>';
  3186. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideAnyComments">No</input><br>';
  3187. uroCtrlURs.innerHTML += '<i>If last comment made by me?</i><br>';
  3188. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfLastCommenter">Yes </input>';
  3189. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfNotLastCommenter">No </input><br>';
  3190. uroCtrlURs.innerHTML += '<i>If last comment made by UR reporter?</i><br>';
  3191. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfReporterLastCommenter">Yes </input>';
  3192. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfReporterNotLastCommenter">No</input><br>';
  3193.  
  3194. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMinCommentsFilter">With less than </input>';
  3195. uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMinComments"> comments<br>';
  3196. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMaxCommentsFilter">With more than </input>';
  3197. uroCtrlURs.innerHTML += '<input type="number" min="0" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMaxComments"> comments<br>';
  3198. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyFollowed">Ones I am or </input>';
  3199. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyUnfollowed">am not following</input><br>';
  3200.  
  3201. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableCommentAgeFilter2">Last comment less than </input>';
  3202. uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterCommentDays2"> days ago<br>';
  3203. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableCommentAgeFilter">Last comment more than </input>';
  3204. uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterCommentDays"> days ago<br>';
  3205.  
  3206.  
  3207. // Map problems controls tab
  3208. uroCtrlMPs.id = "uroCtrlMPs";
  3209. uroCtrlMPs.innerHTML = '<br>';
  3210.  
  3211. uroCtrlMPs.innerHTML += '<b>Filter MPs by type:</b><br>';
  3212. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterMissingJunction">Missing junction</input><br>';
  3213. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterMissingRoad">Missing road</input><br>';
  3214. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterCrossroadsJunctionMissing">Missing crossroads</input><br>';
  3215. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterDrivingDirectionMismatch">Driving direction mismatch</input><br>';
  3216. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterRoadTypeMismatch">Road type mismatch</input><br>';
  3217. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterRestrictedTurn">Restricted turn might be allowed</input><br>';
  3218. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterUnknownProblem">Unknown problem type</input><br><br>';
  3219. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterTurnProblem">Turn Problems</input><br><br>';
  3220. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbInvertMPFilter">Invert operation of type filters?</input><br>';
  3221.  
  3222. uroCtrlMPs.innerHTML += '<br><b>Hide closed/solved/unidentified Problems:</b><br>';
  3223. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterClosed">Closed</input><br>';
  3224. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterSolved">Solved</input><br>';
  3225. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterUnidentified">Not identified</input><br><br>';
  3226.  
  3227. uroCtrlMPs.innerHTML += '<br><b>Hide problems (not turn) by severity:</b><br>';
  3228. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterLowSeverity">Low</input>&nbsp;&nbsp;';
  3229. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterMediumSeverity">Medium</input>&nbsp;&nbsp;';
  3230. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterHighSeverity">High</input><br>';
  3231.  
  3232.  
  3233.  
  3234. // Camera controls tab
  3235. uroCtrlCameras.id = "uroCtrlCameras";
  3236. uroCtrlCameras.innerHTML = '<br><b>Show Cameras by creator:</b><br>';
  3237. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowWorldCams" checked>world_* users</input><br>';
  3238. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowUSACams" checked>usa_* users</input><br>';
  3239. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowNonWorldCams" checked>other users</input><br>';
  3240. uroCtrlCameras.innerHTML += '<br><input type="checkbox" id="_cbShowOnlyMyCams">Show ONLY cameras created/edited by me</input><br>';
  3241.  
  3242.  
  3243. uroCtrlCameras.innerHTML += '<br><b>Show Cameras by approval status:</b><br>';
  3244. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowApprovedCams" checked>approved</input><br>';
  3245. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowNonApprovedCams" checked>non-approved</input><br>';
  3246. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowOlderCreatedNonApproved"> if created more than </input>';
  3247. uroCtrlCameras.innerHTML += '<input type="number" min="1" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCameraMinCreatedDays"> days ago<br>';
  3248. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowOlderUpdatedNonApproved"> if updated more than </input>';
  3249. uroCtrlCameras.innerHTML += '<input type="number" min="1" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCameraMinUpdatedDays"> days ago<br>';
  3250.  
  3251. uroCtrlCameras.innerHTML += '<br><b>Show Cameras by type:</b><br>';
  3252. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowSpeedCams" checked>Speed</input><br>';
  3253. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowIfMPHSpeedSet" checked> with MPH speeds</input><br>';
  3254. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowIfKPHSpeedSet" checked> with KM/H speeds</input><br>';
  3255. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowIfNoSpeedSet" checked> with no speed</input><br>';
  3256. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowRedLightCams" checked>Red Light</input><br>';
  3257. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowDummyCams" checked>Dummy</input><br>';
  3258.  
  3259. uroCtrlCameras.innerHTML += '<br><b>Hide Cameras by creator:</b><br>';
  3260. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByMe">me</input>';
  3261. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank0">L1</input>';
  3262. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank1">L2</input>';
  3263. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank2">L3</input>';
  3264. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank3">L4</input>';
  3265. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank4">L5</input>';
  3266. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank5">L6</input>';
  3267.  
  3268. uroCtrlCameras.innerHTML += '<br><b>Hide Cameras by updater:</b><br>';
  3269. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByMe">me</input>';
  3270. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank0">L1</input>';
  3271. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank1">L2</input>';
  3272. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank2">L3</input>';
  3273. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank3">L4</input>';
  3274. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank4">L5</input>';
  3275. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank5">L6</input>';
  3276.  
  3277. uroCtrlCameras.innerHTML += '<br><br><b><input type="checkbox" id="_cbHideCWLCams">Hide cameras on CWL</input></b><br>';
  3278.  
  3279. // Camera watchlist tab
  3280. uroCamWatchlist.id = "uroCamWatchlist";
  3281. uroCWLUpdateHTML();
  3282. // Misc controls tab
  3283. uroCtrlMisc.id = "uroCtrlMisc";
  3284. uroCtrlMisc.innerHTML = '<br><b>Use default conversation markers:</b><br>';
  3285. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbNativeConvoMarkers" checked>in public WME</input><br>';
  3286. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbNativeBetaConvoMarkers" checked>in beta WME</input><br>';
  3287. uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbCommentCount">Show comment count on UR markers</input></b><br>';
  3288. uroCtrlMisc.innerHTML += '<br><br><b>Use custom marker for URs tagged as:</b><br>';
  3289. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomRoadworksMarkers">[ROADWORKS]</input><br>';
  3290. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomConstructionMarkers">[CONSTRUCTION]</input><br>';
  3291. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomClosuresMarkers">[CLOSURE]</input><br>';
  3292. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomEventsMarkers">[EVENT]</input><br>';
  3293. uroCtrlMisc.innerHTML += '<br><br><b>Disable popup for:</b><br>';
  3294. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitURPopup">URs</input><br>';
  3295. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitMPPopup">MPs</input><br>';
  3296. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitCamPopup">Cameras</input><br>';
  3297. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitSegPopup">Segments</input><br>';
  3298. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitLandmarkPopup">Landmarks</input><br>';
  3299.  
  3300. uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbWhiteBackground">Use white background</input></b><br>';
  3301.  
  3302. uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbHideAMLayer">Hide Area Manager polygons</input></b><br>';
  3303. uroCtrlMisc.innerHTML += '<br><b>Enable integrated scripts:</b><br>';
  3304. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbEnableDTE">Drive Tab Enhancement</input><br>';
  3305. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbEnableSRS">Select Roundabout Segments</input><br>';
  3306.  
  3307. uroCtrlMisc.innerHTML += '<br><br><b>Settings backup/restore:</b><br>';
  3308. uroCtrlMisc.innerHTML += '<input type="button" id="_btnSettingsToText" value="Backup">&nbsp;&nbsp;&nbsp;';
  3309. uroCtrlMisc.innerHTML += '<input type="button" id="_btnTextToSettings" value="Restore">&nbsp;&nbsp;|&nbsp;&nbsp;';
  3310. uroCtrlMisc.innerHTML += '<input type="button" id="_btnClearSettingsText" value="Clear"><br>';
  3311. uroCtrlMisc.innerHTML += '<textarea id="_txtSettings" value="">';
  3312. // footer for tabs container
  3313. uroCtrlHides.id = 'uroCtrlHides';
  3314. uroCtrlHides.innerHTML = '<input type="button" id="_btnUndoLastHide" value="Undo last hide">&nbsp;&nbsp;&nbsp;';
  3315. uroCtrlHides.innerHTML += '<input type="button" id="_btnClearSessionHides" value="Undo all hides"><p>';
  3316.  
  3317. // footer for AM list
  3318. uroAMList.id = 'uroAMList';
  3319.  
  3320. window.addEventListener("beforeunload", uroSaveSettings, false);
  3321. uroWazeBits();
  3322. }
  3323.  
  3324.  
  3325. function dteAddHeader()
  3326. {
  3327. rlcObj = document.getElementsByClassName("result-list-container");
  3328. if(typeof rlcObj == "undefined") return;
  3329. if(typeof rlcObj[0].children[0] == "undefined") return;
  3330. if(typeof rlcObj[0].children[0].innerHTML == "undefined") return;
  3331. var thtml = rlcObj[0].children[0].innerHTML;
  3332. if(thtml.indexOf('Full drive history') == -1)
  3333. {
  3334. thtml += '<br><br><i><small>Full drive history goes back to '+dteOldestFullDrive.toDateString()+'</small></i>';
  3335. rlcObj[0].children[0].innerHTML = thtml;
  3336. }
  3337. }
  3338.  
  3339.  
  3340. function dteSetNewTabLength()
  3341. {
  3342. uroAddLog('altering ResultsPerPage parameter...');
  3343.  
  3344. var t = document.getElementById('sidepanel-drives');
  3345. t.style.overflow = 'auto';
  3346. t.style.height = (window.innerHeight * 0.6) + 'px';
  3347.  
  3348. baseloc = 'https://'+window.location.hostname+Waze.Config.api_base+'/Archive/MyList?minDistance=1000';
  3349.  
  3350. var a = new XMLHttpRequest();
  3351. var idxCheckFullDrive = 0;
  3352. var fullDrives = 0;
  3353. var foundMissingDrive = false;
  3354.  
  3355. while(!foundMissingDrive)
  3356. {
  3357. document.getElementById(uroUserTabId).style.display = 'none';
  3358. var loc = baseloc+'&offset='+fullDrives+'&count=5';
  3359. uroAddLog('requesting '+loc);
  3360. a.open('GET',loc,false);
  3361. a.send();
  3362. var b = JSON.parse(a.responseText);
  3363. var loadedDrives = b.archives.objects.length;
  3364. uroAddLog('received '+loadedDrives+' drives');
  3365. if(loadedDrives != 5) foundMissingDrive = true;
  3366.  
  3367. for(var loop=0; loop < loadedDrives; loop++)
  3368. {
  3369. if(b.archives.objects[loop].hasFullSession == false) foundMissingDrive = true;
  3370. else
  3371. {
  3372. fullDrives++;
  3373. dteOldestFullDrive = new Date(b.archives.objects[loop].startTime);
  3374. }
  3375. }
  3376. }
  3377.  
  3378. uroAddLog(fullDrives+' full drives in history');
  3379. uroAddLog('oldest drives are on '+dteOldestFullDrive.toDateString());
  3380. if(fullDrives < 5)
  3381. {
  3382. fullDrives = 5;
  3383. uroAddLog('insufficient full drives, using standard drives tab');
  3384. }
  3385. else if(fullDrives > 50)
  3386. {
  3387. uroAddLog('too many full drives for a single tab page, splitting over multiple pages...');
  3388. fullDrives = Math.ceil(fullDrives/Math.ceil(fullDrives/50));
  3389. }
  3390. document.getElementById(uroUserTabId).style.display = '';
  3391. if((dteOldestFullDrive - dteEpoch) > 0)
  3392. {
  3393. uroAddLog('updating drives tab...');
  3394. wazeMap.controls[dteControlsIdx].sidePanelView.ResultsPerPage = fullDrives;
  3395. setInterval(dteAddHeader,250);
  3396. }
  3397. }
  3398.  
  3399.  
  3400. function srsSelect()
  3401. {
  3402. if(selectionManager.selectedItems[0].fid == null) rbtID = selectionManager.selectedItems[0].model.attributes.junctionID;
  3403. else rbtID = selectionManager.selectedItems[0].attributes.junctionID;
  3404. uroAddLog('selecting roundabout ID '+rbtID);
  3405. selectionManager.selectControl.unselectAll();
  3406.  
  3407. for(var slIdx=0; slIdx < W.map.segmentLayer.features.length; slIdx++)
  3408. {
  3409. if(W.map.segmentLayer.features[slIdx].fid == null)
  3410. {
  3411. junctionID = W.map.segmentLayer.features[slIdx].model.attributes.junctionID;
  3412. segID = W.map.segmentLayer.features[slIdx].model.attributes.id;
  3413. }
  3414. else
  3415. {
  3416. junctionID = W.map.segmentLayer.features[slIdx].attributes.junctionID;
  3417. segID = W.map.segmentLayer.features[slIdx].fid;
  3418. }
  3419. if(junctionID == rbtID)
  3420. {
  3421. uroAddLog('...adding segment '+segID);
  3422. selectionManager.selectControl.select(W.map.segmentLayer.features[slIdx]);
  3423. }
  3424. }
  3425. }
  3426.  
  3427.  
  3428. function srsCheckSidePanel()
  3429. {
  3430. if(selectionManager.selectedItems.length == 0) return;
  3431. if(document.getElementById('srsCtrl') != null) return;
  3432. var junctionID = null;
  3433. if(selectionManager.selectedItems[0].fid == null) junctionID = selectionManager.selectedItems[0].model.attributes.junctionID;
  3434. else junctionID = selectionManager.selectedItems[0].attributes.junctionID;
  3435. if(junctionID == null) return;
  3436. srsCtrl = document.createElement('section');
  3437. srsCtrl.id = 'srsCtrl';
  3438. srsCtrl.innerHTML = '<button id="srsButton" class="btn">Select roundabout</button>';
  3439. document.getElementById('segment-edit-general').appendChild(srsCtrl);
  3440. document.getElementById('srsButton').onclick = srsSelect;
  3441. }
  3442.  
  3443.  
  3444. uroBootstrap();