UROverview Plus (URO+)

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

当前为 2015-01-04 提交的版本,查看 最新版本

  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.35
  9. // ==/UserScript==
  10.  
  11. /*
  12. To-do list
  13. ==========
  14.  
  15. Expand scope of CWL to allow watching of other objects (segments, places, URs...) - Object Watch List (OWL :-)
  16.  
  17. Unstacking of stacked UR/MP/etc markers?
  18.  
  19. Restricted turn info popup
  20.  
  21. Place filtering
  22. - by last user to edit
  23. - collapsible filter subcategories
  24.  
  25. First-run information
  26. - show quickstart guide to URO features if no existing settings are present (i.e. new installation)
  27.  
  28. User-defined setting presets
  29.  
  30. Fix problem with UR conversations
  31.  
  32. Done for this release
  33. =====================
  34.  
  35. UR backfilling (beta release code)
  36.  
  37. */
  38.  
  39. function uroGlobals()
  40. {
  41. uroVersion = "3.35";
  42. uroShowDebugOutput = true;//false;
  43. uroCtrlsHidden = false;
  44. uroCurrentTab = 1;
  45. uroFID = -1;
  46. uroShownFID = -1;
  47. uroShownPopupType = null;
  48. uroInhibitSave = true;
  49. uroPopupTimer = -2;
  50. uroPopupShown = false;
  51. uroSetupListeners = true;
  52. uroRootContainer = null;
  53. uroPlacesRoot = null;
  54. uroMaskLayer = null;
  55. uroCamLayer = null;
  56. uroCustomMarkerFID = null;
  57. uroConfirmIntercepted = false;
  58. uroCustomMarkerList = [];
  59. uroURLayerIdx = null;
  60. uroProblemLayerIdx = null;
  61. uroMouseInPopup = false;
  62. uroURControlsIdx = null;
  63. uroProblemControlsIdx = null;
  64. uroMaskActive = false;
  65. uroAMLayerIdx = null;
  66. uroTurnsLayerIdx = null;
  67.  
  68. uroNullCamLayer = false;
  69. uroNullOpenLayers = false;
  70. uroNullRootContainer = false;
  71. uroNullURLayer = false;
  72. uroNullProblemLayer = false;
  73. uroNullMapViewport = false;
  74. uroPlaceSelected = false;
  75. uroMouseIsDown = false;
  76. uroBackfilling = false;
  77. uroUserID = -1;
  78. uroURSCurrentCount = 0;
  79. uroURSPrevCount = 0;
  80. uroBetaEditor = false;
  81. uroPracticeMode = false;
  82. uroWazeBitsPresent = 0;
  83. uroCamWatchObjects = new Array();
  84. uroCWLGroups = new Array();
  85. uroFilteredCameraIDs = new Array();
  86. uroAMPosX = null;
  87. uroAMPosY = null;
  88. dteControlsIdx = -1;
  89. dteOldestFullDrive = new Date(0);
  90. dteEpoch = new Date(0);
  91. uroUserTabId = '';
  92.  
  93. uroIcons =
  94. [
  95. // stuff used within the URO tabbed UI
  96. // 0 = group collapse/group expand
  97. [
  98. "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94CAhYRIqo78SIAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAADtJREFUKM9j/P//PwNJgCQN////ZyFeGyMjIwMDAxMDiWAQamDB9Bb+kKTMBmICdxgFK64AxZKiSE3eAAOXFRnJRfN6AAAAAElFTkSuQmCC",
  99. "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94CAhYRDHbt/O0AAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAE5JREFUKM+9UkEKACAMcmP//7IdgghqMQvytoOKTiMJCRKBZNRpZgbAIcIzsa5XJcgOB8Qaaz3nSt4chlLX3nb9OXRlL7cO2V83I1Dn3QDKfhshMqWScAAAAABJRU5ErkJggg=="
  100. ],
  101. // 1 = addtogroup active/addtogroup idle
  102. [
  103. "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BGhYVKhKBubQAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAEZJREFUOMtjYBjygBHB/P8fjzJGIszCZQA+gxkYWIjTABPDdAkL8U7G7hIcYcDISEGYwDQSFyZM5AQckYA4F7CQZ8goQAYAMCsd/TxbqrwAAAAASUVORK5CYII=",
  104. "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94DAw0tDee2t8AAAABPSURBVDjL7ZAxCgAgDAMT6cP6dH+mUwfBaugmeFMpbTgCPA9j6H2M7MidvCZlAadgADDlIXY7E1OVM5NtB+5kuZN4VDtpleIkVAOrhHxWJoJkNv2QAd51AAAAAElFTkSuQmCC"
  105. ],
  106. // 2 = goto active/goto idle
  107. [
  108. "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BGhYfLAEN9AsAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAGdJREFUOMutk+EKACEIg7fD93/l3Y+uP5kmeYMgkH0NTUpCRw+acgBynHaCKsgBlpaIhDJQtQchaAtIBuNAlAQSV7OUwPYYGX2kL6Zi37hYYk6NU1ZPui/Y4XWeVsWSDpdkt8bftvEFOy0jJkeygWMAAAAASUVORK5CYII=",
  109. "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94DAw0tFm3TfiwAAABySURBVDjLrZNRDsAgCEPp4r306HKy7sMsMRMckZH4ZfqoYEFSMnVJshYAME7aQRS0AOaR9C5UFe5AoRnsQCbAW4wFAklRlaNd1ipIrxHeRwKGZeuuNcEjK554J5x7lohNS+g+4d39Kyqug2jGyqnwtzTengM2Gxwa0GsAAAAASUVORK5CYII="
  110. ],
  111. // replacements for native UR/problem markers
  112. // 3 = normal/selected open roadworks UR
  113. [
  114. "data:image/png;base64,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",
  115. "data:image/png;base64,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"
  116. ],
  117. // 4 = normal/selected closed roadworks UR
  118. [
  119. "data:image/png;base64,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",
  120. "data:image/png;base64,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"
  121. ],
  122. // 5 = normal/selected open closure UR
  123. [
  124. "data:image/png;base64,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",
  125. "data:image/png;base64,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"
  126. ],
  127. // 6 = normal/selected closed closure UR
  128. [
  129. "data:image/png;base64,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",
  130. "data:image/png;base64,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"
  131. ],
  132. // 7 = normal/selected open event UR
  133. [
  134. "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAoCAYAAABw65OnAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94ICBQjDyQd1Y0AAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAADRJJREFUWMOdWGuMXOV5fr7Luc7O7Myud3zD62XBxmmAGpu4rE3KqJCkNkKVsNympQktP2ijBqlQpYQikTa4qSqUVX4QESjEwRQJgVAoN7dxRKfF4GJuDmGJVzbJ1Lf17uzsZW7nfOe7vP2xa8fYJiQ9Pz+dc97ne6/P8zL85g8HwCqVCmu1Wuz0YT6fp2q1SgAIgPtNfsh+zXdYpVLhtVpNDg0NSWOMlySJCIKAN5tNVigUSCnloiiyUkpdq9XM0NCQqVarbhEU/SoD4hOM840bN0rnXFgoFHL5fL6QJEnROVcC0CelLPm+X+KcF6y1eWttrJQKi8Wib60VWmu2bt06mpiY+H95glUqFaGU8gBEQoge51xh06ZNq2655ZbPDQ4OXt3T03NJGIZLOOe+cy5L03S63W5/ePTo0beefPLJvQcOHDjGOW9aa9sAkiAIdLVatRfyyoVAsI0bN8owDMM0TXs8zyveeOONl916661/sXLlyhs45/LjbpRkHUR+Ds45c+LEiR8//vjjD7/00kvjWuu5MAzbaZqmb7/9tjkXCLsQACllFARBb5ZlA6Ojo3+6adOmrzDOQs74r51sjhzIUXrgwIGH7rrrrn/1fb+ulJo3xiTnAmHnhkBrHTHGSnEcL3/44YfvGxoa2vaJFolAjMHNHoI78jzY9E8h1Dxsbikw+HnUvKtf/quv/OU3u93uBBHNep6XnB2asxNTJEkSFovFXsbYsl27dv3D6tWrtzHGFl79FXXkGAN9+ALYTx+FzDpgzIARB1cN8BP/hfxsdc3mPxtd+dxzzx9wzunDhw+bTqdzHgi2detWL47jvFKqPDo6+udXXnnlLYwxqCyDa87Apho8Cs/DQkRwp96E+PB58KAf8EMw5gGMA8yBnIFI5tDbPLBm3R98Q734wguHyuVydvnll+sjR464040HlUpFTE1NhURU2Lp166evueaa23WmMPsvj6F+3e9icus2nNiyBb8YXoXWW2/BOQdyDsY6OGiIsR+AgjwoKsL5JZDXA5IRiHlgMgRxCVl/HxsHZm/funXrp4moMDU1FVYqFXHaE6xWq3l9fX35QqFQvv/++++OZbCmceuXgONHIXp7IfwITHrQBCSP7sIPSsP4+kwB3z48gyfG67hUzmNFDEi/AC4kYDIwl4FZBegUzKQgp0C6Kdd+4W9KL7744r5ms5m8+eabCoDjAPiWLVv8MAxzGzZsuHjF6tW/17rnbkQDZQTlMsJyGV5/CbK3iObgEP7uif3Yt2YERd/DijAAyRC3d7bimhPXg1EXZBUYWZAzADmALMAMGBxE4ydYtWrVdRs2bLg4DMPcli1bfACcVyoVprX24zjObd++/QZVrUKaDF7/EoTl5fD6+sELBbieCN/5+qPoy+ewPAww4AsUPYGC7yEnBaZcAZ86PAKWNgDdBrMJnFUgZ0DGAY4Ao8A5F9u3b78hjuOc1tqvVCqMV6tVYa31lVK5wcHBq7J9r4KHEUQuhtfXB0QBBPfwzdt2YkkQYCAKsTTyUfI5ejyJWEqEQiDkHP9rCxidWY3MzINUE1x3wWwK2GQhi+MyuqqNwcHBq5RSOWutX61WBR8ZGeFBEPhRFIXFYnHIHT4MpzUoUchmZ0CJgnEWWa6IWEj0BxKlIEBOBggZh2QckjNwziEY4VutTfCSeSBrAVkb0B3AqYUSX7oJcdCDYrE4FEVRGASBPzIywmU+n+eNRkMSkR/HcbHdbAOMg/M6WCsAaYWDxVUgEAwcUmchiGCI4AhwYCACHBEIDAk4WHoKsA5kE7CsAwYsJObwQt+L47iYZZmfZZns7+/nMssyJqXkRMQ55x5yMUxjDlAKTHCQMTjZtxZda9DUHCACiKFlMrSMQWItFDloa2HJgcBASQOAWAgFGMCArLAS3srrFggJ5x4RcSklz7KMSQCIoojSNIW1Vst1l3npnj0w3RBCcFhj0C/fQ0ttB5xDIj0QEVLr0LIa7cyhY4CuM7AO8JgFsxlAfJGJEMhm4JXv4vTksdbq03YBgPu+T8YY5/u+7XQ6M8H1NyA9fhx6ahrqVB3Z1BTWHKhiJlWYTjUm0wSTKsOUUmhkDnPaoGkMEiMAxpCDgjlrPhIR3GfuBev/7TOnnU5nxvd9u2iXZKvVckII45zLGo1GbdnV65fy8jJkR2tgnINZB5cpzHYVOj7BFxwEICMgBdDWGm1tocmBIPAl+58Qp+9MBDtyH9jaP4bkCw1f6QQzMzO/cM5lAEyr1XJ8//79LkkSbYxJxsfHD0ZehPKux5BN1aEbMzBz87CdLu76zt+inmWYTBWmUoVpo1FPFWYyi9Q6gDEEAvj2F7+K9PNP40h4Hbp/+DrYmi9CcAmihckdeBEOHTr0E2NMkiSJ3r9/v+OVSsX6vq8YY93du3fvM8aonsuvwMonngC0hlvkrJ994z+Qzc+jnmrUjUMjs+hoC+ccGGNwRLhzTQGWRxBRBO/SGxH4eQixkEOMLXjCGKN27969jzHW9X1fVSoVy6vVqguCIBNCdI4fPz4xNjZWBYDCLX+CFc8+C6sNYAzIaOx97Gtw0oNzAOyCcTCAHOGKkoedVy6D4AJ+aS1MYRjCCz4CAADGxsaqx48fnxBCdIIgyKrVquMAqFqt6rm5uY7WenZ0dPTpNE1bknGUbr4Zn9IaPXd8FerLf4QNr7+KN65fCY8xGCz0CGOBzw5EePdzlwDil8zPabWQmmcBUEq1RkdHn9Zaz87NzXWq1aoGQGdIzZo1ayCEEHNzc4iiqHvFFVf8DmOMkbMIohjJ2mH0X7oOy3Ih7v2tEiJukE5P45+vXo4HPnMRGOcf4Ri5fBHS888+o6eeeup7e/fu/R8hxGQQBPPHjh1TANwZEMeOHcPAwACstXjnnXdmVqxY0bNnz551IyOb4V18MXiphDDOgTMOMI6852NFeTlWZVNYvWTJWSxn8facg3MOIsJ7772H999//4cPPPDAs1rrE1rrmTfeeCMBFqqZ//JTaADdXC7X0Fqf2Llz567Vq1c/u23bQqvtLS0DOXeGn15ZCvHlwQDriuFHmRYjHP1wDJxxWGtxzz334Oabb56644479iilTuZyuQaA7qK98zgmLrvsMgLgiMgCMK+99trPb7rppslHHnnkqlOTE3LN2mGEYQ5nhRndVhNxvndhPhCBAZiaPIVHHv0+brvtNmetfZlz/o04jseFEFNSylYQBKpWq7kLKrBarUZDQ0NOSmmTJNFCCD0+Pj5hjHldCFF++cXnV37h97cxIcQZ97W7bfTkegDGwBhDqlJ8//En6OC7B8d6enrua7fbewCcyLJsKo7jJoD0XBF0ngw8DSTLMhMEQdZut5XWunXy5Ml3Z2bnXxsfP7R+8+bNec/zAAA6TRDl8iAizMzM4N67v9ap/verd3e73R92Op0PkySZiKJoWmvdCoJAXUiFXVCL1mo1mpiYcMPDwyZN00wIoQCkjLH0yJHD77TbnZFisZgrl8tIuy2EcQ/SNIXOss5z//b838/Mzv5Ma32ciCadc7NxHHf379+fLYaALiTzP1YatlotG0WRMsa0OOcN59wpxvjxgwcP/tPQ0FATAKxzICIEQeAeeui7j9SOHh231k5wzqe11q0oilS9XndnK/xPUuVsx44d/IMPPvCWLl3q9/X1+YyxQErpW2ul1lqGYeQ1GtM8SdL5zZs3b5yaOcn6igN45ZVX9j744IM/FkJMCyFanHOdJAmklGLJkiVi+fLl8qKLLuK9vb2sXq9/bDhYpVIRk5OTwapVq3KlUinPOe8looKUspdzXgiCIM8Yy2lt4kOHfqaGhi6O1l6ydujEsaO1v77zzmcY423OecYY4wCCKIoiY0ycZVkEIGi1WjIMQ6xfv54Whc95JXp6CRJ7nlc0xpR83y8JIUpa6xJjrKi17uWcFxhjF+lMlV97/fXW+qvWL935j9/ad2piAkLIAACEEJKIckTUAyAnhIg4577v+8L3faeUsuVy2U1MTJwPYmRkRDLGIgA5IspzznMAYmttKKUMpZS+1tonoiXOuUgbLX/07z/6eb0+pQjMMcYc51wDMEQkhBBCSimstdzzPMqyzHLOM9/3syzL9MTEhDtXlXMA3rXXXhsDyCul8p7nxYyxkIg8a61kjAnOOWeMCWutZIDgQgiVpk5IaYUQhogsEVnGmJNSGgBGKZURUaK17hhjmkTUGRsbSwFYAHT2woN27Nhh6vV60mq1nFJKRVHkz83NyTAMPc65sNZyay2klFxKybudzkKHIkehFxFjjKy1zhhDYRiSUspYa20QBIYxphljSmutAGSLyzW64JJkcVEiGo2G6O/v5/l8nrdaLZHP55kxhllr2SJZZUQO1lgwxiCkhBDiTNYnSeKEEBSGoTty5IgbHh52zWbTDgwMuHMbFvuEXRZbLFvU6/WPrAxPPzpTkJ7/Ed5w9kpxx44deOaZZ+isQXles/o/KhD5gMjJ8lsAAAAASUVORK5CYII=",
  135. "data:image/png;base64,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"
  136. ],
  137. // 8 = normal/selected closed event UR
  138. [
  139. "data:image/png;base64,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",
  140. "data:image/png;base64,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"
  141. ],
  142. // 9 = normal/selected open note UR
  143. [
  144. "data:image/png;base64,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",
  145. "data:image/png;base64,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"
  146. ],
  147. // 10 = normal/selected closed note UR
  148. [
  149. "data:image/png;base64,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",
  150. "data:image/png;base64,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"
  151. ]
  152. ];
  153.  
  154. uroMarkers =
  155. [
  156. // 0 = comment count circle
  157. ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAaCAYAAAA5WTUBAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90LCxYGJyle3m4AAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAv1JREFUSMfFls1r3EYYxn+zo9XsqjuSxpBQU5OCDy0Y3JODs2Z36W6P/YBCk159s+/5F9Z/QsHkUAruZZ344Jx7KPTSa2/NwSdDE1ISf8SWI63k6UVLN8ZuZFnQ56IZDYwevR/P+wguh7jieXF9Gewla3vJWeELAfA8b9ZxnFWl1P0kST7NsswDkFJGrus+i+P4cZqmP0VR9JyKIWq12owx5kff95PBYBCPRiN7EaPRyA4Gg9j3/cQY80hK6VdFwFFK3TXGvOx0OoktiE6nExtjXjSbzYUb/T3QqNfrvSAITofDob0uhsOhDcPwTVkiAmgCC8aYV2UITBMxxrwok5oGcEdr/XR5eXlsb4g8NY+uVQPAh0KIr7XW6f7+vq0Cvu8nnufNvu/jtak03FZKfbe4uGjn5uYqqe6lpSXrOM5qERIS8IEZz/O66+vrTlUttra25iql7hfSImAB+DIIgrd7e3u2KhwcHNggCE6LREIBGlBZlqn5+fnK1C4MQybqWiQdKi/O/wWTwpSAkFLGWZZVdnkURUgpoyIk/t3Uas93dnYqI7G9vY3rus+KkLBABtgoin7f3NxMqyKxtbWVxHH8uIhUG+AT4CMhxK1Wq/XD8fGxrIJEEATjNE0/ft+IrwEx8AaIrbWH1tpfV1ZWbhyNbrc7llL+XMRjyDwdTt6mzSRJ/jw5Ofkiy7JGr9crRWBjY4Pd3d3XR0dH31hrz4pOTw18BnwFPBBCPPR9/6zsKA+C4FQpdbeoc3tngAErwLfA90KIh2EYHrbb7cITtd1uj40xr+r1eq+s7jSAO0A3J/IAWG21Wr9ordN+vz++yt71+/2x1jrVWj/NR0DjukbmHVcF3ALmgJl8L4UQoeu6n3ued+/8/Hw2yzKVG91YSvlXFEW/xXH8xFr7B/A38PYqZ13EbYtcwkPgdk7kgylZF1PWPc076xR4DbwEDvN3tmwkLtZIMx/xwWTA5d1ELm6T1j4CjoGznFgpX/lfZxJwpwhMR2JCJJkobllN+QeQNNGuneopoQAAAABJRU5ErkJggg=="],
  158. // 1 = green comment marker
  159. ["data:image/png;base64,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"],
  160. // 2 = yellow (own) comment marker
  161. ["data:image/png;base64,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"]
  162. ];
  163.  
  164. }
  165.  
  166.  
  167. function uroBootstrap()
  168. {
  169. var bGreasemonkeyServiceDefined = false;
  170. try {
  171. bGreasemonkeyServiceDefined = (typeof Components.interfaces.gmIGreasemonkeyService === "object");
  172. }
  173. catch (err) { /* Ignore */ }
  174. if (typeof unsafeWindow === "undefined" || ! bGreasemonkeyServiceDefined) {
  175. unsafeWindow = ( function () {
  176. var dummyElem = document.createElement('p');
  177. dummyElem.setAttribute('onclick', 'return window;');
  178. return dummyElem.onclick();
  179. }) ();
  180. }
  181. /* begin running the code! */
  182. uroInitialise();
  183. }
  184.  
  185.  
  186. function uroAddLog(logtext)
  187. {
  188. if(uroShowDebugOutput) console.log('URO+: '+logtext);
  189. }
  190.  
  191. function uroGetCBChecked(cbID)
  192. {
  193. return(document.getElementById(cbID).checked);
  194. }
  195.  
  196. function uroGetElmValue(elmID)
  197. {
  198. return(document.getElementById(elmID).value);
  199. }
  200.  
  201. function uroSetStyleDisplay(elm,style)
  202. {
  203. document.getElementById(elm).style.display = style;
  204. }
  205.  
  206. function uroSetOnClick(elm,fn)
  207. {
  208. document.getElementById(elm).onclick = fn;
  209. }
  210.  
  211. function uroAddEventListener(elm,eventType,eventFn,eventBool)
  212. {
  213. document.getElementById(elm).addEventListener(eventType, eventFn, eventBool);
  214. }
  215.  
  216.  
  217. function uroFirstTimerWelcomePack()
  218. {
  219. uroAddLog('welcome new users to Club URO...');
  220. // to be completed...
  221. }
  222.  
  223. function uroShowUpdateNotes()
  224. {
  225. uroAddLog('let existing users know what\'s new in this release');
  226. var alertMsg = 'URO+ Update Notes...\n\n';
  227. alertMsg += 'Thanks for upgrading to URO+ '+uroVersion+' (20150101). What\'s changed?\n\n';
  228.  
  229. alertMsg += '* More tweaking in an attempt to improve responsiveness with latest WME update\n';
  230. alertMsg += '* (beta release code) Added UR backfilling feature\n';
  231.  
  232. alert(alertMsg);
  233. }
  234.  
  235. function uroAdvertiseCustomIcons()
  236. {
  237. uroAddLog('advertise the benefits of custom UR icons...');
  238. var confirmMsg = 'URO+ Installation/Upgrade Processing...\n\n';
  239. confirmMsg += 'Hi there. One of the features of URO+ that a lot of users find useful is the ability to use a custom marker for URs which have been tagged with a specific keyword in their description text.\n\n';
  240. confirmMsg += 'Markers are defined for [ROADWORKS], [CONSTRUCTION], [CLOSURE], [EVENT] and [NOTE] tags.\n\n';
  241. confirmMsg += 'Would you like me to automatically enable these custom markers?\n\n';
  242. confirmMsg += 'If you change your mind later on, they can be enabled/disabled via the Misc tab within the URO+ settings';
  243. if(confirm(confirmMsg) == true)
  244. {
  245. document.getElementById('_cbCustomRoadworksMarkers').checked = true;
  246. document.getElementById('_cbCustomConstructionMarkers').checked = true;
  247. document.getElementById('_cbCustomClosuresMarkers').checked = true;
  248. document.getElementById('_cbCustomEventsMarkers').checked = true;
  249. document.getElementById('_cbCustomNotesMarkers').checked = true;
  250. }
  251. }
  252.  
  253.  
  254. function uroGatherSettings(container)
  255. {
  256. var options = '';
  257. var urOptions = document.getElementById(container).getElementsByTagName('input');
  258. for (var optIdx=0;optIdx<urOptions.length;optIdx++)
  259. {
  260. var id = urOptions[optIdx].id;
  261. if((id.indexOf('_cb') == 0)||(id.indexOf('_text') == 0)||(id.indexOf('_input') == 0))
  262. {
  263. options += ':' + id;
  264. if(urOptions[optIdx].type == 'checkbox') options += ',' + urOptions[optIdx].checked.toString();
  265. else if((urOptions[optIdx].type == 'text')||(urOptions[optIdx].type == 'number')) options += ',' + urOptions[optIdx].value.toString();
  266. }
  267. }
  268. return options;
  269. }
  270.  
  271.  
  272. function uroGatherCamWatchList()
  273. {
  274. var liststr = '';
  275. for(var loop=0;loop<uroCamWatchObjects.length;loop++)
  276. {
  277. camObj = uroCamWatchObjects[loop];
  278. if((camObj.fid != undefined) && (camObj.persistent == true))
  279. {
  280. if(loop > 0) liststr += ':';
  281.  
  282. liststr += camObj.fid+',';
  283. liststr += camObj.watchLon+',';
  284. liststr += camObj.watchLat+',';
  285. liststr += camObj.watchType+',';
  286. liststr += camObj.watchAzymuth+',';
  287. liststr += camObj.watchSpeed+',';
  288. liststr += camObj.watchValidated+',';
  289. liststr += camObj.groupID+',';
  290. liststr += camObj.server;
  291. }
  292. }
  293. return liststr;
  294. }
  295.  
  296. function uroGatherCWLGroups()
  297. {
  298. var liststr = '';
  299. for(var loop=0;loop<uroCWLGroups.length;loop++)
  300. {
  301. groupObj = uroCWLGroups[loop];
  302. if(groupObj.groupID != -1)
  303. {
  304. if(loop > 0) liststr += ':';
  305.  
  306. liststr += groupObj.groupID+',';
  307. liststr += groupObj.groupName+',';
  308. liststr += groupObj.groupCollapsed;
  309. }
  310. }
  311. return liststr;
  312. }
  313.  
  314. function uroSaveSettings()
  315. {
  316. if(uroInhibitSave) return;
  317.  
  318. if (localStorage)
  319. {
  320. localStorage.UROverviewUROptions = uroGatherSettings('uroCtrlURs');
  321. localStorage.UROverviewMPOptions = uroGatherSettings('uroCtrlMPs');
  322. localStorage.UROverviewCameraOptions = uroGatherSettings('uroCtrlCameras');
  323. localStorage.UROverviewMiscOptions = uroGatherSettings('uroCtrlMisc');
  324. localStorage.UROverviewPlacesOptions = uroGatherSettings('uroCtrlPlaces');
  325. localStorage.UROverviewCamWatchList = uroGatherCamWatchList();
  326. localStorage.UROverviewCWLGroups = uroGatherCWLGroups();
  327. localStorage.UROverviewCurrentVersion = uroVersion;
  328. }
  329. }
  330.  
  331. function uroApplySettings(settings)
  332. {
  333. var options = settings.split(':');
  334. for(var optIdx=0;optIdx<options.length;optIdx++)
  335. {
  336. var fields = options[optIdx].split(',');
  337. if(fields[0].indexOf('_cb') == 0)
  338. {
  339. if(document.getElementById(fields[0]) != null)
  340. {
  341. document.getElementById(fields[0]).checked = (fields[1] == 'true');
  342. }
  343. }
  344. else if((fields[0].indexOf('_input') == 0)||(fields[0].indexOf('_text') == 0))
  345. {
  346. if(document.getElementById(fields[0]) != null) document.getElementById(fields[0]).value = fields[1];
  347. }
  348. }
  349. }
  350.  
  351.  
  352. function uroApplyCamWatchList()
  353. {
  354. var objects = localStorage.UROverviewCamWatchList.split(':');
  355. uroCamWatchObjects = new Array();
  356.  
  357. for(var objIdx=0;objIdx<objects.length;objIdx++)
  358. {
  359. var fields = objects[objIdx].split(',');
  360. // following two bits of code add in blank fields if the user has updated their copy of URO+ from an
  361. // older version which didn't include support for either of these field types
  362. // add default groupID field
  363. if(fields.length == 7)
  364. {
  365. fields.push(0);
  366. }
  367. // set default groupID value to 0 (no group)
  368. if(fields[7] == -1)
  369. {
  370. fields[7] = 0;
  371. }
  372.  
  373. // add default server field
  374. if(fields.length == 8)
  375. {
  376. fields.push('??');
  377. }
  378. // set default server value to unknown
  379. if(fields[8] == 0)
  380. {
  381. fields[8] = '??';
  382. }
  383.  
  384. uroCamWatchObjects.push(new uroCamWatchObj(true,fields[0],fields[1],fields[2],fields[3],fields[4],fields[5],fields[6],fields[7],fields[8]));
  385. }
  386. }
  387.  
  388. function uroApplyCWLGroups()
  389. {
  390. var objects = localStorage.UROverviewCWLGroups.split(':');
  391. uroCWLGroups = new Array();
  392.  
  393. for(var objIdx=0;objIdx<objects.length;objIdx++)
  394. {
  395. var fields = objects[objIdx].split(',');
  396. if(fields.length < 2)
  397. {
  398. fields.push(false);
  399. }
  400. uroCWLGroups.push(new uroCWLGroupObj(fields[0],fields[1],(fields[2] == 'true')));
  401. }
  402. }
  403.  
  404. function uroLoadSettings()
  405. {
  406. var isNewInstall = true;
  407. var isUpgradeInstall = true;
  408. var notifyAboutCustomIcons = true;
  409. uroAddLog('loadSettings()');
  410. if (localStorage.UROverviewUROptions)
  411. {
  412. uroAddLog('recover UR tab settings');
  413. uroApplySettings(localStorage.UROverviewUROptions);
  414. isNewInstall = false;
  415. }
  416. if (localStorage.UROverviewCameraOptions)
  417. {
  418. uroAddLog('recover camera tab settings');
  419. uroApplySettings(localStorage.UROverviewCameraOptions);
  420. isNewInstall = false;
  421. }
  422.  
  423. if (localStorage.UROverviewMPOptions)
  424. {
  425. uroAddLog('recover MP tab settings');
  426. uroApplySettings(localStorage.UROverviewMPOptions);
  427. isNewInstall = false;
  428. }
  429.  
  430. if (localStorage.UROverviewPlacesOptions)
  431. {
  432. uroAddLog('recover Places tab settings');
  433. uroApplySettings(localStorage.UROverviewPlacesOptions);
  434. isNewInstall = false;
  435. }
  436. if (localStorage.UROverviewMiscOptions)
  437. {
  438. uroAddLog('recover misc tab settings');
  439. uroApplySettings(localStorage.UROverviewMiscOptions);
  440. isNewInstall = false;
  441. if(localStorage.UROverviewCurrentVersion)
  442. {
  443. notifyAboutCustomIcons = false;
  444. }
  445. else
  446. {
  447. if(uroGetCBChecked('_cbCustomRoadworksMarkers') == true) notifyAboutCustomIcons = false;
  448. if(uroGetCBChecked('_cbCustomConstructionMarkers')== true) notifyAboutCustomIcons = false;
  449. if(uroGetCBChecked('_cbCustomClosuresMarkers') == true) notifyAboutCustomIcons = false;
  450. if(uroGetCBChecked('_cbCustomEventsMarkers') == true) notifyAboutCustomIcons = false;
  451. if(uroGetCBChecked('_cbCustomNotesMarkers') == true) notifyAboutCustomIcons = false;
  452. }
  453. }
  454. if(localStorage.UROverviewCWLGroups)
  455. {
  456. uroAddLog('recover CWL groups');
  457. uroApplyCWLGroups();
  458. isNewInstall = false;
  459. }
  460. else
  461. {
  462. uroAddLog('set default CWL group');
  463. uroCWLGroups.push(new uroCWLGroupObj(0,'No group',false));
  464. }
  465.  
  466. if(localStorage.UROverviewCamWatchList)
  467. {
  468. uroAddLog('recover camera watchlist');
  469. uroApplyCamWatchList();
  470. uroGetCurrentCamWatchListObjects();
  471. isNewInstall = false;
  472. }
  473. if(localStorage.UROverviewCurrentVersion)
  474. {
  475. uroAddLog('comparing install versions');
  476. if(localStorage.UROverviewCurrentVersion == uroVersion)
  477. {
  478. isUpgradeInstall = false;
  479. }
  480. }
  481. if(isNewInstall)
  482. {
  483. uroFirstTimerWelcomePack();
  484. }
  485. else if(isUpgradeInstall)
  486. {
  487. uroShowUpdateNotes();
  488. }
  489. if(notifyAboutCustomIcons)
  490. {
  491. uroAdvertiseCustomIcons();
  492. }
  493. uroInhibitSave = false;
  494. }
  495.  
  496. function uroSettingsToText()
  497. {
  498. var txtSettings = '';
  499. uroSaveSettings();
  500. if (localStorage.UROverviewUROptions)
  501. {
  502. txtSettings += '[UROverviewUROptions][len=' + localStorage.UROverviewUROptions.length + ']' + localStorage.UROverviewUROptions + '[END]';
  503. }
  504. if (localStorage.UROverviewCameraOptions)
  505. {
  506. txtSettings += '[UROverviewCameraOptions][len=' + localStorage.UROverviewCameraOptions.length + ']' + localStorage.UROverviewCameraOptions + '[END]';
  507. }
  508. if (localStorage.UROverviewMPOptions)
  509. {
  510. txtSettings += '[UROverviewMPOptions][len=' + localStorage.UROverviewMPOptions.length + ']' + localStorage.UROverviewMPOptions + '[END]';
  511. }
  512. if (localStorage.UROverviewMiscOptions)
  513. {
  514. txtSettings += '[UROverviewMiscOptions][len=' + localStorage.UROverviewMiscOptions.length + ']' + localStorage.UROverviewMiscOptions + '[END]';
  515. }
  516. if (localStorage.UROverviewCamWatchList)
  517. {
  518. txtSettings += '[UROverviewCamWatchList][len=' + localStorage.UROverviewCamWatchList.length + ']' + localStorage.UROverviewCamWatchList + '[END]';
  519. }
  520. if (localStorage.UROverviewCWLGroups)
  521. {
  522. txtSettings += '[UROverviewCWLGroups][len=' + localStorage.UROverviewCWLGroups.length + ']' + localStorage.UROverviewCWLGroups + '[END]';
  523. }
  524. if (localStorage.UROverviewPlacesOptions)
  525. {
  526. txtSettings += '[UROverviewPlacesOptions][len=' + localStorage.UROverviewPlacesOptions.length + ']' + localStorage.UROverviewPlacesOptions + '[END]';
  527. }
  528. document.getElementById('_txtSettings').value = txtSettings;
  529. document.getElementById('_txtSettings').focus();
  530. document.getElementById('_txtSettings').select();
  531. }
  532.  
  533. function uroTextToSettings()
  534. {
  535. var txtSettings = '';
  536. txtSettings = uroGetElmValue('_txtSettings');
  537. if(txtSettings.indexOf('[END]') == -1) return;
  538. var subText = txtSettings.split('[END]');
  539. for(var i=0;i<subText.length;i++)
  540. {
  541. var bPos = subText[i].indexOf(']');
  542. if(bPos != -1)
  543. {
  544. var settingID = subText[i].substr(1,bPos-1);
  545. subText[i] = subText[i].substr(bPos+1);
  546. bPos = subText[i].indexOf(']');
  547. if(bPos != -1)
  548. {
  549. var settingLength = subText[i].substr(5,bPos-5);
  550. subText[i] = subText[i].substr(bPos+1);
  551. if(subText[i].length == settingLength)
  552. {
  553. if(settingID == 'UROverviewCamWatchList') localStorage.UROverviewCamWatchList = subText[i];
  554. if(settingID == 'UROverviewCWLGroups') localStorage.UROverviewCWLGroups = subText[i];
  555. if(settingID == 'UROverviewUROptions') localStorage.UROverviewUROptions = subText[i];
  556. if(settingID == 'UROverviewCameraOptions') localStorage.UROverviewCameraOptions = subText[i];
  557. if(settingID == 'UROverviewMPOptions') localStorage.UROverviewMPOptions = subText[i];
  558. if(settingID == 'UROverviewMiscOptions') localStorage.UROverviewMiscOptions = subText[i];
  559. if(settingID == 'UROverviewPlacesOptions') localStorage.UROverviewPlacesOptions = subText[i];
  560. }
  561. }
  562. }
  563. }
  564. uroLoadSettings();
  565. }
  566.  
  567. function uroClearSettingsText()
  568. {
  569. document.getElementById('_txtSettings').value = '';
  570. }
  571.  
  572.  
  573. function uroDateToDays(dateToConvert)
  574. {
  575. var dateNow = new Date();
  576. var elapsedSinceEpoch = dateNow.getTime();
  577. var elapsedSinceEvent = elapsedSinceEpoch - dateToConvert;
  578. dateNow.setHours(0);
  579. dateNow.setMinutes(0);
  580. dateNow.setSeconds(0);
  581. dateNow.setMilliseconds(0);
  582. var elapsedSinceMidnight = elapsedSinceEpoch - dateNow.getTime();
  583. if(elapsedSinceEvent < elapsedSinceMidnight)
  584. {
  585. // event occurred today...
  586. return 0;
  587. }
  588. else
  589. {
  590. // event occurred at some point prior to midnight this morning, so return a minimum value of 1...
  591. return 1 + Math.floor((elapsedSinceEvent - elapsedSinceMidnight) / 86400000);
  592. }
  593. }
  594.  
  595. function uroGetURAge(urObj,ageType)
  596. {
  597. if(ageType == 0)
  598. {
  599. if((urObj.attributes.driveDate == null)||(urObj.attributes.driveDate == 0)) return -1;
  600. return uroDateToDays(urObj.attributes.driveDate);
  601. }
  602. else
  603. {
  604. if((urObj.attributes.resolvedOn == null)||(urObj.attributes.resolvedOn == 0)) return -1;
  605. return uroDateToDays(urObj.attributes.resolvedOn);
  606. }
  607. }
  608.  
  609. function uroGetCameraAge(camObj, mode)
  610. {
  611. if(mode == 0)
  612. {
  613. if(camObj.attributes.updatedOn == null) return -1;
  614. return uroDateToDays(camObj.attributes.updatedOn);
  615. }
  616. if(mode == 1)
  617. {
  618. if(camObj.attributes.createdOn == null) return -1;
  619. return uroDateToDays(camObj.attributes.createdOn);
  620. }
  621. }
  622.  
  623. function uroGetCommentAge(commentObj)
  624. {
  625. if(commentObj.createdOn == null) return -1;
  626. return uroDateToDays(commentObj.createdOn);
  627. }
  628.  
  629. function uroParseDaysAgo(days)
  630. {
  631. if(days == 0) return 'today';
  632. else if(days == 1) return '1 day ago';
  633. else return days+' days ago';
  634. }
  635.  
  636. function uroIsCameraSpeedValid(camObj)
  637. {
  638. // returns 1 if the entered speed converts correctly into a multiple of 10MPH
  639. // returns -1 if the entered speed does not convert correctly
  640. // returns 0 if no speed data is present, or if the entered speed is 0
  641. if(camObj.attributes.speed != null)
  642. {
  643. var speed = Math.round(camObj.attributes.speed /1.609);
  644. if(speed == 0) return 0;
  645. else if(speed % 10 == 0) return 1;
  646. else return -1;
  647. }
  648. else return 0;
  649. }
  650.  
  651.  
  652. function uroTypeCast(varin)
  653. {
  654. if(varin == "null") return null;
  655. if(typeof varin == "string") return parseInt(varin);
  656. return varin;
  657. }
  658.  
  659. function uroCWLGroupObj(groupID, groupName, groupCollapsed)
  660. {
  661. groupID = uroTypeCast(groupID);
  662. this.groupID = groupID;
  663. this.groupName = groupName;
  664. this.groupCount = 0;
  665. this.groupCollapsed = groupCollapsed;
  666. }
  667. function uroCamWatchObj(persistent, fid, lon, lat, type, azymuth, speed, validated, groupID, server)
  668. {
  669. fid = uroTypeCast(fid);
  670. lon = uroTruncate(uroTypeCast(lon));
  671. lat = uroTruncate(uroTypeCast(lat));
  672. type = uroTypeCast(type);
  673. azymuth = uroTruncate(uroTypeCast(azymuth)%360);
  674. speed = uroTruncate(uroTypeCast(speed));
  675. groupID = uroTypeCast(groupID);
  676. if(typeof validated == "string") validated = (validated == "true");
  677. if(typeof persistent == "string") persistent = (persistent == "true");
  678.  
  679. this.fid = fid;
  680. this.persistent = persistent;
  681. this.loaded = false;
  682. this.watchType = type;
  683. this.watchAzymuth = azymuth;
  684. this.watchSpeed = speed;
  685. this.watchValidated = validated;
  686. this.watchLat = lat;
  687. this.watchLon = lon;
  688. this.groupID = groupID;
  689. this.currentType = null;
  690. this.currentAzymuth = null;
  691. this.currentSpeed = null;
  692. this.currentValidated = null;
  693. this.currentLat = null;
  694. this.currentLon = null;
  695. this.server = server;
  696. }
  697.  
  698. function uroCamDataChanged(camidx)
  699. {
  700. camObj = uroCamWatchObjects[camidx];
  701. if(camObj.loaded == false) return false;
  702. if(camObj.currentType != camObj.watchType) return true;
  703. if(camObj.currentAzymuth != camObj.watchAzymuth) return true;
  704. if(camObj.currentSpeed != camObj.watchSpeed) return true;
  705. if(camObj.currentValidated != camObj.watchValidated) return true;
  706. if(camObj.currentLat != camObj.watchLat) return true;
  707. if(camObj.currentLon != camObj.watchLon) return true;
  708. return false;
  709. }
  710.  
  711. function uroAddCurrentCamWatchData(idx, lat, lon, type, azymuth, speed, validated, server)
  712. {
  713. camObj = uroCamWatchObjects[idx];
  714. camObj.loaded = true;
  715. camObj.currentType = type;
  716. camObj.currentAzymuth = uroTruncate(azymuth%360);
  717. camObj.currentSpeed = uroTruncate(speed);
  718. camObj.currentValidated = validated;
  719. camObj.currentLat = uroTruncate(lat);
  720. camObj.currentLon = uroTruncate(lon);
  721. camObj.server = server;
  722. return(uroCamDataChanged(idx));
  723. }
  724.  
  725. function uroIsCamOnWatchList(fid)
  726. {
  727. for(var loop=0;loop<uroCamWatchObjects.length;loop++)
  728. {
  729. if(uroCamWatchObjects[loop].fid == fid) return loop;
  730. }
  731. return -1;
  732. }
  733.  
  734. function uroAddCamToWatchList()
  735. {
  736. if(uroIsCamOnWatchList(uroShownFID) == -1)
  737. {
  738. camObj = W.model.cameras.objects[uroShownFID];
  739. 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));
  740. 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);
  741. uroAddLog('added camera '+uroShownFID+' to watchlist');
  742. uroCWLUpdateHTML();
  743. }
  744. }
  745.  
  746. function uroRemoveCamFromWatchList()
  747. {
  748. camidx = uroIsCamOnWatchList(uroShownFID);
  749. if(camidx != -1)
  750. {
  751. uroCamWatchObjects.splice(camidx,1);
  752. uroAddLog('removed camera '+uroShownFID+' from watchlist');
  753. uroCWLUpdateHTML();
  754. }
  755. }
  756.  
  757. function uroUpdateCamWatchList()
  758. {
  759. var camIdx = uroIsCamOnWatchList(uroShownFID);
  760. if(camIdx != -1)
  761. {
  762. var camObj = W.model.cameras.objects[uroShownFID];
  763. uroCamWatchObjects[camIdx].watchLon = uroTruncate(camObj.geometry.x);
  764. uroCamWatchObjects[camIdx].watchLat = uroTruncate(camObj.geometry.y);
  765. uroCamWatchObjects[camIdx].watchAzymuth = uroTruncate(camObj.attributes.azymuth%360);
  766. uroCamWatchObjects[camIdx].watchSpeed = uroTruncate(camObj.attributes.speed);
  767. uroCamWatchObjects[camIdx].watchValidated = camObj.attributes.validated;
  768. }
  769. }
  770.  
  771.  
  772. function uroClearCamWatchList()
  773. {
  774. if(confirm('Removing all cameras from the CWL cannot be undone\nAre you sure you want to do this?') == true)
  775. {
  776. uroCamWatchObjects = new Array();
  777. uroCWLUpdateHTML();
  778. }
  779. }
  780.  
  781. function uroTruncate(val)
  782. {
  783. if(val == null) return val;
  784. if(val < 0) return Math.ceil(val);
  785. return Math.floor(val);
  786. }
  787.  
  788.  
  789. function uroRetrieveCameras(lat, lon)
  790. {
  791. var camPos = new OpenLayers.LonLat();
  792. var camChanged = false;
  793. camPos.lon = lon;
  794. camPos.lat = lat;
  795. camPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
  796.  
  797. var camURL = 'https://' + document.location.host;
  798. camURL += Waze.Config.api_base;
  799. camURL += '/Features?language=en&cameras=true&bbox=';
  800. var latl = camPos.lat - 0.25;
  801. var latu = camPos.lat + 0.25;
  802. var lonl = camPos.lon - 0.25;
  803. var lonr = camPos.lon + 0.25;
  804. camURL += lonl+','+latl+','+lonr+','+latu;
  805. uroAddLog('retrieving camera data around '+camPos.lon+','+camPos.lat);
  806.  
  807. camReq = new XMLHttpRequest();
  808. camReq.open('GET',camURL,false);
  809. try
  810. {
  811. camReq.send();
  812. uroAddLog('response '+camReq.status+' received');
  813. if (camReq.status === 200)
  814. {
  815. camData = JSON.parse(camReq.responseText);
  816. for(var camIdx = 0; camIdx < camData.cameras.objects.length; camIdx++)
  817. {
  818. camObj = camData.cameras.objects[camIdx];
  819. var listIdx = uroIsCamOnWatchList(camObj.id);
  820. if(listIdx != -1)
  821. {
  822. camPos.lon = camObj.geometry.coordinates[0];
  823. camPos.lat = camObj.geometry.coordinates[1];
  824. camPos.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
  825. camPos.lon = uroTruncate(camPos.lon);
  826. camPos.lat = uroTruncate(camPos.lat);
  827. camChanged |= uroAddCurrentCamWatchData(listIdx, camPos.lat, camPos.lon, camObj.type, camObj.azymuth, camObj.speed, camObj.validated, W.location.code);
  828. }
  829. else if(camObj.validated == false)
  830. {
  831.  
  832. }
  833. }
  834. }
  835. else
  836. {
  837. uroAddLog('request failed (status != 200)');
  838. }
  839. }
  840. catch(err)
  841. {
  842. uroAddLog('camera load request failed (exception '+err+' caught)');
  843. }
  844. return camChanged;
  845. }
  846.  
  847.  
  848. function uroGetCurrentCamWatchListObjects()
  849. {
  850. var camChanged = false;
  851. var camsChanged = new Array();
  852. var camsDeleted = new Array();
  853. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  854. {
  855. camObj = uroCamWatchObjects[camidx];
  856. if((camObj.loaded == false) && ((camObj.server == W.location.code) || (camObj.server == '??')))
  857. {
  858. if(typeof W.model.cameras.objects[camObj.fid] == 'object')
  859. {
  860. if(W.model.cameras.objects[camObj.fid].state != "Delete")
  861. {
  862. wazeObj = W.model.cameras.objects[camObj.fid];
  863. camChanged |= uroAddCurrentCamWatchData(camidx, wazeObj.geometry.y, wazeObj.geometry.x, wazeObj.attributes.type, wazeObj.attributes.azymuth, wazeObj.attributes.speed, wazeObj.attributes.validated);
  864. }
  865. else
  866. {
  867. camChanged |= uroRetrieveCameras(camObj.watchLat, camObj.watchLon);
  868. }
  869. }
  870. else
  871. {
  872. camChanged |= uroRetrieveCameras(camObj.watchLat, camObj.watchLon);
  873. }
  874. }
  875. }
  876. if(camChanged)
  877. {
  878. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  879. {
  880. if(uroCamDataChanged(camidx))
  881. {
  882. camsChanged.push(uroCamWatchObjects[camidx]);
  883. }
  884. }
  885. }
  886.  
  887. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  888. {
  889. camObj = uroCamWatchObjects[camidx];
  890. if((camObj.loaded == false) && (camObj.server == W.location.code))
  891. {
  892. camsDeleted.push(camObj);
  893. }
  894. }
  895.  
  896. if((camsChanged.length > 0) || (camsDeleted.length > 0))
  897. {
  898. var alertStr = 'Camera WatchList Alert!!!\r\n';
  899. for(var camidx=0;camidx<camsChanged.length;camidx++)
  900. {
  901. alertStr += 'Camera ID '+camsChanged[camidx].fid+' in group "'+uroFindCWLGroupByIdx(camsChanged[camidx].groupID)+'" has been changed\r\n';
  902. }
  903. for(var camidx=0;camidx<camsDeleted.length;camidx++)
  904. {
  905. alertStr += 'Camera ID '+camsDeleted[camidx].fid+' in group "'+uroFindCWLGroupByIdx(camsDeleted[camidx].groupID)+'" has been deleted\r\n';
  906. }
  907. alert(alertStr);
  908. }
  909. }
  910.  
  911. function uroClearDeletedCameras()
  912. {
  913. for(var camidx=uroCamWatchObjects.length-1;camidx>=0;camidx--)
  914. {
  915. if(uroCamWatchObjects[camidx].loaded == false)
  916. {
  917. uroShownFID = uroCamWatchObjects[camidx].fid;
  918. uroRemoveCamFromWatchList();
  919. }
  920. }
  921. }
  922.  
  923. function uroClearUnknownServerCameras()
  924. {
  925. var confirmMsg = 'Cameras with an unknown server cannot be automatically verified by URO+.\n';
  926. confirmMsg += 'It is recommended that you manually load WME from each server (World, USA/Canada and Israel) to give URO+ a chance of locating these cameras.\n';
  927. confirmMsg += 'If the cameras then continue to show up as an unknown server, it is safe to delete them...\n\n';
  928. confirmMsg += 'Do you still wish to proceed with deleting all unknown server cameras?';
  929. if(confirm(confirmMsg) == true)
  930. {
  931. for(var camidx=uroCamWatchObjects.length-1;camidx>=0;camidx--)
  932. {
  933. if(uroCamWatchObjects[camidx].server == '??')
  934. {
  935. uroShownFID = uroCamWatchObjects[camidx].fid;
  936. uroRemoveCamFromWatchList();
  937. }
  938. }
  939. }
  940. }
  941.  
  942.  
  943. function uroRescanCamWatchList()
  944. {
  945. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  946. {
  947. uroCamWatchObjects[camidx].loaded = false;
  948. }
  949. uroGetCurrentCamWatchListObjects();
  950. uroCWLUpdateHTML();
  951. }
  952.  
  953.  
  954. function uroGotoCam()
  955. {
  956. var camidx = this.id.substr(13);
  957. var camPos = new OpenLayers.LonLat();
  958. camPos.lon = uroCamWatchObjects[camidx].watchLon;
  959. camPos.lat = uroCamWatchObjects[camidx].watchLat;
  960. W.map.setCenter(camPos,4);
  961. W.map.layers[uroCamLayer].setVisibility(true);
  962. return false;
  963. }
  964.  
  965. function uroSetCamGroup()
  966. {
  967. var camidx = this.id.substr(13);
  968. return false;
  969. }
  970.  
  971. function uroHighlightCWLEntry()
  972. {
  973. this.style.backgroundColor = '#FFFFAA';
  974. return false;
  975. }
  976.  
  977. function uroUnhighlightCWLEntry()
  978. {
  979. var camidx = this.id.substr(8);
  980. var changed = uroCamDataChanged(camidx);
  981. var deleted = (uroCamWatchObjects[camidx].loaded == false);
  982.  
  983. if(uroCamWatchObjects[camidx].server != W.location.code)
  984. {
  985. if(uroCamWatchObjects[camidx].server == '??') this.style.backgroundColor = '#A0A0A0';
  986. else this.style.backgroundColor = '#AAFFAA';
  987. }
  988. else if(changed) this.style.backgroundColor = '#AAAAFF';
  989. else if(deleted) this.style.backgroundColor = '#FFAAAA';
  990. else this.style.backgroundColor = '#FFFFFF';
  991. return false;
  992. }
  993.  
  994. function uroCWLIconHighlight()
  995. {
  996. iconType = this.id.substr(11,1);
  997. this.src = uroIcons[iconType][0];
  998. return false;
  999. }
  1000.  
  1001. function uroCWLIconLowlight()
  1002. {
  1003. iconType = this.id.substr(11,1);
  1004. this.src = uroIcons[iconType][1];
  1005. return false;
  1006. }
  1007.  
  1008. function uroRemoveFromCWL()
  1009. {
  1010. uroShownFID = uroCamWatchObjects[this.id.substr(18)].fid;
  1011. uroRemoveCamFromWatchList();
  1012. }
  1013.  
  1014.  
  1015. function uroSetCamGroups()
  1016. {
  1017. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  1018. {
  1019. camObj = uroCamWatchObjects[camidx];
  1020. camGroup = parseInt(uroGetElmValue("_uroGroupSelect-"+camidx));
  1021. camObj.groupID = camGroup;
  1022. }
  1023. }
  1024.  
  1025.  
  1026. function uroPopulateCWLGroupSelect()
  1027. {
  1028. var selector = document.getElementById('_uroCWLGroupSelect');
  1029. while(selector.options.length > 0)
  1030. {
  1031. selector.options.remove(0);
  1032. }
  1033. for(var loop=0;loop<uroCWLGroups.length;loop++)
  1034. {
  1035. var groupObj = uroCWLGroups[loop];
  1036. if(groupObj.groupID != -1)
  1037. {
  1038. selector.options.add(new Option(groupObj.groupName,groupObj.groupID));
  1039. }
  1040. }
  1041. }
  1042.  
  1043. function uroGetNextCWLGroupID()
  1044. {
  1045. var nextID = 1;
  1046. for(var loop=0;loop<uroCWLGroups.length;loop++)
  1047. {
  1048. if(uroCWLGroups[loop].groupID >= nextID)
  1049. {
  1050. nextID = uroCWLGroups[loop].groupID + 1;
  1051. }
  1052. }
  1053. return nextID;
  1054. }
  1055.  
  1056. function uroFindCWLGroupByName(groupName)
  1057. {
  1058. var groupID = -1;
  1059. for(var loop=0;loop<uroCWLGroups.length;loop++)
  1060. {
  1061. if((uroCWLGroups[loop].groupName == groupName) && (uroCWLGroups[loop].groupID != -1))
  1062. {
  1063. groupID = uroCWLGroups[loop].groupID;
  1064. break;
  1065. }
  1066. }
  1067. return groupID;
  1068. }
  1069.  
  1070. function uroFindCWLGroupByIdx(groupIdx)
  1071. {
  1072. var groupName = '';
  1073. for(var loop=0;loop<uroCWLGroups.length;loop++)
  1074. {
  1075. if(uroCWLGroups[loop].groupID == groupIdx)
  1076. {
  1077. groupName = uroCWLGroups[loop].groupName;
  1078. break;
  1079. }
  1080. }
  1081. return groupName;
  1082. }
  1083.  
  1084. function uroAddCWLGroup()
  1085. {
  1086. var groupID = uroGetNextCWLGroupID();
  1087. var groupName = uroGetElmValue('_uroCWLGroupEntry');
  1088. if(uroFindCWLGroupByName(groupName) == -1)
  1089. {
  1090. uroCWLGroups.push(new uroCWLGroupObj(groupID,groupName,false));
  1091. uroPopulateCWLGroupSelect();
  1092. }
  1093. }
  1094.  
  1095. function uroRemoveCWLGroup()
  1096. {
  1097. var selector = document.getElementById('_uroCWLGroupSelect');
  1098. var groupID = parseInt(selector.selectedOptions[0].value);
  1099. if(groupID == 0) return false; // prevent deletion of the default group
  1100. for(var loop=0;loop<uroCamWatchObjects.length;loop++)
  1101. {
  1102. var cwObj = uroCamWatchObjects[loop];
  1103. if(cwObj.groupID == groupID)
  1104. {
  1105. cwObj.groupID = 0;
  1106. }
  1107. }
  1108. for(var loop=0;loop<uroCWLGroups.length;loop++)
  1109. {
  1110. var groupObj = uroCWLGroups[loop];
  1111. if(groupObj.groupID == groupID)
  1112. {
  1113. groupObj.groupID = -1;
  1114. }
  1115. }
  1116. uroCWLUpdateHTML();
  1117. }
  1118.  
  1119. function uroAssignCameraToGroup()
  1120. {
  1121. var camidx = this.id.substr(13);
  1122. var selector = document.getElementById('_uroCWLGroupSelect');
  1123. uroCamWatchObjects[camidx].groupID = parseInt(selector.selectedOptions[0].value);
  1124. uroCWLUpdateHTML();
  1125. return false;
  1126. }
  1127.  
  1128. function uroAddBtnEvl(btnID, evlType, evlFunction)
  1129. {
  1130. btnObj = document.getElementById(btnID);
  1131. if(btnObj != null)
  1132. {
  1133. btnObj.addEventListener(evlType, evlFunction, true);
  1134. }
  1135. }
  1136.  
  1137. function uroCWLGroupCollapseExpand()
  1138. {
  1139. var groupidx = this.id.substr(18);
  1140. if(uroCWLGroups[groupidx].groupCollapsed == true) uroCWLGroups[groupidx].groupCollapsed = false;
  1141. else uroCWLGroups[groupidx].groupCollapsed = true;
  1142. uroCWLUpdateHTML();
  1143. return false;
  1144. }
  1145.  
  1146. function uroCWLUpdateHTML()
  1147. {
  1148. var camTypes = new Array("","","Speed", "Dummy", "Red Light");
  1149. var selectedGroup = 0;
  1150. iHTML = '';
  1151. if(document.getElementById('_uroCWLGroupSelect') != null)
  1152. {
  1153. selectedGroup = document.getElementById('_uroCWLGroupSelect').selectedIndex;
  1154. }
  1155.  
  1156. iHTML = '<br><b>Camera Watchlist:</b><br><br>';
  1157. iHTML += '<div id="_uroCWLCamList" style="height:65%;overflow:auto;">';
  1158. for(var groupidx=0;groupidx<uroCWLGroups.length;groupidx++)
  1159. {
  1160. var groupObj = uroCWLGroups[groupidx];
  1161. iHTML += '<div id="_uroCWLGroup-'+groupidx+'">';
  1162. if(groupObj.groupCollapsed == true)
  1163. {
  1164. iHTML += '<img src="'+uroIcons[0][1]+'" id="_uroCWLGroupState-'+groupidx+'">';
  1165. }
  1166. else
  1167. {
  1168. iHTML += '<img src="'+uroIcons[0][0]+'" id="_uroCWLGroupState-'+groupidx+'">';
  1169. }
  1170. iHTML += '<b>'+groupObj.groupName+'</b><br>';
  1171. groupObj.groupCount = 0;
  1172. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  1173. {
  1174. camObj = uroCamWatchObjects[camidx];
  1175. if(camObj.groupID == groupObj.groupID)
  1176. {
  1177. groupObj.groupCount++;
  1178. var changed = uroCamDataChanged(camidx);
  1179. var deleted = (camObj.loaded == false);
  1180. iHTML += '<div id="_uroCWL-'+camidx+'" style="padding:3px;border-width:2px;border-style:solid;border-color:#FFFFFF;background-color:';
  1181. if(camObj.server != W.location.code)
  1182. {
  1183. if(camObj.server == '??') iHTML += '#A0A0A0;';
  1184. else iHTML += '#AAFFAA;';
  1185. }
  1186. else if(changed) iHTML += '#AAAAFF;';
  1187. else if(deleted) iHTML += '#FFAAAA;';
  1188. else iHTML += '#FFFFFF;';
  1189. if(groupObj.groupCollapsed == true) iHTML += 'display:none;">';
  1190. else iHTML += 'display:block;">';
  1191.  
  1192. iHTML += 'ID: '+camObj.fid;
  1193. iHTML += ' ('+camObj.server+')';
  1194. iHTML += ' Type: '+camTypes[camObj.watchType];
  1195. if(camObj.server != W.location.code)
  1196. {
  1197. if(camObj.server == '??')
  1198. {
  1199. iHTML += '<br><i>Unknown server</i>';
  1200. }
  1201. else
  1202. {
  1203. iHTML += '<br><i>Not on this server</i>';
  1204. }
  1205. }
  1206. else if(deleted)
  1207. {
  1208. iHTML += '<br>DELETED';
  1209. }
  1210. else if(changed)
  1211. {
  1212. if(camObj.currentType != camObj.watchType)
  1213. {
  1214. iHTML += '<br>&nbsp;&nbsp;Type changed';
  1215. iHTML += ' ('+camObj.watchType+' to '+camObj.currentType+')';
  1216. }
  1217. if(camObj.currentAzymuth != camObj.watchAzymuth)
  1218. {
  1219. iHTML += '<br>&nbsp;&nbsp;Azimuth changed';
  1220. iHTML += ' ('+camObj.watchAzymuth+' to '+camObj.currentAzymuth+')';
  1221. }
  1222. if(camObj.currentSpeed != camObj.watchSpeed)
  1223. {
  1224. iHTML += '<br>&nbsp;&nbsp;Speed changed';
  1225. iHTML += ' ('+camObj.watchSpeed+' to '+camObj.currentSpeed+')';
  1226. }
  1227. if(camObj.currentValidated != camObj.watchValidated)
  1228. {
  1229. iHTML += '<br>&nbsp;&nbsp;Approval state changed';
  1230. iHTML += ' ('+camObj.watchValidated+' to '+camObj.currentValidated+')';
  1231. }
  1232. if(camObj.currentLat != camObj.watchLat)
  1233. {
  1234. iHTML += '<br>&nbsp;&nbsp;Latitude changed';
  1235. iHTML += ' ('+camObj.watchLat+' to '+camObj.currentLat+')';
  1236. }
  1237. if(camObj.currentLon != camObj.watchLon)
  1238. {
  1239. iHTML += '<br>&nbsp;&nbsp;Longitude changed';
  1240. iHTML += ' ('+camObj.watchLon+' to '+camObj.currentLon+')';
  1241. }
  1242. }
  1243. if(camObj.server == W.location.code)
  1244. {
  1245. if(deleted == false)
  1246. {
  1247. iHTML += '&nbsp;<img id="_uroCWLIcon1-'+camidx+'" src="'+uroIcons[1][1]+'">';
  1248. }
  1249. iHTML += '&nbsp;<img id="_uroCWLIcon2-'+camidx+'" src="'+uroIcons[2][1]+'">';
  1250. }
  1251. iHTML += '</div>';
  1252. }
  1253. }
  1254. iHTML += '</div>';
  1255. }
  1256. iHTML += '</div><div id="_uroCWLControls">';
  1257. iHTML += '<hr>Group control:<br>';
  1258. iHTML += '<select id="_uroCWLGroupSelect" style="width:40%;height:22px;"></select>&nbsp;<input type="button" id="_btnCWLGroupDel" value="Delete group"><br>';
  1259. iHTML += '<input type="text" id="_uroCWLGroupEntry" style="width:40%;height:22px;">&nbsp;<input type="button" id="_btnCWLGroupAdd" value="Add group">';
  1260. iHTML += '<br><input type="button" id="_btnRescanCamWatchList" value="Refresh Camera Data"><br><br>';
  1261. iHTML += '<b>Remove cameras from CWL:</b><br>';
  1262. iHTML += '<input type="button" id="_btnRemoveDeletedCameras" value="Deleted">&nbsp;&nbsp;';
  1263. iHTML += '<input type="button" id="_btnRemoveUnknownServerCameras" value="Unknown Server">&nbsp;&nbsp;';
  1264. iHTML += '<input type="button" id="_btnClearCamWatchList" value="ALL Cameras">';
  1265. iHTML += '</div>';
  1266. uroCamWatchlist.innerHTML = iHTML;
  1267. for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
  1268. {
  1269. document.getElementById("_uroCWL-"+camidx).onmouseover = uroHighlightCWLEntry;
  1270. document.getElementById("_uroCWL-"+camidx).onmouseleave = uroUnhighlightCWLEntry;
  1271.  
  1272. if(uroCamWatchObjects[camidx].server == W.location.code)
  1273. {
  1274. var icon1 = document.getElementById("_uroCWLIcon1-"+camidx);
  1275. var icon2 = document.getElementById("_uroCWLIcon2-"+camidx);
  1276. if(icon1 != null)
  1277. {
  1278. icon1.onmouseover = uroCWLIconHighlight;
  1279. icon1.onmouseleave = uroCWLIconLowlight;
  1280. icon1.onclick = uroAssignCameraToGroup;
  1281. }
  1282. if(icon2 != null)
  1283. {
  1284. icon2.onmouseover = uroCWLIconHighlight;
  1285. icon2.onmouseleave = uroCWLIconLowlight;
  1286. icon2.onclick = uroGotoCam;
  1287. }
  1288. }
  1289. }
  1290. uroAddBtnEvl('_btnClearCamWatchList', 'click', uroClearCamWatchList);
  1291. uroAddBtnEvl('_btnRemoveDeletedCameras', 'click', uroClearDeletedCameras);
  1292. uroAddBtnEvl('_btnRemoveUnknownServerCameras', 'click', uroClearUnknownServerCameras);
  1293. uroAddBtnEvl('_btnRescanCamWatchList', 'click', uroRescanCamWatchList);
  1294. uroAddBtnEvl('_btnCWLGroupDel', 'click', uroRemoveCWLGroup);
  1295. uroAddBtnEvl('_btnCWLGroupAdd', 'click', uroAddCWLGroup);
  1296. if(document.getElementById('_uroCWLGroupSelect') != null)
  1297. {
  1298. uroAddLog('populating CWL group list');
  1299. uroPopulateCWLGroupSelect();
  1300. var selector = document.getElementById('_uroCWLGroupSelect');
  1301. if(selectedGroup >= selector.length)
  1302. {
  1303. selectedGroup = 0;
  1304. }
  1305. selector.selectedIndex = selectedGroup;
  1306. }
  1307.  
  1308. for(var groupidx=0;groupidx<uroCWLGroups.length;groupidx++)
  1309. {
  1310. if(uroCWLGroups[groupidx].groupCount == 0)
  1311. {
  1312. uroSetStyleDisplay('_uroCWLGroup-'+groupidx,'none');
  1313. }
  1314. else
  1315. {
  1316. uroSetOnClick('_uroCWLGroupState-'+groupidx,uroCWLGroupCollapseExpand);
  1317. }
  1318. }
  1319. }
  1320.  
  1321.  
  1322. function uroIsOnIgnoreList(fid)
  1323. {
  1324. if(sessionStorage.UROverview_FID_IgnoreList.indexOf('fid:'+fid) == -1) return false;
  1325. else return true;
  1326. }
  1327.  
  1328. function uroEnableIgnoreListControls()
  1329. {
  1330. var btnState = false;
  1331. if(sessionStorage.UROverview_FID_IgnoreList == '')
  1332. {
  1333. btnState = true;
  1334. }
  1335. document.getElementById('_btnUndoLastHide').disabled = btnState;
  1336. document.getElementById('_btnClearSessionHides').disabled = btnState;
  1337. uroFilterItems();
  1338. }
  1339.  
  1340. function uroAddToIgnoreList()
  1341. {
  1342. if(!uroIsOnIgnoreList(uroShownFID))
  1343. {
  1344. sessionStorage.UROverview_FID_IgnoreList += 'fid:'+uroShownFID;
  1345. uroAddLog('added fid '+uroShownFID+' to ignore list');
  1346. uroAddLog(sessionStorage.UROverview_FID_IgnoreList);
  1347. document.getElementById('_btnUndoLastHide').disabled = false;
  1348. document.getElementById('_btnClearSessionHides').disabled = false;
  1349. uroDiv.style.visibility = 'hidden';
  1350. uroEnableIgnoreListControls();
  1351. W.map.events.register("mousemove", null, uroFilterItemsOnMove);
  1352. }
  1353. return false;
  1354. }
  1355.  
  1356. function uroRemoveFromIgnoreList(fid)
  1357. {
  1358. var ignorelist = sessionStorage.UROverview_FID_IgnoreList;
  1359. var fidpos = ignorelist.indexOf('fid:'+fid);
  1360. if(fidpos != -1)
  1361. {
  1362. var preFID = ignorelist.slice(0,fidpos);
  1363. ignorelist = ignorelist.slice(fidpos+1);
  1364. fidpos = ignorelist.indexOf('fid:');
  1365. if(fidpos == -1) ignorelist = '';
  1366. else ignorelist = ignorelist.slice(fidpos);
  1367. sessionStorage.UROverview_FID_IgnoreList = preFID + ignorelist;
  1368. uroAddLog('removed fid '+fid+' from ignore list');
  1369. uroAddLog(sessionStorage.UROverview_FID_IgnoreList);
  1370. uroEnableIgnoreListControls();
  1371. }
  1372. }
  1373.  
  1374. function uroRemoveLastAddedIgnore()
  1375. {
  1376. var ignorelist = sessionStorage.UROverview_FID_IgnoreList;
  1377. var fidpos = ignorelist.lastIndexOf('fid:');
  1378. if(fidpos != -1)
  1379. {
  1380. ignorelist = ignorelist.slice(0,fidpos);
  1381. sessionStorage.UROverview_FID_IgnoreList = ignorelist;
  1382. uroAddLog('removed last fid from ignore list');
  1383. uroAddLog(sessionStorage.UROverview_FID_IgnoreList);
  1384. uroEnableIgnoreListControls();
  1385. }
  1386. }
  1387.  
  1388. function uroRemoveAllIgnores()
  1389. {
  1390. sessionStorage.UROverview_FID_IgnoreList = '';
  1391. uroEnableIgnoreListControls();
  1392. }
  1393.  
  1394.  
  1395. function uroKeywordPresent(desc, keyword)
  1396. {
  1397. if(uroGetCBChecked('_cbCaseInsensitive') == true) re = RegExp(keyword,'i');
  1398. else re = RegExp(keyword);
  1399. if(desc.search(re) == -1) return false;
  1400. else return true;
  1401. }
  1402.  
  1403.  
  1404. function uroClickify(desc)
  1405. {
  1406. var linkStartPos = desc.indexOf('http://');
  1407. if(linkStartPos == -1) linkStartPos = desc.indexOf('https://');
  1408. if(linkStartPos != -1)
  1409. {
  1410. var descPreLink = desc.slice(0,linkStartPos);
  1411. var descURL = desc.slice(linkStartPos);
  1412. var linkEndPos = descURL.indexOf(' ');
  1413. var descPostLink = '';
  1414. if(linkEndPos != -1)
  1415. {
  1416. descPostLink = descURL.slice(linkEndPos);
  1417. descURL = descURL.slice(0,linkEndPos);
  1418. }
  1419. var linkTarget = '';
  1420. if(descURL.indexOf('cryosphere') != -1) linkTarget = '_cryosphere';
  1421. else if(descURL.indexOf('waze.com') != -1) linkTarget = '_wazeUR';
  1422. desc = descPreLink + '<a target="'+linkTarget+'" href="'+descURL+'">here</a>' + descPostLink;
  1423. }
  1424. return desc;
  1425. }
  1426.  
  1427.  
  1428. function uroMaskTest()
  1429. {
  1430. if(W.map.layers[uroMaskLayer].div == null)
  1431. {
  1432. if(uroMaskActive == false)
  1433. {
  1434. uroAddLog('mask layer not found');
  1435. uroMaskActive = true;
  1436. }
  1437. return true;
  1438. }
  1439. if(W.map.layers[uroMaskLayer].div.innerHTML.indexOf('fill="black"') != -1)
  1440. {
  1441. if(uroMaskActive == false)
  1442. {
  1443. uroAddLog('mask layer active');
  1444. uroMaskActive = true;
  1445. }
  1446. return true;
  1447. }
  1448. uroMaskActive = false;
  1449. return false;
  1450. }
  1451.  
  1452.  
  1453. function uroRefreshUpdateRequestSessions()
  1454. {
  1455. var idList = [];
  1456. for (var urID in W.model.mapUpdateRequests.objects)
  1457. {
  1458. if(W.model.updateRequestSessions.objects[urID] == null) idList.push(urID);
  1459. }
  1460. if(idList.length > 0)
  1461. {
  1462. uroAddLog('grabbing updateRequestSessions with IDs '+idList);
  1463. W.model.updateRequestSessions.get(idList);
  1464. }
  1465. }
  1466.  
  1467. function uroURHasMyComments(fid)
  1468. {
  1469. var nComments = W.model.updateRequestSessions.objects[fid].comments.length;
  1470. if(nComments == 0) return false;
  1471.  
  1472. for(var cidx=0; cidx<nComments; cidx++)
  1473. {
  1474. if(W.model.updateRequestSessions.objects[fid].comments[cidx].userID == uroUserID) return true;
  1475. }
  1476. return false;
  1477. }
  1478.  
  1479. function uroACMObj(urID, customType, hasMyComments, nComments)
  1480. {
  1481. this.urID = urID;
  1482. this.customType = customType;
  1483. this.hasMyComments = hasMyComments;
  1484. this.nComments = nComments;
  1485. }
  1486.  
  1487. function uroAddCustomMarkers(urID, customType, hasMyComments, nComments)
  1488. {
  1489. var useCustomMarker = false;
  1490.  
  1491. if(customType == 0) useCustomMarker = (uroGetCBChecked('_cbCustomRoadworksMarkers'));
  1492. else if(customType == 1) useCustomMarker = (uroGetCBChecked('_cbCustomConstructionMarkers'));
  1493. else if(customType == 2) useCustomMarker = (uroGetCBChecked('_cbCustomClosuresMarkers'));
  1494. else if(customType == 3) useCustomMarker = (uroGetCBChecked('_cbCustomEventsMarkers'));
  1495. else if(customType == 4) useCustomMarker = (uroGetCBChecked('_cbCustomNotesMarkers'));
  1496. if(!useCustomMarker) customType = -1;
  1497. uroCustomMarkerList.push(new uroACMObj(urID, customType, hasMyComments, nComments));
  1498. }
  1499.  
  1500. function uroRenderCustomMarkers()
  1501. {
  1502. var markersToAdd = uroCustomMarkerList.length;
  1503. var useDefaultConvoMarker = false;
  1504. if((uroGetCBChecked('_cbNativeConvoMarkers')) && (uroBetaEditor == false)) useDefaultConvoMarker = true;
  1505. if((uroGetCBChecked('_cbNativeBetaConvoMarkers')) && (uroBetaEditor == true)) useDefaultConvoMarker = true;
  1506. var divElem = document.getElementById(W.map.layers[uroURLayerIdx].id);
  1507. if(divElem.childNodes.length > 0)
  1508. {
  1509. for(var nodeIdx = 0; nodeIdx < divElem.childNodes.length; nodeIdx++)
  1510. {
  1511. for(var objIdx = 0; objIdx < uroCustomMarkerList.length; objIdx++)
  1512. {
  1513. var urID = uroCustomMarkerList[objIdx].urID;
  1514. var customType = uroCustomMarkerList[objIdx].customType;
  1515. var hasMyComments = uroCustomMarkerList[objIdx].hasMyComments;
  1516. var nComments = uroCustomMarkerList[objIdx].nComments;
  1517. if(divElem.childNodes[nodeIdx].getAttribute("data-id") == urID)
  1518. {
  1519. var divHTML = '';
  1520. if(customType != -1)
  1521. {
  1522. divHTML += '<div id="customMarker_'+urID+'" style="position:absolute;pointer-events:none;">';
  1523. customType = uroGetCustomMarkerIdx(customType);
  1524. if(W.model.updateRequestSessions.objects[urID] != undefined)
  1525. {
  1526. if(W.model.updateRequestSessions.objects[urID].open == false) customType += 1;
  1527. }
  1528. divHTML += '<img src="'+uroIcons[customType][0]+'">';
  1529. divHTML += '</div>';
  1530. }
  1531. if(nComments > 0)
  1532. {
  1533. if(uroGetCBChecked('_cbCommentCount'))
  1534. {
  1535. divHTML += '<div style="position:absolute;top:-9px;left:-11px;pointer-events:none;">';
  1536. divHTML += '<img src="'+uroMarkers[0]+'">';
  1537. divHTML += '</div>';
  1538. divHTML += '<div style="position:absolute;top:-6px;left:-';
  1539. if(nComments < 10) divHTML += '0';
  1540. else if(nComments < 100) divHTML += '3';
  1541. else divHTML += '6';
  1542. divHTML += 'px;font-size:11px;;pointer-events:none;">'+nComments+'</div>';
  1543. }
  1544.  
  1545. if(useDefaultConvoMarker == false)
  1546. {
  1547. divHTML += '<div style="position:absolute;top:-9px;left:18px;pointer-events:none;">';
  1548. if(hasMyComments) divHTML += '<img src="'+uroMarkers[2]+'">';
  1549. else divHTML += '<img src="'+uroMarkers[1]+'">';
  1550. divHTML += '</div>';
  1551. W.map.layers[uroURLayerIdx].markers[urID].icon.imageDiv.classList.remove("has-comments")
  1552. }
  1553. else
  1554. {
  1555. W.map.layers[uroURLayerIdx].markers[urID].icon.imageDiv.classList.add("has-comments")
  1556. }
  1557. }
  1558. divElem.childNodes[nodeIdx].innerHTML = divHTML;
  1559.  
  1560. if(--markersToAdd == 0)
  1561. {
  1562. return;
  1563. }
  1564. }
  1565. }
  1566. }
  1567. }
  1568. }
  1569.  
  1570.  
  1571. function uroChangeCustomMarkers(urID,isHighlighted,customType)
  1572. {
  1573. if(document.getElementById('customMarker_'+urID) != null)
  1574. {
  1575. if(W.model.updateRequestSessions.objects[urID].open == false) customType += 1;
  1576.  
  1577. if(isHighlighted == true)
  1578. {
  1579. document.getElementById('customMarker_'+urID).innerHTML = '<img src="'+uroIcons[customType][1]+'">';
  1580. }
  1581. else
  1582. {
  1583. document.getElementById('customMarker_'+urID).innerHTML = '<img src="'+uroIcons[customType][0]+'">';
  1584. }
  1585. }
  1586. }
  1587.  
  1588. function uroFilterPlaces()
  1589. {
  1590. if(uroFilterPreamble() == false) return;
  1591. if(uroPlaceSelected == true) return;
  1592. if(uroGetCBChecked('_cbDisablePlacesFiltering') == true) return;
  1593. var filterCats = [];
  1594. for(var i=0; i<W.Config.venues.categories.length; i++)
  1595. {
  1596. parentCategory = W.Config.venues.categories[i];
  1597. if(uroGetCBChecked('_cbPlacesFilter-'+parentCategory) == true)
  1598. {
  1599. filterCats.push(parentCategory);
  1600. for(var ii=0; ii<W.Config.venues.subcategories[parentCategory].length; ii++)
  1601. {
  1602. subCategory = W.Config.venues.subcategories[parentCategory][ii];
  1603. filterCats.push(subCategory);
  1604. }
  1605. }
  1606. else
  1607. {
  1608. for(var ii=0; ii<W.Config.venues.subcategories[parentCategory].length; ii++)
  1609. {
  1610. subCategory = W.Config.venues.subcategories[parentCategory][ii];
  1611. if(uroGetCBChecked('_cbPlacesFilter-'+subCategory) == true)
  1612. {
  1613. filterCats.push(subCategory);
  1614. }
  1615. }
  1616. }
  1617. }
  1618.  
  1619. for(var v=0; v<W.map.landmarkLayer.features.length; v++)
  1620. {
  1621. placeStyle = 'visible';
  1622. lmObj = W.map.landmarkLayer.features[v];
  1623. // when an area place is selected, the drag points for editing the place outline now get added as objects into W.map.landmarkLayer.features,
  1624. // however none of these objects have the .model property - we must therefore check each entry in features[] to see if it has .model before
  1625. // attempting to filter it...
  1626. if(lmObj.model != undefined)
  1627. {
  1628. editDate = lmObj.model.attributes.updatedOn;
  1629. if(editDate == undefined)
  1630. {
  1631. // where a place has never been edited since its creation, use the creation date instead...
  1632. editDate = lmObj.model.attributes.createdOn;
  1633. }
  1634. if(editDate != undefined)
  1635. {
  1636. editDaysAgo = uroDateToDays(editDate);
  1637. if(uroGetCBChecked('_cbPlaceFilterEditedLessThan'))
  1638. {
  1639. if(editDaysAgo < document.getElementById('_inputFilterPlaceEditMinDays').value)
  1640. {
  1641. placeStyle = 'hidden';
  1642. }
  1643. }
  1644. if(uroGetCBChecked('_cbPlaceFilterEditedMoreThan'))
  1645. {
  1646. if(editDaysAgo > document.getElementById('_inputFilterPlaceEditMaxDays').value)
  1647. {
  1648. placeStyle = 'hidden';
  1649. }
  1650. }
  1651. }
  1652. if(placeStyle == 'visible')
  1653. {
  1654. lockLevel = lmObj.model.attributes.lockRank;
  1655. if ((uroGetCBChecked('_cbHidePlacesL0')) && (lockLevel == 0)) placeStyle = 'hidden';
  1656. if ((uroGetCBChecked('_cbHidePlacesL1')) && (lockLevel == 1)) placeStyle = 'hidden';
  1657. if ((uroGetCBChecked('_cbHidePlacesL2')) && (lockLevel == 2)) placeStyle = 'hidden';
  1658. if ((uroGetCBChecked('_cbHidePlacesL3')) && (lockLevel == 3)) placeStyle = 'hidden';
  1659. if ((uroGetCBChecked('_cbHidePlacesL4')) && (lockLevel == 4)) placeStyle = 'hidden';
  1660. if ((uroGetCBChecked('_cbHidePlacesL5')) && (lockLevel == 5)) placeStyle = 'hidden';
  1661. }
  1662. if(placeStyle == 'visible')
  1663. {
  1664. nPhotos = 0;
  1665. for(var loop=0; loop<lmObj.model.attributes.images.length; loop++)
  1666. {
  1667. if(lmObj.model.attributes.images[loop].attributes.approved) nPhotos++;
  1668. }
  1669. if((uroGetCBChecked('_cbHideNoPhotoPlaces')) && (nPhotos == 0)) placeStyle = 'hidden';
  1670. if((uroGetCBChecked('_cbHidePhotoPlaces')) && (nPhotos != 0)) placeStyle = 'hidden';
  1671. }
  1672. if(placeStyle == 'visible')
  1673. {
  1674. if((lmObj.model.attributes.residential == true) && (uroGetCBChecked('_cbFilterPrivatePlaces') == true))
  1675. {
  1676. placeStyle = 'hidden';
  1677. }
  1678. else
  1679. {
  1680. for(var cat=0; cat<filterCats.length; cat++)
  1681. {
  1682. if(lmObj.model.attributes.categories.contains(filterCats[cat]))
  1683. {
  1684. placeStyle = 'hidden';
  1685. break;
  1686. }
  1687. }
  1688. }
  1689. }
  1690. }
  1691. if(uroGetCBChecked('_cbInvertPlacesFilter') == true)
  1692. {
  1693. if(placeStyle == 'hidden') placeStyle = 'visible';
  1694. else placeStyle = 'hidden';
  1695. }
  1696. geoID = W.map.landmarkLayer.features[v].geometry.id;
  1697. // area places...
  1698. if(document.getElementById(uroPlacesRoot).getElementsByTagName('path')[geoID] != null)
  1699. {
  1700. document.getElementById(uroPlacesRoot).getElementsByTagName('path')[geoID].style.visibility = placeStyle;
  1701. }
  1702. // point places...
  1703. if(document.getElementById(uroPlacesRoot).getElementsByTagName('circle')[geoID] != null)
  1704. {
  1705. document.getElementById(uroPlacesRoot).getElementsByTagName('circle')[geoID].style.visibility = placeStyle;
  1706. }
  1707.  
  1708. }
  1709.  
  1710. for(var pu in W.map.placeUpdatesLayer.markers)
  1711. {
  1712. puObj = W.map.placeUpdatesLayer.markers[pu];
  1713. if(W.map.placeUpdatesLayer.getVisibility() == true)
  1714. {
  1715. placeStyle = 'visible';
  1716. if(uroGetCBChecked('_cbFilterUneditablePlaceUpdates') == true)
  1717. {
  1718. if(puObj.model.attributes.permissions == 0)
  1719. {
  1720. placeStyle = 'hidden';
  1721. }
  1722. if(W.model.loginManager.isLoggedIn())
  1723. {
  1724. if(W.model.loginManager.user.rank < puObj.model.attributes.lockRank)
  1725. {
  1726. placeStyle = 'hidden';
  1727. }
  1728. }
  1729. }
  1730. if(uroGetCBChecked('_cbFilterLockRankedPlaceUpdates') == true)
  1731. {
  1732. if(puObj.model.attributes.lockRank != 0)
  1733. {
  1734. placeStyle = 'hidden';
  1735. }
  1736. }
  1737. if(uroGetCBChecked("_cbFilterFlaggedPUR") == true)
  1738. {
  1739. if(puObj.icon.imageDiv.className.indexOf('flag') != -1)
  1740. {
  1741. placeStyle = 'hidden';
  1742. }
  1743. }
  1744. if(uroGetCBChecked("_cbFilterNewPlacePUR") == true)
  1745. {
  1746. if(puObj.icon.imageDiv.className.indexOf('add_venue') != -1)
  1747. {
  1748. placeStyle = 'hidden';
  1749. }
  1750. }
  1751. if(uroGetCBChecked("_cbFilterUpdatedDetailsPUR") == true)
  1752. {
  1753. if((puObj.icon.imageDiv.className.indexOf('update_venue') != -1) || (puObj.icon.imageDiv.className.indexOf('multiple') != -1))
  1754. {
  1755. placeStyle = 'hidden';
  1756. }
  1757. }
  1758. if(uroGetCBChecked("_cbFilterNewPhotoPUR") == true)
  1759. {
  1760. if(puObj.icon.imageDiv.className.indexOf('add_image') != -1)
  1761. {
  1762. placeStyle = 'hidden';
  1763. }
  1764. }
  1765.  
  1766. if(uroGetCBChecked('_cbInvertPURFilters') == true)
  1767. {
  1768. if(placeStyle == 'hidden') placeStyle = 'visible';
  1769. else placeStyle = 'hidden';
  1770. }
  1771. puObj.icon.imageDiv.style.visibility = placeStyle;
  1772. if(uroGetCBChecked('_cbLeavePURGeos') == false)
  1773. {
  1774. if(puObj.model != undefined)
  1775. {
  1776. if(puObj.model.geometry != undefined)
  1777. {
  1778. puGeo = document.getElementById(puObj.model.geometry.id);
  1779. if(puGeo != null)
  1780. {
  1781. puGeo.style.visibility = placeStyle;
  1782. }
  1783. }
  1784. }
  1785. }
  1786. }
  1787. }
  1788. }
  1789.  
  1790. function uroFilterCameras()
  1791. {
  1792. if(uroFilterPreamble() == false) return;
  1793. var camLayer = document.getElementById(uroRootContainer+'_svgRoot');
  1794. if(camLayer == null)
  1795. {
  1796. if(uroNullCamLayer == false)
  1797. {
  1798. uroAddLog('caught null camLayer');
  1799. uroNullCamLayer = true;
  1800. }
  1801. return;
  1802. }
  1803. uroNullCamLayer = false;
  1804. if(uroMouseIsDown == false) W.map.camerasLayer.redraw();
  1805. for (var uroCamObj in W.model.cameras.objects)
  1806. {
  1807. var uroCam = W.model.cameras.objects[uroCamObj];
  1808. var uroCamStyle = 'visible';
  1809. if(W.model.users.objects[uroCam.attributes.createdBy] != null)
  1810. {
  1811. var uroCamCreator = W.model.users.objects[uroCam.attributes.createdBy].userName;
  1812. var uroCamCreatorRank = W.model.users.objects[uroCam.attributes.createdBy].rank;
  1813. }
  1814. else
  1815. {
  1816. var uroCamCreator = '';
  1817. var uroCamCreatorRank = -1;
  1818. }
  1819. if(W.model.users.objects[uroCam.attributes.updatedBy] != null)
  1820. {
  1821. var uroCamUpdater = W.model.users.objects[uroCam.attributes.updatedBy].userName;
  1822. var uroCamUpdaterRank = W.model.users.objects[uroCam.attributes.updatedBy].rank;
  1823. }
  1824. else
  1825. {
  1826. var uroCamUpdater = '';
  1827. var uroCamUpdaterRank = -1;
  1828. }
  1829.  
  1830. var uroCamApproved = uroCam.attributes.validated;
  1831. var uroCamType = uroCam.attributes.type;
  1832.  
  1833.  
  1834. if(uroGetCBChecked('_cbShowOnlyMyCams') == true)
  1835. {
  1836. if((uroUserID != uroCam.attributes.createdBy)&&(uroUserID != uroCam.attributes.updatedBy)) uroCamStyle = 'hidden';
  1837. }
  1838.  
  1839. if((uroGetCBChecked('_cbShowWorldCams') == false) || (uroGetCBChecked('_cbShowUSACams') == false) || (uroGetCBChecked('_cbShowNonWorldCams') == false))
  1840. {
  1841. var posWorld = uroCamCreator.indexOf('world_');
  1842. var posUSA = uroCamCreator.indexOf('usa_');
  1843.  
  1844. if((uroGetCBChecked('_cbShowWorldCams') == false) && (posWorld == 0)) uroCamStyle = 'hidden';
  1845. if((uroGetCBChecked('_cbShowUSACams') == false) && (posUSA == 0)) uroCamStyle = 'hidden';
  1846. if((uroGetCBChecked('_cbShowNonWorldCams') == false) && (posWorld != 0) && (posUSA != 0)) uroCamStyle = 'hidden';
  1847. }
  1848.  
  1849. if((uroGetCBChecked('_cbShowApprovedCams') == false) || (uroGetCBChecked('_cbShowNonApprovedCams') == false))
  1850. {
  1851. if((uroGetCBChecked('_cbShowApprovedCams') == false) && (uroCamApproved == true)) uroCamStyle = 'hidden';
  1852. if((uroGetCBChecked('_cbShowNonApprovedCams') == false) && (uroCamApproved == false)) uroCamStyle = 'hidden';
  1853. }
  1854.  
  1855. if((uroGetCBChecked('_cbShowNonApprovedCams') == true) && (uroCamApproved == false))
  1856. {
  1857. if(((uroGetCBChecked('_cbShowOlderCreatedNonApproved') == true)) && (uroGetCameraAge(uroCam,1) <= uroGetElmValue('_inputCameraMinCreatedDays'))) uroCamStyle = 'hidden';
  1858. if(((uroGetCBChecked('_cbShowOlderUpdatedNonApproved') == true)) && (uroGetCameraAge(uroCam,0) <= uroGetElmValue('_inputCameraMinUpdatedDays'))) uroCamStyle = 'hidden';
  1859. }
  1860.  
  1861. if((uroGetCBChecked('_cbShowSpeedCams') == false) || (uroGetCBChecked('_cbShowRedLightCams') == false) || (uroGetCBChecked('_cbShowDummyCams') == false))
  1862. {
  1863. if((uroGetCBChecked('_cbShowSpeedCams') == false) && (uroCamType == 2)) uroCamStyle = 'hidden';
  1864. if((uroGetCBChecked('_cbShowRedLightCams') == false) && (uroCamType == 4)) uroCamStyle = 'hidden';
  1865. if((uroGetCBChecked('_cbShowDummyCams') == false) && (uroCamType == 3)) uroCamStyle = 'hidden';
  1866. }
  1867.  
  1868. if(uroGetCBChecked('_cbShowSpeedCams') == true)
  1869. {
  1870. if((uroGetCBChecked('_cbShowIfMPHSpeedSet') == false) && (uroIsCameraSpeedValid(uroCam) == 1)) uroCamStyle = 'hidden';
  1871. if((uroGetCBChecked('_cbShowIfNoSpeedSet') == false) && (uroIsCameraSpeedValid(uroCam) == 0)) uroCamStyle = 'hidden';
  1872. if((uroGetCBChecked('_cbShowIfKPHSpeedSet') == false) && (uroIsCameraSpeedValid(uroCam) == -1)) uroCamStyle = 'hidden';
  1873. }
  1874.  
  1875. if(uroGetCBChecked('_cbHideCreatedByMe') == true)
  1876. {
  1877. if(uroUserID == uroCam.attributes.createdBy) uroCamStyle = 'hidden';
  1878. }
  1879. if((uroGetCBChecked('_cbHideCreatedByRank0') == true) && (uroCamCreatorRank == 0)) uroCamStyle = 'hidden';
  1880. if((uroGetCBChecked('_cbHideCreatedByRank1') == true) && (uroCamCreatorRank == 1)) uroCamStyle = 'hidden';
  1881. if((uroGetCBChecked('_cbHideCreatedByRank2') == true) && (uroCamCreatorRank == 2)) uroCamStyle = 'hidden';
  1882. if((uroGetCBChecked('_cbHideCreatedByRank3') == true) && (uroCamCreatorRank == 3)) uroCamStyle = 'hidden';
  1883. if((uroGetCBChecked('_cbHideCreatedByRank4') == true) && (uroCamCreatorRank == 4)) uroCamStyle = 'hidden';
  1884. if((uroGetCBChecked('_cbHideCreatedByRank5') == true) && (uroCamCreatorRank == 5)) uroCamStyle = 'hidden';
  1885.  
  1886. if(uroGetCBChecked('_cbHideUpdatedByMe') == true)
  1887. {
  1888. if(uroUserID == uroCam.attributes.updatedBy) uroCamStyle = 'hidden';
  1889. }
  1890. if((uroGetCBChecked('_cbHideUpdatedByRank0') == true) && (uroCamUpdaterRank == 0)) uroCamStyle = 'hidden';
  1891. if((uroGetCBChecked('_cbHideUpdatedByRank1') == true) && (uroCamUpdaterRank == 1)) uroCamStyle = 'hidden';
  1892. if((uroGetCBChecked('_cbHideUpdatedByRank2') == true) && (uroCamUpdaterRank == 2)) uroCamStyle = 'hidden';
  1893. if((uroGetCBChecked('_cbHideUpdatedByRank3') == true) && (uroCamUpdaterRank == 3)) uroCamStyle = 'hidden';
  1894. if((uroGetCBChecked('_cbHideUpdatedByRank4') == true) && (uroCamUpdaterRank == 4)) uroCamStyle = 'hidden';
  1895. if((uroGetCBChecked('_cbHideUpdatedByRank5') == true) && (uroCamUpdaterRank == 5)) uroCamStyle = 'hidden';
  1896.  
  1897. if((uroGetCBChecked('_cbHideCWLCams') == true) && (uroIsCamOnWatchList(uroCam.attributes.id) != -1)) uroCamStyle = 'hidden';
  1898.  
  1899. var uroCamGeometryID = uroCam.geometry.id;
  1900. if(camLayer.getElementById(uroCamGeometryID) != null)
  1901. {
  1902. var camX = parseInt(camLayer.getElementById(uroCamGeometryID).getAttribute('x'));
  1903. if(uroCamStyle == "hidden")
  1904. {
  1905. camLayer.getElementById(uroCamGeometryID).remove();
  1906. }
  1907. }
  1908. }
  1909. }
  1910.  
  1911. function uroFilterURs_onObjectsChanged()
  1912. {
  1913. if(uroBackfilling == false)
  1914. {
  1915. console.log('uroFilterURs_onObjectsChanged');
  1916. uroURBackfill();
  1917. uroFilterURs();
  1918. }
  1919. }
  1920. function uroFilterURs_onObjectsAdded()
  1921. {
  1922. if(uroBackfilling == false)
  1923. {
  1924. console.log('uroFilterURs_onObjectsAdded');
  1925. uroURBackfill();
  1926. uroFilterURs();
  1927. }
  1928. }
  1929. function uroFilterURs_onObjectsRemoved()
  1930. {
  1931. if(uroBackfilling == false)
  1932. {
  1933. console.log('uroFilterURs_onObjectsRemoved');
  1934. uroURBackfill();
  1935. uroFilterURs();
  1936. }
  1937. }
  1938.  
  1939. function uroURBackfill_GetData(lon, lat, blockSize)
  1940. {
  1941. lon = parseFloat(lon);
  1942. lat = parseFloat(lat);
  1943. blockSize = parseFloat(blockSize);
  1944. var xmlReq = new XMLHttpRequest();
  1945. var tURL = 'https://' + document.location.host;
  1946. tURL += Waze.Config.api_base;
  1947. tURL += '/Features?language=en&mapUpdateRequestFilter=0';
  1948. if(uroPracticeMode == true) tURL += '&sandbox=true';
  1949. tURL += '&bbox='+(lon)+','+(lat)+','+(lon + blockSize)+','+(lat + blockSize);
  1950. xmlReq.open('GET',tURL,false);
  1951. try
  1952. {
  1953. xmlReq.send();
  1954. uroAddLog('response '+xmlReq.status+' received');
  1955. if (xmlReq.status === 200)
  1956. {
  1957. var tResp = JSON.parse(xmlReq.responseText);
  1958. var urCount = tResp.mapUpdateRequests.objects.length;
  1959. uroAddLog(urCount+' URs loaded for backfill processing');
  1960. if(urCount == 500)
  1961. {
  1962. uroAddLog('WARNING - backfill data may have been pre-filtered by server');
  1963. }
  1964.  
  1965. var backfilled = 0;
  1966. for(var i=0; i<urCount; i++)
  1967. {
  1968. var urID = tResp.mapUpdateRequests.objects[i].id;
  1969. if(W.model.mapUpdateRequests.objects[urID] == undefined)
  1970. {
  1971. uroAddLog('backfilling '+urID);
  1972. var newUR = require('Waze/Feature/Vector/UpdateRequest');
  1973. var tUR = new newUR(tResp.mapUpdateRequests.objects[i]);
  1974. var tPoint = new OpenLayers.Geometry.Point();
  1975. tPoint.x = tResp.mapUpdateRequests.objects[i].geometry.coordinates[0];
  1976. tPoint.y = tResp.mapUpdateRequests.objects[i].geometry.coordinates[1];
  1977. tPoint.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
  1978. tUR.geometry = tPoint;
  1979. W.model.mapUpdateRequests.put(tUR);
  1980. backfilled++;
  1981. }
  1982. }
  1983.  
  1984. uroAddLog(backfilled+' URs backfilled');
  1985. }
  1986. else
  1987. {
  1988. uroAddLog('request failed (status != 200)');
  1989. }
  1990. }
  1991. catch(err)
  1992. {
  1993. uroAddLog('UR backfill request failed (exception '+err+' caught)');
  1994. }
  1995. }
  1996. function uroURBackfill()
  1997. {
  1998. if(uroGetCBChecked('_cbURBackfill') == false)
  1999. {
  2000. return;
  2001. }
  2002. var nativeURCount = Object.keys(W.model.mapUpdateRequests.objects).length;
  2003. if(nativeURCount < 500)
  2004. {
  2005. return;
  2006. }
  2007.  
  2008. uroAddLog('exactly 500 URs loaded, possible server-side filtering requiring backfill...');
  2009. var centreLon = W.map.getCenter().transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326")).lon;
  2010. var centreLat = W.map.getCenter().transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326")).lat;
  2011. var subSize = 0.2;
  2012. uroBackfilling = true;
  2013. uroURBackfill_GetData(centreLon - subSize, centreLat - subSize, subSize);
  2014. uroURBackfill_GetData(centreLon, centreLat - subSize, subSize);
  2015. uroURBackfill_GetData(centreLon, centreLat, subSize);
  2016. uroURBackfill_GetData(centreLon - subSize, centreLat, subSize);
  2017. uroBackfilling = false;
  2018. uroFilterURs();
  2019. }
  2020.  
  2021.  
  2022. function uroFilterURs()
  2023. {
  2024. if(uroFilterPreamble() == false) return;
  2025. uroRefreshUpdateRequestSessions();
  2026. if(uroGetCBChecked('_cbURResolverIDFilter') == false)
  2027. {
  2028. var selector = document.getElementById('_selectURResolverID');
  2029. while(selector.options.length > 0)
  2030. {
  2031. selector.options.remove(0);
  2032. }
  2033. }
  2034. if(uroGetCBChecked('_cbURUserIDFilter') == false)
  2035. {
  2036. var selector = document.getElementById('_selectURUserID');
  2037. while(selector.options.length > 0)
  2038. {
  2039. selector.options.remove(0);
  2040. }
  2041. }
  2042. if(Object.keys(W.model.updateRequestSessions.objects).length == 0)
  2043. {
  2044. return;
  2045. }
  2046.  
  2047. if(uroGetCBChecked('_cbURUserIDFilter') == true)
  2048. {
  2049. var selector = document.getElementById('_selectURUserID');
  2050. if(selector.options.length == 0)
  2051. {
  2052. uroUpdateUserList();
  2053. }
  2054. }
  2055. if(uroGetCBChecked('_cbURResolverIDFilter') == true)
  2056. {
  2057. console.log('resolver checked');
  2058. var selector = document.getElementById('_selectURResolverID');
  2059. if(selector.options.length == 0)
  2060. {
  2061. console.log('build resolver list');
  2062. uroUpdateResolverList();
  2063. }
  2064. }
  2065. console.log('filtering urs');
  2066.  
  2067.  
  2068. uroCustomMarkerList = [];
  2069. if(uroGetCBChecked('_cbURResolverIDFilter') == true)
  2070. {
  2071. var selector = document.getElementById('_selectURResolverID');
  2072. var selectedUser = null;
  2073. if(selector.selectedOptions[0] != undefined)
  2074. {
  2075. selectedUser = parseInt(selector.selectedOptions[0].value);
  2076. }
  2077. }
  2078. for (var urobj in W.model.mapUpdateRequests.objects)
  2079. {
  2080. var ureq = W.model.mapUpdateRequests.objects[urobj];
  2081. var urStyle = 'visible';
  2082. var cryosphere_link = false;
  2083. var wazeauto_ur = false;
  2084. var ukroadworks_ur = false;
  2085. var construction_ur = false;
  2086. var closure_ur = false;
  2087. var event_ur = false;
  2088. var note_ur = false;
  2089. var hasMyComments = false;
  2090. var nComments = 0;
  2091. var commentDaysOld = -1;
  2092. var desc = '';
  2093. if(ureq.attributes.description != null) desc = ureq.attributes.description.replace(/<\/?[^>]+(>|$)/g, "");
  2094. var ureqID = null;
  2095. if(ureq.fid == null) ureqID = ureq.attributes.id;
  2096. else ureqID = ureq.fid;
  2097.  
  2098. var customType = uroGetCustomType(ureqID);
  2099. if(customType == 0) ukroadworks_ur = true;
  2100. else if(customType == 1) construction_ur = true;
  2101. else if(customType == 2) closure_ur = true;
  2102. else if(customType == 3) event_ur = true;
  2103. else if(customType == 4) note_ur = true;
  2104. // check UR against current session ignore list...
  2105. if(uroIsOnIgnoreList(ureqID)) urStyle = 'hidden';
  2106.  
  2107. // check against closed/not identified filtering if enabled...
  2108. if(uroGetCBChecked('_cbFilterSolved') == true)
  2109. {
  2110. if(ureq.attributes.resolution == 0) urStyle = 'hidden';
  2111. }
  2112. if(uroGetCBChecked('_cbFilterUnidentified') == true)
  2113. {
  2114. if(ureq.attributes.resolution == 1) urStyle = 'hidden';
  2115. }
  2116. if((ureq.attributes.resolvedOn != null) && (uroGetCBChecked('_cbFilterClosedUR') == true))
  2117. {
  2118. urStyle = 'hidden';
  2119. }
  2120.  
  2121. if((ureq.attributes.resolvedOn == null) && (uroGetCBChecked('_cbFilterOpenUR') == true))
  2122. {
  2123. urStyle = 'hidden';
  2124. }
  2125.  
  2126. if(urStyle == 'visible')
  2127. {
  2128. // check UR against keyword filtering if enabled...
  2129. if(uroGetCBChecked('_cbURDescriptionMustBePresent') == true)
  2130. {
  2131. if(desc == '') urStyle = 'hidden';
  2132. }
  2133. if(uroGetCBChecked('_cbURDescriptionMustBeAbsent') == true)
  2134. {
  2135. if(desc != '') urStyle = 'hidden';
  2136. }
  2137. if(uroGetCBChecked('_cbEnableKeywordMustBePresent') == true)
  2138. {
  2139. if(!uroKeywordPresent(desc,uroGetElmValue('_textKeywordPresent'))) urStyle = 'hidden';
  2140. }
  2141. if(uroGetCBChecked('_cbEnableKeywordMustBeAbsent') == true)
  2142. {
  2143. if(uroKeywordPresent(desc,uroGetElmValue('_textKeywordAbsent'))) urStyle = 'hidden';
  2144. }
  2145. }
  2146.  
  2147. if(urStyle == 'visible')
  2148. {
  2149. // do age-based filtering if enabled
  2150. if(uroGetCBChecked('_cbEnableMinAgeFilter') == true)
  2151. {
  2152. if(uroGetURAge(ureq,0) < uroGetElmValue('_inputFilterMinDays')) urStyle = 'hidden';
  2153. }
  2154. if(uroGetCBChecked('_cbEnableMaxAgeFilter') == true)
  2155. {
  2156. if(uroGetURAge(ureq,0) > uroGetElmValue('_inputFilterMaxDays')) urStyle = 'hidden';
  2157. }
  2158. }
  2159. if(urStyle == 'visible')
  2160. {
  2161. if(uroGetCBChecked('_cbURResolverIDFilter') == true)
  2162. {
  2163. if(ureq.attributes.resolvedBy != selectedUser) urStyle = 'hidden';
  2164. }
  2165. }
  2166. if(urStyle == 'visible')
  2167. {
  2168. // do comments/following filtering
  2169. if(W.model.updateRequestSessions.objects[ureqID] != null)
  2170. {
  2171. nComments = W.model.updateRequestSessions.objects[ureqID].comments.length;
  2172. var commentDaysOld = -1;
  2173. if(uroGetCBChecked('_cbEnableMinCommentsFilter') == true)
  2174. {
  2175. if(nComments < uroGetElmValue('_inputFilterMinComments')) urStyle = 'hidden';
  2176. }
  2177. if(uroGetCBChecked('_cbEnableMaxCommentsFilter') == true)
  2178. {
  2179. if(nComments > uroGetElmValue('_inputFilterMaxComments')) urStyle = 'hidden';
  2180. }
  2181. if(nComments > 0)
  2182. {
  2183. var reporterIsLastCommenter = false;
  2184. if(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1].userID == -1) reporterIsLastCommenter = true;
  2185. if(uroGetCBChecked('_cbHideIfReporterLastCommenter') == true)
  2186. {
  2187. if(reporterIsLastCommenter == true) urStyle = 'hidden';
  2188. }
  2189. else if(uroGetCBChecked('_cbHideIfReporterNotLastCommenter') == true)
  2190. {
  2191. if(reporterIsLastCommenter == false) urStyle = 'hidden';
  2192. }
  2193. hasMyComments = uroURHasMyComments(ureqID);
  2194. if(hasMyComments == false)
  2195. {
  2196. if(uroGetCBChecked('_cbHideAnyComments') == true) urStyle = 'hidden';
  2197. if(uroGetCBChecked('_cbHideIfNotLastCommenter') == true) urStyle = 'hidden';
  2198. }
  2199. else
  2200. {
  2201. if(uroGetCBChecked('_cbHideMyComments') == true) urStyle = 'hidden';
  2202. var userIsLastCommenter = false;
  2203. if(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1].userID == uroUserID) userIsLastCommenter = true;
  2204. if(uroGetCBChecked('_cbHideIfLastCommenter') == true)
  2205. {
  2206. if(userIsLastCommenter == true) urStyle = 'hidden';
  2207. }
  2208. else if(uroGetCBChecked('_cbHideIfNotLastCommenter') == true)
  2209. {
  2210. if(userIsLastCommenter == false) urStyle = 'hidden';
  2211. }
  2212. }
  2213. commentDaysOld = uroGetCommentAge(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1]);
  2214. if((uroGetCBChecked('_cbEnableCommentAgeFilter') == true) && (commentDaysOld != -1))
  2215. {
  2216. if(uroGetElmValue('_inputFilterCommentDays') < commentDaysOld) urStyle = 'hidden';
  2217. }
  2218. if((uroGetCBChecked('_cbEnableCommentAgeFilter2') == true) && (commentDaysOld != -1))
  2219. {
  2220. if(uroGetElmValue('_inputFilterCommentDays2') > commentDaysOld) urStyle = 'hidden';
  2221. }
  2222.  
  2223. if((uroGetCBChecked('_cbURUserIDFilter') == true) && (urStyle != 'hidden'))
  2224. {
  2225. var selector2 = document.getElementById('_selectURUserID');
  2226. var userID2 = parseInt(selector2.selectedOptions[0].value);
  2227. urStyle = 'hidden';
  2228. for(var cidx=0; cidx<nComments; cidx++)
  2229. {
  2230. if(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1].userID == userID2)
  2231. {
  2232. urStyle = 'visible';
  2233. break;
  2234. }
  2235. }
  2236. }
  2237. }
  2238. else
  2239. {
  2240. if(uroGetCBChecked('_cbURUserIDFilter') == true)
  2241. {
  2242. urStyle = 'hidden';
  2243. }
  2244. }
  2245. if(W.model.updateRequestSessions.objects[ureqID].isFollowing == true)
  2246. {
  2247. if(uroGetCBChecked('_cbHideMyFollowed') == true) urStyle = 'hidden';
  2248. }
  2249. else
  2250. {
  2251. if(uroGetCBChecked('_cbHideMyUnfollowed') == true) urStyle = 'hidden';
  2252. }
  2253. }
  2254. }
  2255.  
  2256. if(urStyle == 'visible')
  2257. {
  2258. // Test for Waze automatic URs before any others - these always (?) get inserted as General Error URs,
  2259. // so we can't filter them by type...
  2260. if(desc.indexOf('Waze Automatic:') != -1)
  2261. {
  2262. wazeauto_ur = true;
  2263. }
  2264. if(wazeauto_ur == true)
  2265. {
  2266. if(uroGetCBChecked('_cbFilterWazeAuto') == true) urStyle = 'hidden';
  2267. }
  2268.  
  2269. else if(ukroadworks_ur == true)
  2270. {
  2271. if(uroGetCBChecked('_cbFilterRoadworks') == true) urStyle = 'hidden';
  2272. }
  2273. else if(construction_ur == true)
  2274. {
  2275. if(uroGetCBChecked('_cbFilterConstruction') == true) urStyle = 'hidden';
  2276. }
  2277. else if(closure_ur == true)
  2278. {
  2279. if(uroGetCBChecked('_cbFilterClosure') == true) urStyle = 'hidden';
  2280. }
  2281. else if(event_ur == true)
  2282. {
  2283. if(uroGetCBChecked('_cbFilterEvent') == true) urStyle = 'hidden';
  2284. }
  2285. else if(note_ur == true)
  2286. {
  2287. if(uroGetCBChecked('_cbFilterNote') == true) urStyle = 'hidden';
  2288. }
  2289.  
  2290. else if(ureq.attributes.type == 6)
  2291. {
  2292. if(uroGetCBChecked('_cbFilterIncorrectTurn') == true) urStyle = 'hidden';
  2293. }
  2294. else if(ureq.attributes.type == 7)
  2295. {
  2296. if (uroGetCBChecked('_cbFilterIncorrectAddress') == true) urStyle = 'hidden';
  2297. }
  2298. else if(ureq.attributes.type == 8)
  2299. {
  2300. if(uroGetCBChecked('_cbFilterIncorrectRoute') == true) urStyle = 'hidden';
  2301. }
  2302. else if(ureq.attributes.type == 9)
  2303. {
  2304. if(uroGetCBChecked('_cbFilterMissingRoundabout') == true) urStyle = 'hidden';
  2305. }
  2306. else if(ureq.attributes.type == 10)
  2307. {
  2308. if(uroGetCBChecked('_cbFilterGeneralError') == true) urStyle = 'hidden';
  2309. }
  2310. else if(ureq.attributes.type == 11)
  2311. {
  2312. if(uroGetCBChecked('_cbFilterTurnNotAllowed') == true) urStyle = 'hidden';
  2313. }
  2314. else if(ureq.attributes.type == 12)
  2315. {
  2316. if(uroGetCBChecked('_cbFilterIncorrectJunction') == true) urStyle = 'hidden';
  2317. }
  2318. else if(ureq.attributes.type == 13)
  2319. {
  2320. if(uroGetCBChecked('_cbFilterMissingBridgeOverpass') == true) urStyle = 'hidden';
  2321. }
  2322. else if(ureq.attributes.type == 14)
  2323. {
  2324. if(uroGetCBChecked('_cbFilterWrongDrivingDirection') == true) urStyle = 'hidden';
  2325. }
  2326. else if(ureq.attributes.type == 15)
  2327. {
  2328. if(uroGetCBChecked('_cbFilterMissingExit') == true) urStyle = 'hidden';
  2329. }
  2330. else if(ureq.attributes.type == 16)
  2331. {
  2332. if(uroGetCBChecked('_cbFilterMissingRoad') == true) urStyle = 'hidden';
  2333. }
  2334. else if(ureq.attributes.type == 18)
  2335. {
  2336. if(uroGetCBChecked('_cbFilterMissingLandmark') == true) urStyle = 'hidden';
  2337. }
  2338. else if(ureq.attributes.type == 19)
  2339. {
  2340. if(uroGetCBChecked('_cbFilterBlockedRoad') == true) urStyle = 'hidden';
  2341. }
  2342. else if(uroGetCBChecked('_cbFilterUndefined') == true) urStyle = 'hidden';
  2343. if(uroGetCBChecked('_cbInvertURFilter') == true)
  2344. {
  2345. if(urStyle == 'hidden') urStyle = 'visible';
  2346. else urStyle = 'hidden';
  2347. }
  2348. }
  2349.  
  2350. // filtering override for tagged URs
  2351. if(uroGetCBChecked('_cbNoFilterForTaggedURs') == true)
  2352. {
  2353. if(ukroadworks_ur == true)
  2354. {
  2355. if(uroGetCBChecked('_cbFilterRoadworks') == false) urStyle = 'visible';
  2356. }
  2357. else if(construction_ur == true)
  2358. {
  2359. if(uroGetCBChecked('_cbFilterConstruction') == false) urStyle = 'visible';
  2360. }
  2361. else if(closure_ur == true)
  2362. {
  2363. if(uroGetCBChecked('_cbFilterClosure') == false) urStyle = 'visible';
  2364. }
  2365. else if(event_ur == true)
  2366. {
  2367. if(uroGetCBChecked('_cbFilterEvent') == false) urStyle = 'visible';
  2368. }
  2369. else if(note_ur == true)
  2370. {
  2371. if(uroGetCBChecked('_cbFilterNote') == false) urStyle = 'visible';
  2372. }
  2373. }
  2374. W.map.layers[uroURLayerIdx].markers[urobj].icon.imageDiv.style.visibility = urStyle;
  2375. if(urStyle != 'hidden')
  2376. {
  2377. var customMarkerType = -1;
  2378. if(ukroadworks_ur == true) customMarkerType = 0;
  2379. if(construction_ur == true) customMarkerType = 1;
  2380. if(closure_ur == true) customMarkerType = 2;
  2381. if(event_ur == true) customMarkerType = 3;
  2382. if(note_ur == true) customMarkerType = 4;
  2383. uroAddCustomMarkers(ureqID,customMarkerType, hasMyComments, nComments);
  2384. }
  2385. }
  2386. uroRenderCustomMarkers();
  2387.  
  2388. }
  2389.  
  2390.  
  2391. function uroFilterProblems()
  2392. {
  2393. if(uroFilterPreamble() == false) return;
  2394. for (var urobj in W.model.problems.objects)
  2395. {
  2396. var problem = W.model.problems.objects[urobj];
  2397. var problemStyle = 'visible';
  2398.  
  2399. // check problem against current session ignore list...
  2400. if(uroIsOnIgnoreList(problem.fid)) problemStyle = 'hidden';
  2401.  
  2402. // check against closed/not identified filtering if enabled...
  2403. var problem_marker_img = '';
  2404. if(problem.geometry.id != null)
  2405. {
  2406. if(document.getElementById(problem.geometry.id) != null)
  2407. {
  2408. problem_marker_img = document.getElementById(problem.geometry.id).href.baseVal;
  2409. if(uroGetCBChecked('_cbMPFilterSolved') == true)
  2410. {
  2411. if(problem_marker_img.indexOf('_solved') != -1) problemStyle = 'hidden';
  2412. }
  2413. if(uroGetCBChecked('_cbMPFilterUnidentified') == true)
  2414. {
  2415. if(problem_marker_img.indexOf('_rejected') != -1) problemStyle = 'hidden';
  2416. }
  2417. }
  2418. }
  2419. if(uroGetCBChecked('_cbMPFilterClosed') == true)
  2420. {
  2421. if(problem.attributes.open == false)
  2422. {
  2423. problemStyle = 'hidden';
  2424. }
  2425. }
  2426.  
  2427. if(problemStyle == 'visible')
  2428. {
  2429. if(problem.attributes.problemType == 101)
  2430. {
  2431. if(uroGetCBChecked('_cbMPFilterDrivingDirectionMismatch') == true) problemStyle = 'hidden';
  2432. }
  2433. else if(problem.attributes.problemType == 102)
  2434. {
  2435. if(uroGetCBChecked('_cbMPFilterMissingJunction') == true) problemStyle = 'hidden';
  2436. }
  2437. else if(problem.attributes.problemType == 103)
  2438. {
  2439. if(uroGetCBChecked('_cbMPFilterMissingRoad') == true) problemStyle = 'hidden';
  2440. }
  2441. else if(problem.attributes.problemType == 104)
  2442. {
  2443. if(uroGetCBChecked('_cbMPFilterCrossroadsJunctionMissing') == true) problemStyle = 'hidden';
  2444. }
  2445. else if(problem.attributes.problemType == 105)
  2446. {
  2447. if(uroGetCBChecked('_cbMPFilterRoadTypeMismatch') == true) problemStyle = 'hidden';
  2448. }
  2449. else if(problem.attributes.problemType == 106)
  2450. {
  2451. if(uroGetCBChecked('_cbMPFilterRestrictedTurn') == true) problemStyle = 'hidden';
  2452. }
  2453. else if(uroGetCBChecked('_cbMPFilterUnknownProblem') == true) problemStyle = 'hidden';
  2454. if(uroGetCBChecked('_cbMPFilterReopenedProblem') == true)
  2455. {
  2456. if((problem.attributes.open == true) && (problem.attributes.resolvedOn != null))
  2457. {
  2458. problemStyle = 'hidden';
  2459. }
  2460. }
  2461. if(uroGetCBChecked('_cbInvertMPFilter') == true)
  2462. {
  2463. if(problemStyle == 'hidden') problemStyle = 'visible';
  2464. else problemStyle = 'hidden';
  2465. }
  2466. if(problem.attributes.weight <= 3)
  2467. {
  2468. if(uroGetCBChecked('_cbMPFilterLowSeverity') == true) problemStyle = 'hidden';
  2469. }
  2470. else if(problem.attributes.weight <= 7)
  2471. {
  2472. if(uroGetCBChecked('_cbMPFilterMediumSeverity') == true) problemStyle = 'hidden';
  2473. }
  2474. else if(uroGetCBChecked('_cbMPFilterHighSeverity') == true) problemStyle = 'hidden';
  2475. }
  2476. W.map.layers[uroProblemLayerIdx].markers[urobj].icon.imageDiv.style.visibility = problemStyle;
  2477. }
  2478.  
  2479. for (var urobj in W.model.turnProblems.objects)
  2480. {
  2481. var problem = W.model.turnProblems.objects[urobj];
  2482. var problemStyle = 'visible';
  2483.  
  2484. // check problem against current session ignore list...
  2485. if(uroIsOnIgnoreList(problem.fid)) problemStyle = 'hidden';
  2486.  
  2487. // check against closed/not identified filtering if enabled...
  2488. var problem_marker_img = '';
  2489. if(problem.geometry.id != null)
  2490. {
  2491. if(document.getElementById(problem.geometry.id) != null)
  2492. {
  2493. problem_marker_img = document.getElementById(problem.geometry.id).href.baseVal;
  2494. if(uroGetCBChecked('_cbMPFilterSolved') == true)
  2495. {
  2496. if(problem_marker_img.indexOf('_solved') != -1) problemStyle = 'hidden';
  2497. }
  2498. if(uroGetCBChecked('_cbMPFilterUnidentified') == true)
  2499. {
  2500. if(problem_marker_img.indexOf('_rejected') != -1) problemStyle = 'hidden';
  2501. }
  2502. }
  2503. }
  2504.  
  2505. if(uroGetCBChecked('_cbMPFilterClosed') == true)
  2506. {
  2507. if(problem.attributes.open == false)
  2508. {
  2509. problemStyle = 'hidden';
  2510. }
  2511. }
  2512. if(problemStyle == 'visible')
  2513. {
  2514. if(uroGetCBChecked('_cbMPFilterTurnProblem') == true) problemStyle = 'hidden';
  2515. if(uroGetCBChecked('_cbMPFilterReopenedProblem') == true)
  2516. {
  2517. if((problem.attributes.open == true) && (problem.attributes.resolvedOn != null))
  2518. {
  2519. problemStyle = 'hidden';
  2520. }
  2521. }
  2522. if(uroGetCBChecked('_cbInvertMPFilter') == true)
  2523. {
  2524. if(problemStyle == 'hidden') problemStyle = 'visible';
  2525. else problemStyle = 'hidden';
  2526. }
  2527. }
  2528. W.map.layers[uroProblemLayerIdx].markers[urobj].icon.imageDiv.style.visibility = problemStyle;
  2529. }
  2530. }
  2531.  
  2532. function uroToHex(decValue,digits)
  2533. {
  2534. var modifier = 1;
  2535. for(var i=0; i<digits; i++)
  2536. {
  2537. modifier *= 16;
  2538. }
  2539. decValue = parseInt(decValue);
  2540. decValue += modifier;
  2541. var retval = decValue.toString(16);
  2542. retval = retval.substr(-digits);
  2543. retval = retval.toUpperCase();
  2544. return retval;
  2545. }
  2546.  
  2547. function uroFilterPreamble()
  2548. {
  2549. var mapviewport = document.getElementsByClassName("olMapViewport")[0];
  2550. if(mapviewport == null)
  2551. {
  2552. if(uroNullMapViewport == false)
  2553. {
  2554. uroAddLog('caught null mapviewport');
  2555. uroNullMapViewport = true;
  2556. }
  2557. return false;
  2558. }
  2559. uroNullMapViewport = false;
  2560. if(uroGetCBChecked('_cbWhiteBackground'))
  2561. {
  2562. var customColour = '#' + uroToHex(uroGetElmValue('_inputCustomBackgroundRed'),2);
  2563. customColour += uroToHex(uroGetElmValue('_inputCustomBackgroundGreen'),2);
  2564. customColour += uroToHex(uroGetElmValue('_inputCustomBackgroundBlue'),2);
  2565. mapviewport.style.backgroundColor = customColour;
  2566. }
  2567. else
  2568. {
  2569. mapviewport.style.backgroundColor = "#C2C2C2";
  2570. }
  2571. if(uroGetCBChecked('_cbHideAMLayer'))
  2572. {
  2573. W.map.layers[uroAMLayerIdx].setOpacity(0);
  2574. }
  2575. else
  2576. {
  2577. W.map.layers[uroAMLayerIdx].setOpacity(1);
  2578. }
  2579. //if(uroMaskTest() == true) return false;
  2580. return true;
  2581. }
  2582.  
  2583. function uroFilterItems_URTabClick()
  2584. {
  2585. console.log('ur tab click');
  2586. uroFilterItems();
  2587. }
  2588. function uroFilterItems_MPTabClick()
  2589. {
  2590. console.log('mp tab click');
  2591. uroFilterItems();
  2592. }
  2593. function uroFilterItems_PlacesTabClick()
  2594. {
  2595. console.log('places tab click');
  2596. uroFilterItems();
  2597. }
  2598. function uroFilterItems_CamerasTabClick()
  2599. {
  2600. console.log('cameras tab click');
  2601. uroFilterItems();
  2602. }
  2603. function uroFilterItems_MiscTabClick()
  2604. {
  2605. console.log('misc tab click');
  2606. uroFilterItems();
  2607. }
  2608.  
  2609. function uroFilterItems()
  2610. {
  2611. console.log('filteritems');
  2612. uroFilterProblems();
  2613. uroFilterPlaces();
  2614. uroFilterCameras();
  2615. uroFilterURs();
  2616. }
  2617. function uroFilterItemsOnMove()
  2618. {
  2619. console.log('onmove');
  2620. W.map.events.unregister('mousemove',null,uroFilterItemsOnMove);
  2621. uroFilterItems();
  2622. }
  2623.  
  2624.  
  2625. function uroDeleteObject()
  2626. {
  2627. uroAddLog('delete camera ID '+uroShownFID);
  2628. if(W.model.cameras.objects[uroShownFID] == null)
  2629. {
  2630. uroAddLog('camera object not found...');
  2631. return false;
  2632. }
  2633.  
  2634. uroRemoveCamFromWatchList();
  2635.  
  2636. var actionObj = require('Waze/Action/DeleteObject');
  2637. deleteAction = new actionObj(W.model.cameras.objects[uroShownFID], null);
  2638. W.model.actionManager.add(deleteAction);
  2639. uroExitPopup();
  2640. return false;
  2641. }
  2642.  
  2643.  
  2644. function uroGetUserNameAndRank(userID)
  2645. {
  2646. var userName;
  2647. var userLevel;
  2648. if(W.model.users.objects[userID] != undefined)
  2649. {
  2650. userName = W.model.users.objects[userID].userName;
  2651. userLevel = W.model.users.objects[userID].rank + 1;
  2652. }
  2653. else
  2654. {
  2655. userName = userID;
  2656. userLevel = '?';
  2657. }
  2658. return userName + ' (' + userLevel + ')';
  2659. }
  2660.  
  2661.  
  2662. function uroGetCustomMarkerIdx(customType)
  2663. {
  2664. if(customType == 0) return 3;
  2665. if(customType == 1) return 3;
  2666. if(customType == 2) return 5;
  2667. if(customType == 3) return 7;
  2668. if(customType == 4) return 9;
  2669. return -1;
  2670. }
  2671.  
  2672. function uroGetCustomType(idSrc)
  2673. {
  2674. var ureq = W.model.mapUpdateRequests.objects[idSrc];
  2675. var desc = '';
  2676. if(ureq.attributes.description != null)
  2677. {
  2678. desc = ureq.attributes.description;
  2679. if(desc.indexOf('[ROADWORKS]') != -1) return 0;
  2680. if(desc.indexOf('[CONSTRUCTION]') != -1) return 1;
  2681. if(desc.indexOf('[CLOSURE]') != -1) return 2;
  2682. if(desc.indexOf('[EVENT]') != -1) return 3;
  2683. if(desc.indexOf('[NOTE]') != -1) return 4;
  2684. }
  2685. return -1;
  2686. }
  2687.  
  2688.  
  2689. function uroFormatRestriction(restObj)
  2690. {
  2691. var retval = '<tr>';
  2692. retval += '<td style="text-align:center;">';
  2693. if((restObj.days & 1) == 1) retval += 'S';
  2694. else retval += '-';
  2695. retval += '</td><td style="text-align:center;">';
  2696. if((restObj.days & 2) == 2) retval += 'M';
  2697. else retval += '-';
  2698. retval += '</td><td style="text-align:center;">';
  2699. if((restObj.days & 4) == 4) retval += 'T';
  2700. else retval += '-';
  2701. retval += '</td><td style="text-align:center;">';
  2702. if((restObj.days & 8) == 8) retval += 'W';
  2703. else retval += '-';
  2704. retval += '</td><td style="text-align:center;">';
  2705. if((restObj.days & 16) == 16) retval += 'T';
  2706. else retval += '-';
  2707. retval += '</td><td style="text-align:center;">';
  2708. if((restObj.days & 32) == 32) retval += 'F';
  2709. else retval += '-';
  2710. retval += '</td><td style="text-align:center;">';
  2711. if((restObj.days & 64) == 64) retval += 'S';
  2712. else retval += '-';
  2713. retval += '</td><td>';
  2714. if(restObj.fromDate == null) retval += 'All dates';
  2715. else retval += restObj.fromDate+' to '+restObj.toDate;
  2716. retval += '</td><td>';
  2717.  
  2718. if(restObj.allDay == true) retval += 'All day';
  2719. else retval += restObj.fromTime+' to '+restObj.toTime;
  2720. retval += '</td><td>';
  2721. if(restObj.allVehicleTypes == restObj.vehicleTypes) retval += 'All vehicles';
  2722. else retval += 'Some vehicles';
  2723. retval += '</td><td>';
  2724. var desc = restObj.description.replace(/<\/?[^>]+(>|$)/g, "");
  2725. desc = uroClickify(desc);
  2726. retval += desc;
  2727. retval += '</td></tr>';
  2728. return retval;
  2729. }
  2730.  
  2731. function uroHidePopup()
  2732. {
  2733. uroDiv.style.visibility = 'hidden';
  2734. uroPopupShown = false;
  2735. uroPopupTimer = -2;
  2736. uroShownFID = -1;
  2737. }
  2738.  
  2739. function uroRecentreSessionOnUR()
  2740. {
  2741. W.map.updateRequestLayer.markers[uroShownFID].icon.imageDiv.click();
  2742. W.map.moveTo(W.map.updateRequestLayer.markers[uroShownFID].lonlat, 5);
  2743. uroHidePopup();
  2744. return false;
  2745. }
  2746.  
  2747. function uroRecentreSessionOnMP()
  2748. {
  2749. W.map.problemLayer.markers[uroShownFID].icon.imageDiv.click();
  2750. W.map.moveTo(W.map.problemLayer.markers[uroShownFID].lonlat, 5);
  2751. uroHidePopup();
  2752. return false;
  2753. }
  2754.  
  2755. function uroRecentreSessionOnPUR()
  2756. {
  2757. W.map.placeUpdatesLayer.markers[uroShownFID].icon.imageDiv.click()
  2758. W.map.moveTo(W.map.placeUpdatesLayer.markers[uroShownFID].lonlat, 5);
  2759. uroHidePopup();
  2760. return false;
  2761. }
  2762.  
  2763.  
  2764. function uroNewLookHighlightedItemsCheck(e)
  2765. {
  2766. //if(uroMaskTest() == true) return;
  2767. if(uroMouseIsDown == true) return;
  2768. if(W.geometryEditing.activeEditor != null)
  2769. {
  2770. uroHidePopup();
  2771. return;
  2772. }
  2773.  
  2774. if(OpenLayers == null)
  2775. {
  2776. if(uroNullOpenLayers == false)
  2777. {
  2778. uroAddLog('caught null OpenLayers');
  2779. uroNullOpenLayers = true;
  2780. }
  2781. return;
  2782. }
  2783. uroNullOpenLayers = false;
  2784.  
  2785. var rc = document.getElementById(uroRootContainer);
  2786. if(rc == null)
  2787. {
  2788. if(uroNullRootContainer == false)
  2789. {
  2790. uroAddLog('caught null rootContainer');
  2791. uroNullRootContainer = true
  2792. }
  2793. return;
  2794. }
  2795. uroNullRootContainer = false;
  2796. if(W.map.layers[uroURLayerIdx] == null)
  2797. {
  2798. if(uroNullURLayer == false)
  2799. {
  2800. uroAddLog('caught null UR layer');
  2801. uroNullURLayer = true;
  2802. }
  2803. return;
  2804. }
  2805. uroNullURLayer = false;
  2806.  
  2807. if(W.map.layers[uroProblemLayerIdx] == null)
  2808. {
  2809. if(uroNullProblemLayer == false)
  2810. {
  2811. uroAddLog('caught null problem layer');
  2812. uroNullProblemLayer = true;
  2813. }
  2814. return;
  2815. }
  2816. uroNullProblemLayer = false;
  2817.  
  2818. var mouseX = e.pageX - document.getElementById('map').getBoundingClientRect().left;
  2819. var mouseY = e.pageY - document.getElementById('map').getBoundingClientRect().top;
  2820. var currentItems = rc.getElementsByTagName('g');
  2821.  
  2822. var result = '';
  2823. var rw;
  2824. var rh;
  2825. var doPopUp = false;
  2826. var popup_loc = new OpenLayers.LonLat(0,0);
  2827. var objHasIgnoreLink = false;
  2828. var objHasDeleteLink = false;
  2829.  
  2830. var popupXOffset = document.getElementById('sidebar').clientWidth;
  2831. var popupYOffset = document.getElementsByClassName('waze-header')[0].clientHeight;
  2832. var uroPopupX = mouseX + popupXOffset;
  2833. var uroPopupY = mouseY + popupYOffset;
  2834. var objHasIgnoreLink = false;
  2835. var objHasDeleteLink = false;
  2836. var objHasAddWatchLink = false;
  2837. var objHasRemoveWatchLink = false;
  2838. var objHasUpdateWatchLink = false;
  2839. var objHasRecentreSessionLink = false;
  2840. var newPopupType = null;
  2841.  
  2842. // popup for segment restrictions
  2843. if(uroGetCBChecked('_cbInhibitSegPopup') == false)
  2844. {
  2845. for(var slIdx=0; slIdx < W.map.segmentLayer.features.length; slIdx++)
  2846. {
  2847. if(W.map.segmentLayer.features[slIdx].renderIntent == 'highlight')
  2848. {
  2849. if(W.map.segmentLayer.features[slIdx].fid == null) segObj = W.map.segmentLayer.features[slIdx].model;
  2850. else segObj = W.map.segmentLayer.features[slIdx];
  2851. result += '<table cellpadding=4 border=1">';
  2852. if(segObj.attributes.fwdRestrictions.length > 0)
  2853. {
  2854. doPopUp = true;
  2855. result += '<tr><td colspan=11><b>A-B restrictions:</b></td></tr>';
  2856. for(var idx = 0; idx < segObj.attributes.fwdRestrictions.length; idx++)
  2857. {
  2858. restObj = segObj.attributes.fwdRestrictions[idx];
  2859. result += uroFormatRestriction(restObj);
  2860. }
  2861. }
  2862. if (segObj.attributes.revRestrictions.length > 0)
  2863. {
  2864. doPopUp = true;
  2865. result += '<tr><td colspan=11><b>B-A restrictions:</b></td></tr>';
  2866. for(var idx = 0; idx < segObj.attributes.revRestrictions.length; idx++)
  2867. {
  2868. restObj = segObj.attributes.revRestrictions[idx];
  2869. result += uroFormatRestriction(restObj);
  2870. }
  2871. }
  2872. result += '</table>';
  2873. if(doPopUp == true)
  2874. {
  2875. if(segObj.attributes.id == null) uroFID = segObj.id;
  2876. else uroFID = segObj.attributes.id;
  2877. newPopupType = 'segment_restriction';
  2878. }
  2879. break;
  2880. }
  2881. }
  2882. }
  2883.  
  2884. // popup for restricted turns
  2885. /*
  2886. if(doPopUp == false)
  2887. {
  2888. var idSrc = null;
  2889.  
  2890. //if(uroGetCBChecked('_cbInhibitTurnsPopup') == false)
  2891. {
  2892. if(W.map.layers[uroTurnsLayerIdx].markers.length > 0)
  2893. {
  2894. for(var marker in W.map.layers[uroTurnsLayerIdx].markers)
  2895. {
  2896. markerObj = W.map.layers[uroTurnsLayerIdx].markers[marker];
  2897. markerImg = window.getComputedStyle(markerObj.icon.imageDiv.childNodes[0]).getPropertyValue("background-image");
  2898. markerPos = window.getComputedStyle(markerObj.icon.imageDiv.childNodes[0]).getPropertyValue("background-position");
  2899. markerPos = markerPos.split(' ');
  2900. markerPos = parseInt(markerPos[1].substr(0,markerPos[1].length-2));
  2901.  
  2902. var hovered = false;
  2903. if(markerImg.indexOf('turns-s32af5d033c.png') != -1)
  2904. {
  2905. if(markerPos == -235)
  2906. {
  2907. hovered = true;
  2908. }
  2909. }
  2910. if(hovered == true)
  2911. {
  2912. uroAddLog('hover over turn marker '+marker);
  2913. break;
  2914. }
  2915. }
  2916. }
  2917. }
  2918. }
  2919. */
  2920. // popup for landmarks
  2921. if((doPopUp == false) && (uroGetCBChecked('_cbInhibitLandmarkPopup') == false))
  2922. {
  2923. uroPlaceSelected = false;
  2924. for(var llFeatureIdx=0; llFeatureIdx < W.map.landmarkLayer.features.length; llFeatureIdx++)
  2925. {
  2926. var renderIntent = W.map.landmarkLayer.features[llFeatureIdx].renderIntent;
  2927. if(renderIntent == 'highlight')
  2928. {
  2929. if(W.map.landmarkLayer.features[llFeatureIdx].fid == null) venueObj = W.map.landmarkLayer.features[llFeatureIdx].model;
  2930. else venueObj = W.map.landmarkLayer.features[llFeatureIdx];
  2931. result += '<b>';
  2932. if(venueObj.attributes.name == '') result += 'Unnamed landmark';
  2933. else result += venueObj.attributes.name;
  2934. result += '</b><br>';
  2935. for(var idx = 0; idx < venueObj.attributes.categories.length; idx++)
  2936. {
  2937. result += I18n.translations[I18n.locale].venues.categories[venueObj.attributes.categories[idx]] + '<br>';
  2938. }
  2939. if(venueObj.attributes.residential == true)
  2940. {
  2941. result += '<i>Private Place</i>';
  2942. }
  2943. doPopUp = true;
  2944. newPopupType = 'venue';
  2945. if(venueObj.attributes.id == null) uroFID = venueObj.id;
  2946. else uroFID = venueObj.attributes.id;
  2947. break;
  2948. }
  2949. else if(renderIntent == 'select')
  2950. {
  2951. uroPlaceSelected = true;
  2952. }
  2953. }
  2954. }
  2955.  
  2956. // look for URs, place updates and problems
  2957. //if(doPopUp == false)
  2958. {
  2959. var idSrc = null;
  2960. var divIdx = -1;
  2961. var isUR = false;
  2962. var isProblem = false;
  2963. var isTurnProb = false;
  2964. var isPlaceUpdate = false;
  2965.  
  2966. if(uroGetCBChecked('_cbInhibitURPopup') == false)
  2967. {
  2968. for(var marker in W.map.layers[uroURLayerIdx].markers)
  2969. {
  2970. markerObj = W.map.layers[uroURLayerIdx].markers[marker];
  2971. markerImg = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-image");
  2972. markerPos = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-position");
  2973. markerPos = markerPos.split(' ');
  2974. markerPos = parseInt(markerPos[1].substr(0,markerPos[1].length-2));
  2975.  
  2976. var hovered = false;
  2977. if(markerImg.indexOf('problems-s8f369ca968.png') != -1)
  2978. {
  2979. if((markerPos == -403) || (markerPos == -483) || (markerPos == -563) || (markerPos == -643))
  2980. {
  2981. hovered = true;
  2982. uroAddLog('UR image type 1');
  2983. }
  2984. }
  2985. else if(markerImg.indexOf('problems-se224ab677e.png') != -1)
  2986. {
  2987. if((markerPos == -40) || (markerPos == -160) || (markerPos == -200) || (markerPos == -240))
  2988. {
  2989. hovered = true;
  2990. uroAddLog('UR image type 2');
  2991. }
  2992. }
  2993. else
  2994. {
  2995. if(markerPos > -200)
  2996. {
  2997. hovered = true;
  2998. uroAddLog('UR image type 3');
  2999. }
  3000. }
  3001. if(hovered == true)
  3002. {
  3003. // override popup base position
  3004. var markerXY = W.map.getPixelFromLonLat(markerObj.lonlat);
  3005. uroPopupX = markerXY.x + popupXOffset;
  3006. uroPopupY = markerXY.y + popupYOffset + 40;
  3007. var idSrc = markerObj.id;
  3008. isUR = true;
  3009. newPopupType = 'ur';
  3010. uroAddLog('hover over UR ID '+idSrc);
  3011. if(idSrc != uroCustomMarkerFID)
  3012. {
  3013. if(uroCustomMarkerFID != null)
  3014. {
  3015. var customIdx = uroGetCustomMarkerIdx(uroGetCustomType(uroCustomMarkerFID));
  3016. uroChangeCustomMarkers(uroCustomMarkerFID,false,customIdx);
  3017. uroCustomMarkerFID = null;
  3018. }
  3019. var customIdx = uroGetCustomMarkerIdx(uroGetCustomType(idSrc));
  3020. if(customIdx != -1)
  3021. {
  3022. uroCustomMarkerFID = idSrc;
  3023. uroChangeCustomMarkers(idSrc,hovered,customIdx);
  3024. }
  3025. }
  3026. break;
  3027. }
  3028. }
  3029. if((idSrc == null) && (uroCustomMarkerFID != null))
  3030. {
  3031. var customIdx = uroGetCustomMarkerIdx(uroGetCustomType(uroCustomMarkerFID));
  3032. uroChangeCustomMarkers(uroCustomMarkerFID,false, customIdx);
  3033. uroCustomMarkerFID = null;
  3034. }
  3035. }
  3036.  
  3037. if((isUR == false) && (uroGetCBChecked('_cbInhibitPUPopup') == false))
  3038. {
  3039. var hovered = false;
  3040. for(var marker in W.map.placeUpdatesLayer.markers)
  3041. {
  3042. markerObj = W.map.placeUpdatesLayer.markers[marker];
  3043. markerImg = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-image");
  3044. markerPos = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-position");
  3045. markerPos = markerPos.split(' ');
  3046. markerPos = parseInt(markerPos[1].substr(0,markerPos[1].length-2));
  3047. if(markerImg.indexOf('placeUpdates-sb30471988c.png') != -1)
  3048. {
  3049. // absolute offsets: 0 = new place, -120 = flagged, -240 = new photo, -360 = updated details
  3050. // relative offsets: 0 = green, -40 = highlighted, -80 = default
  3051. if(((markerPos + 40) % 120) == 0)
  3052. {
  3053. var idSrc = markerObj.id;
  3054.  
  3055. // override popup base position
  3056. var markerXY = W.map.getPixelFromLonLat(markerObj.lonlat);
  3057. uroPopupX = markerXY.x + popupXOffset;
  3058. uroPopupY = markerXY.y + popupYOffset + 40;
  3059. isPlaceUpdate = true;
  3060. newPopupType = 'pur';
  3061. uroAddLog('hover over placeUpdate ID '+idSrc);
  3062. break;
  3063. }
  3064. }
  3065. }
  3066. }
  3067.  
  3068. if((isPlaceUpdate == false) && (uroGetCBChecked('_cbInhibitMPPopup') == false))
  3069. {
  3070. var hovered = false;
  3071. for(var marker in W.map.layers[uroProblemLayerIdx].markers)
  3072. {
  3073. markerObj = W.map.layers[uroProblemLayerIdx].markers[marker];
  3074. markerImg = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-image");
  3075. markerPos = window.getComputedStyle(markerObj.icon.imageDiv).getPropertyValue("background-position");
  3076. markerPos = markerPos.split(' ');
  3077. markerPos = parseInt(markerPos[1].substr(0,markerPos[1].length-2));
  3078. if(markerImg.indexOf('problems-s8f369ca968.png') != -1)
  3079. {
  3080. if((markerPos == -65) || (markerPos == -145) || (markerPos == -225) || (markerPos == -305))
  3081. {
  3082. hovered = true;
  3083. uroAddLog('Problem image type 1');
  3084. }
  3085. }
  3086. else if(markerImg.indexOf('problems-se224ab677e.png') != -1)
  3087. {
  3088. if((markerPos == -320) || (markerPos == -560) || (markerPos == -520) || (markerPos == -440))
  3089. {
  3090. hovered = true;
  3091. uroAddLog('Problem image type 2');
  3092. }
  3093. }
  3094. else
  3095. {
  3096. if(markerPos > -200)
  3097. {
  3098. hovered = true;
  3099. uroAddLog('Problem image type 3');
  3100. }
  3101. }
  3102. if(hovered == true)
  3103. {
  3104. var idSrc = null;
  3105. if(markerObj.model.fid == null) idSrc = markerObj.id;
  3106. else idSrc = markerObj.model.fid;
  3107.  
  3108. // override popup base position
  3109. var markerXY = W.map.getPixelFromLonLat(markerObj.lonlat);
  3110. uroPopupX = markerXY.x + popupXOffset;
  3111. uroPopupY = markerXY.y + popupYOffset + 40;
  3112. isProblem = true;
  3113. newPopupType = 'map_problem';
  3114. uroAddLog('hover over problem ID '+idSrc);
  3115.  
  3116. break;
  3117. }
  3118. }
  3119. }
  3120.  
  3121. if (idSrc != null)
  3122. {
  3123. var ureq = null;
  3124. if(isUR) ureq = W.model.mapUpdateRequests.objects[idSrc];
  3125. else if(isProblem)
  3126. {
  3127. ureq = W.model.problems.objects[idSrc];
  3128. if(ureq == undefined)
  3129. {
  3130. var ureq = W.model.turnProblems.objects[idSrc];
  3131. if(ureq != undefined) isTurnProb = true;
  3132. }
  3133. }
  3134. else if(isPlaceUpdate) ureq = W.map.placeUpdatesLayer.markers[idSrc].model;
  3135.  
  3136. var ureqID = null;
  3137. if(ureq.fid != null) ureqID = ureq.fid;
  3138. else if(ureq.id != null) ureqID = ureq.id;
  3139. else if(ureq.attributes.id != null) ureqID = ureq.attributes.id;
  3140. uroFID = ureqID;
  3141. doPopUp = true;
  3142. }
  3143. else
  3144. {
  3145. uroFID = -1;
  3146. }
  3147.  
  3148. if((uroFID != uroShownFID) && (uroFID != -1))
  3149. {
  3150. if(isUR)
  3151. {
  3152. uroAddLog('building popup for UR '+idSrc);
  3153. result = '<b>Update Request ('+idSrc+'): ' + I18n.translations[I18n.locale].update_requests.types[ureq.attributes.type] + '</b><br>';
  3154. if(ureq.attributes.description != null)
  3155. {
  3156. var desc = ureq.attributes.description.replace(/<\/?[^>]+(>|$)/g, "");
  3157. if(desc != "null")
  3158. {
  3159. desc = uroClickify(desc);
  3160. result += desc + '<br>';
  3161. }
  3162. }
  3163.  
  3164. var uroDaysOld = uroGetURAge(ureq,0);
  3165. if(uroDaysOld != -1)
  3166. {
  3167. result += '<i>Submitted ' + uroParseDaysAgo(uroDaysOld) + ' ';
  3168. if(ureq.attributes.guestUserName != null)
  3169. {
  3170. result += 'via Livemap';
  3171. if(ureq.attributes.guestUserName != '')
  3172. {
  3173. result += ' by '+ureq.attributes.guestUserName.replace(/<\/?[^>]+(>|$)/g, "");
  3174. }
  3175. }
  3176. result += '</i>';
  3177. }
  3178. if(ureq.attributes.resolvedOn != null)
  3179. {
  3180. var uroDaysResolved = uroGetURAge(ureq,1);
  3181. if(uroDaysResolved != -1)
  3182. {
  3183. result += '<br><i>Closed ' + uroParseDaysAgo(uroDaysResolved) + ' ';
  3184. if(ureq.attributes.resolvedBy != null)
  3185. {
  3186. result += ' by '+uroGetUserNameAndRank(ureq.attributes.resolvedBy);
  3187. }
  3188. result += '</i>';
  3189. }
  3190. }
  3191. if(W.model.updateRequestSessions.objects[ureqID] != null)
  3192. {
  3193. var hasMyComments = uroURHasMyComments(ureqID);
  3194. var nComments = W.model.updateRequestSessions.objects[ureqID].comments.length;
  3195. result += '<br>' + nComments + ' comment';
  3196. if(nComments != 1) result += 's';
  3197. if((hasMyComments == false) && (nComments > 0)) result += ' (none by me)';
  3198. if(nComments > 0)
  3199. {
  3200. var commentDaysOld = uroGetCommentAge(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1]);
  3201. if(commentDaysOld != -1)
  3202. {
  3203. result += ', last update '+uroParseDaysAgo(commentDaysOld);
  3204. }
  3205. }
  3206. }
  3207. }
  3208. else if(isProblem)
  3209. {
  3210. uroAddLog('building popup for problem '+idSrc);
  3211. if(isTurnProb) result = '<b>Turn Problem ('+idSrc+'): ' + I18n.translations[I18n.locale].problems.types["turn"].title;
  3212. else
  3213. {
  3214. result = '<b>Map Problem ('+idSrc+'): ';
  3215. if(I18n.translations[I18n.locale].problems.types[ureq.attributes.problemType] == undefined) result += 'Unknown problem type ('+ureq.attributes.problemType+')';
  3216. else result += I18n.translations[I18n.locale].problems.types[ureq.attributes.problemType].title;
  3217. }
  3218. result += '</b><br>';
  3219. if(ureq.attributes.resolvedOn != null)
  3220. {
  3221. var uroDaysResolved = uroGetURAge(ureq,1);
  3222. if(uroDaysResolved != -1)
  3223. {
  3224. result += '<br><i>Closed ' + uroParseDaysAgo(uroDaysResolved) + ' ';
  3225. if(ureq.attributes.resolvedBy != null)
  3226. {
  3227. result += ' by '+uroGetUserNameAndRank(ureq.attributes.resolvedBy);
  3228. }
  3229. if((ureq.attributes.open == true) && (ureq.attributes.resolvedOn != null))
  3230. {
  3231. result += '<br>Reopened by Waze';
  3232. }
  3233. result += '</i>';
  3234. }
  3235. }
  3236. }
  3237. else if(isPlaceUpdate)
  3238. {
  3239. uroAddLog('building popup for placeUpdate '+idSrc);
  3240. result = '<b>';
  3241. if(ureq.attributes.name == '') result += 'Unnamed landmark';
  3242. else result += ureq.attributes.name;
  3243. result += '</b><br>';
  3244. for(var idx = 0; idx < ureq.attributes.categories.length; idx++)
  3245. {
  3246. result += I18n.translations[I18n.locale].venues.categories[ureq.attributes.categories[idx]] + '<br>';
  3247. }
  3248. if(ureq.attributes.residential == true)
  3249. {
  3250. result += '<i>Private Place</i>';
  3251. }
  3252. doPopUp = true;
  3253. }
  3254.  
  3255. // add "open new WME tab" link
  3256. var urPos=new OpenLayers.LonLat();
  3257. if(isPlaceUpdate)
  3258. {
  3259. urPos=ureq.geometry.bounds.centerLonLat.clone();
  3260. }
  3261. else
  3262. {
  3263. urPos.lon=ureq.geometry.x;
  3264. urPos.lat=ureq.geometry.y;
  3265. }
  3266. urPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
  3267. var urLink = document.location.href;
  3268. urLayers = '&layers='+W.map.mapState.getLayerVisibilityBitmask();
  3269. urLink = urLink.substr(0,urLink.indexOf('?zoom'));
  3270. urLink += '?zoom=5&lat='+urPos.lat+'&lon='+urPos.lon+urLayers;
  3271. if(isUR) urLink += '&mapUpdateRequest='+idSrc;
  3272. else if(isTurnProb) urLink += '&showturn='+idSrc+'&endshow';
  3273. else if(isProblem) urLink += '&mapProblem='+idSrc;
  3274. else if(isPlaceUpdate) urLink += '&showpur='+idSrc+'&endshow';
  3275. result += '<hr><ul><li><a href="'+urLink+'" target="_urTab">Open in new tab</a> - ';
  3276. //result += '<a href="'+urLink+'">open in current tab</a>';
  3277. result += '<a href="#" id="_recentreSession">centre in current tab</a>';
  3278. objHasRecentreSessionLink = true;
  3279.  
  3280. // add "open new livemap tab" link
  3281. var lmLink = null;
  3282. if(document.getElementsByClassName("waze-header-menu").length == 0)
  3283. {
  3284. uroAddLog('Livemap link in livemap element');
  3285. lmLink = document.getElementById('livemap').href;
  3286. }
  3287. else
  3288. {
  3289. uroAddLog('Livemap link in header menu, locating...');
  3290. var menuItems = document.getElementsByClassName("waze-header-menu")[0];
  3291. for(var miloop = 0; miloop<menuItems.childElementCount; miloop++)
  3292. {
  3293. if(menuItems.children[miloop].innerHTML.indexOf('livemap') != -1)
  3294. {
  3295. uroAddLog('found link in menu entry '+miloop);
  3296. lmLink = menuItems.children[miloop].getElementsByTagName('a')[0].href;
  3297. uroAddLog(lmLink);
  3298. }
  3299. }
  3300. }
  3301. if(lmLink != null)
  3302. {
  3303. var zpos = lmLink.indexOf('?');
  3304. if(zpos > -1) lmLink = lmLink.substr(0,zpos);
  3305. lmLink += '?zoom=17&lat='+urPos.lat+'&lon='+urPos.lon+'&layers=BTTTT';
  3306. result += '<li><a href="'+lmLink+'" target="_lmTab">Open in new livemap tab</a>';
  3307. }
  3308. if(!isPlaceUpdate)
  3309. {
  3310. // add "ignore for this session" link
  3311. result += '<li><a href="#" id="_addtoignore">Hide for this session</a></ul>';
  3312. objHasIgnoreLink = true;
  3313. }
  3314. }
  3315. }
  3316. // look for cameras
  3317. if((doPopUp == false) && (uroGetCBChecked('_cbInhibitCamPopup') == false))
  3318. {
  3319. for(var clFeatureIdx = 0; clFeatureIdx < W.map.camerasLayer.features.length; clFeatureIdx++)
  3320. {
  3321. if(W.map.camerasLayer.features[clFeatureIdx].renderIntent == 'highlight')
  3322. {
  3323. if(W.map.camerasLayer.features[clFeatureIdx].fid == null) ureq = W.map.camerasLayer.features[clFeatureIdx].model;
  3324. else ureq = W.map.camerasLayer.features[clFeatureIdx];
  3325.  
  3326. var ureqID = null;
  3327. if(ureq.fid == null) ureqID = ureq.attributes.id;
  3328. else ureqID = ureq.fid;
  3329. // test isSelected() so that we only do overview data on cameras that are being hovered over
  3330. if(ureq.isSelected() == false)
  3331. {
  3332. // override popup base position
  3333. var markerXY = W.map.getPixelFromLonLat(ureq.geometry.toLonLat());
  3334. uroPopupX = markerXY.x + popupXOffset;
  3335. uroPopupY = markerXY.y + popupYOffset + 60;
  3336.  
  3337. doPopUp = true;
  3338. newPopupType = 'camera';
  3339. uroFID = ureqID;
  3340. uroAddLog('generating popup for camera '+uroFID);
  3341. result += '<b>Camera: ' + ureq.TYPES[ureq.attributes.type] + '</b><br>';
  3342. result += 'ID: '+uroFID+'<br>';
  3343. result += 'Created by ';
  3344. if(W.model.users.get(ureq.attributes.createdBy) != null)
  3345. {
  3346. userID = ureq.attributes.createdBy;
  3347. result += uroGetUserNameAndRank(userID);
  3348. }
  3349. else result += 'unknown';
  3350. result += ', ';
  3351. var camAge = uroGetCameraAge(ureq,1);
  3352. if(camAge != -1)
  3353. {
  3354. result += uroParseDaysAgo(camAge);
  3355. }
  3356. else result += 'unknown days ago';
  3357.  
  3358. result += '<br>Updated by ';
  3359. if(W.model.users.get(ureq.attributes.updatedBy) != null)
  3360. {
  3361. userID = ureq.attributes.updatedBy;
  3362. userName = W.model.users.objects[userID].userName;
  3363. userLevel = W.model.users.objects[userID].rank + 1;
  3364. result += userName + ' (' + userLevel + ')';
  3365. }
  3366. else result += 'unknown';
  3367. result += ', ';
  3368. var camAge = uroGetCameraAge(ureq,0);
  3369. if(camAge != -1)
  3370. {
  3371. result += uroParseDaysAgo(camAge);
  3372. }
  3373. else result += 'unknown days ago';
  3374. result += '<br>Speed data: ';
  3375. if(ureq.attributes.speed != null)
  3376. {
  3377. result += ureq.attributes.speed + 'km/h';
  3378. var speedInMPH = Math.round(ureq.attributes.speed / 1.609);
  3379. result += ' (' + speedInMPH + 'mph';
  3380. if((speedInMPH % 10) != 0) result += ' - not valid?';
  3381. result += ')</i>';
  3382. }
  3383. else result += 'unknown';
  3384.  
  3385. var uid = W.model.loginManager.getLoggedInUser().id;
  3386. result += '<hr><ul>';
  3387. if(uroIsCamOnWatchList(uroFID) != -1)
  3388. {
  3389. result += '<li><a href="#" id="_updatewatchlist">Update watchlist entry</a>';
  3390. result += '<li><a href="#" id="_removefromwatchlist">Remove from watchlist</a>';
  3391. objHasUpdateWatchLink = true;
  3392. objHasRemoveWatchLink = true;
  3393. }
  3394. else
  3395. {
  3396. result += '<li><a href="#" id="_addtowatchlist">Add to watchlist</a>';
  3397. objHasAddWatchLink = true;
  3398. }
  3399.  
  3400. if(ureq.attributes.permissions != 0)
  3401. {
  3402. result += '<li><a href="#" id="_deleteobject">Delete Camera</a>';
  3403. objHasDeleteLink = true;
  3404. }
  3405. result += '</ul>';
  3406. }
  3407. break;
  3408. }
  3409. }
  3410. }
  3411. if(doPopUp == true)
  3412. {
  3413. if((uroFID != uroShownFID) || (newPopupType != uroShownPopupType))
  3414. {
  3415. if(uroFID != uroShownFID) uroAddLog('FID mismatch, show popup: '+uroFID+'/'+uroShownFID);
  3416. else uroAddLog('Popup type mismatch: '+newPopupType+'/'+uroShownPopupType);
  3417. uroShownFID = uroFID;
  3418. uroShownPopupType = newPopupType;
  3419. uroPopupShown = false;
  3420. }
  3421.  
  3422. if(uroPopupShown == false)
  3423. {
  3424. uroAddLog('display popup at '+uroPopupX+','+uroPopupY);
  3425. uroPopupShown = true;
  3426. uroDiv.innerHTML = result;
  3427. if((uroFID != -1) && (objHasIgnoreLink == true))
  3428. {
  3429. uroAddEventListener('_addtoignore','click', uroAddToIgnoreList, true);
  3430. }
  3431. if(objHasDeleteLink == true)
  3432. {
  3433. uroAddEventListener('_deleteobject','click', uroDeleteObject, true);
  3434. }
  3435. if(objHasRemoveWatchLink == true)
  3436. {
  3437. uroAddEventListener('_removefromwatchlist','click', uroRemoveCamFromWatchList, true);
  3438. }
  3439. if(objHasAddWatchLink == true)
  3440. {
  3441. uroAddEventListener('_addtowatchlist','click', uroAddCamToWatchList, true);
  3442. }
  3443. if(objHasUpdateWatchLink == true)
  3444. {
  3445. uroAddEventListener('_updatewatchlist','click', uroUpdateCamWatchList, true);
  3446. }
  3447. if(objHasRecentreSessionLink == true)
  3448. {
  3449. if(isUR) uroAddEventListener('_recentreSession','click', uroRecentreSessionOnUR, true);
  3450. else if((isProblem)||(isTurnProb)) uroAddEventListener('_recentreSession','click', uroRecentreSessionOnMP, true);
  3451. else if(isPlaceUpdate) uroAddEventListener('_recentreSession','click', uroRecentreSessionOnPUR, true);
  3452. }
  3453. rw = parseInt(uroDiv.clientWidth);
  3454. rh = parseInt(uroDiv.clientHeight);
  3455.  
  3456. if(rw > (window.innerWidth / 2)) rw = (window.innerWidth / 2);
  3457. if(rh > (window.innerHeight / 2)) rh = (window.innerHeight / 2);
  3458.  
  3459. if((uroPopupX + rw) > window.innerWidth)
  3460. {
  3461. uroPopupX = window.innerWidth - (rw + 50);
  3462. if(uroPopupX < 0) uroPopupX = 0;
  3463. }
  3464. if((uroPopupY + rh) > window.innerHeight)
  3465. {
  3466. uroPopupY = window.innerHeight - (rh + 50);
  3467. if(uroPopupY < 0) uroPopupY = 0;
  3468. }
  3469.  
  3470. uroDiv.style.top = uroPopupY+'px';
  3471. uroDiv.style.left = uroPopupX+'px';
  3472. uroDiv.clientWidth = rw+'px';
  3473. uroDiv.clientHeight = rh+'px';
  3474. uroDiv.style.visibility = 'visible';
  3475. }
  3476. uroPopupTimer = -1;
  3477. }
  3478. else
  3479. {
  3480. if(uroPopupTimer == -1)
  3481. {
  3482. uroPopupTimer = 2;
  3483. }
  3484. }
  3485. if(uroPopupTimer > 0)
  3486. {
  3487. if(uroMouseInPopup == false)
  3488. {
  3489. uroPopupTimer--;
  3490. }
  3491. }
  3492. if(uroPopupTimer == 0)
  3493. {
  3494. uroHidePopup();
  3495. }
  3496. }
  3497.  
  3498. function uroRestyleWMETabs()
  3499. {
  3500. var navTabs = document.getElementById(uroUserTabId).children[1].children;
  3501. for(var loop = 0; loop<navTabs.length; loop++)
  3502. {
  3503. navTabs[loop].children[0].style.padding = "4px";
  3504. }
  3505. setTimeout(uroRestyleWMETabs,1000);
  3506. }
  3507.  
  3508. function uroExclusiveCB()
  3509. {
  3510. cbChecked = uroGetCBChecked(this.id);
  3511. if(cbChecked == true)
  3512. {
  3513. if(this.id == '_cbHideMyComments') uroGetCBChecked('_cbHideAnyComments') = false;
  3514. if(this.id == '_cbHideAnyComments') uroGetCBChecked('_cbHideMyComments') = false;
  3515. if(this.id == '_cbHideIfLastCommenter') uroGetCBChecked('_cbHideIfNotLastCommenter') = false;
  3516. if(this.id == '_cbHideIfNotLastCommenter') uroGetCBChecked('_cbHideIfLastCommenter') = false;
  3517. if(this.id == '_cbHideIfReporterLastCommenter') uroGetCBChecked('_cbHideIfReporterNotLastCommenter') = false;
  3518. if(this.id == '_cbHideIfReporterNotLastCommenter') uroGetCBChecked('_cbHideIfReporterLastCommenter') = false;
  3519. }
  3520. }
  3521.  
  3522.  
  3523. function uroGetAMs(e)
  3524. {
  3525. var amList = '';
  3526. if(W.map.layers[uroAMLayerIdx].getVisibility() == true)
  3527. {
  3528. var mouseX = e.pageX - document.getElementById('map').getBoundingClientRect().left;
  3529. var mouseY = e.pageY - document.getElementById('map').getBoundingClientRect().top - document.getElementById('toolbar').clientHeight;
  3530. var mousePixel = new OL.Pixel(mouseX, mouseY);
  3531. var mousePoint = W.map.getLonLatFromPixel(mousePixel).toPoint();
  3532.  
  3533. for(var amObj in W.model.managedAreas.objects)
  3534. {
  3535. if(W.model.managedAreas.objects[amObj].geometry.containsPoint(mousePoint))
  3536. {
  3537. if(amList != '') amList += ', ';
  3538. amList += uroGetUserNameAndRank(W.model.managedAreas.objects[amObj].userID);
  3539. }
  3540. }
  3541. if(amList == '')
  3542. {
  3543. amList = 'none';
  3544. }
  3545. amList = "<b>Area Managers:</b> "+amList;
  3546. }
  3547. document.getElementById("uroAMList").innerHTML = amList;
  3548. }
  3549.  
  3550.  
  3551. function uroMouseDown()
  3552. {
  3553. uroMouseIsDown = true;
  3554. }
  3555.  
  3556. function uroMouseUp()
  3557. {
  3558. uroMouseIsDown = false;
  3559. }
  3560.  
  3561. function uroUREvent_onObjectsChanged()
  3562. {
  3563. console.log('uroUREvent_onObjectsChanged');
  3564. }
  3565. function uroUREvent_onObjectsAdded()
  3566. {
  3567. console.log('uroUREvent_onObjectsAdded');
  3568. if(uroGetCBChecked('_cbURResolverIDFilter') == true)
  3569. {
  3570. console.log('build resolver list');
  3571. uroUpdateResolverList();
  3572. }
  3573. uroFilterItems();
  3574.  
  3575. }
  3576. function uroUREvent_onObjectsRemoved()
  3577. {
  3578. console.log('uroUREvent_onObjectsRemoved');
  3579. }
  3580.  
  3581. function uroTenthSecondTick()
  3582. {
  3583. if(uroSetupListeners)
  3584. {
  3585. if((loginManager.isLoggedIn()) || (uroPracticeMode == true))
  3586. {
  3587. uroSetupListeners = false;
  3588. if(uroPracticeMode == true)
  3589. {
  3590. document.getElementsByClassName("sandbox")[0].style.display = "none";
  3591. }
  3592. // filter markers when the marker objects are modified (this happens whenever WME needs to load fresh marker data
  3593. // due to having panned/zoomed the map beyond the extents of the previously loaded data)
  3594. W.model.mapUpdateRequests.events.register("objectschanged", null, uroFilterURs_onObjectsChanged);
  3595. W.model.mapUpdateRequests.events.register("objectsadded", null, uroFilterURs_onObjectsAdded);
  3596. W.model.mapUpdateRequests.events.register("objectsremoved", null, uroFilterURs_onObjectsRemoved);
  3597.  
  3598. W.model.updateRequestSessions.events.register("objectschanged", null, uroUREvent_onObjectsChanged);
  3599. W.model.updateRequestSessions.events.register("objectsadded", null, uroUREvent_onObjectsAdded);
  3600. W.model.updateRequestSessions.events.register("objectsremoved", null, uroUREvent_onObjectsRemoved);
  3601.  
  3602. W.model.cameras.events.register("objectschanged", null, uroFilterCameras);
  3603. W.model.cameras.events.register("objectsadded", null, uroFilterCameras);
  3604. W.model.cameras.events.register("objectsremoved", null, uroFilterCameras);
  3605. W.model.problems.events.register("objectschanged", null, uroFilterProblems);
  3606. W.model.problems.events.register("objectsadded", null, uroFilterProblems);
  3607. W.model.problems.events.register("objectsremoved", null, uroFilterProblems);
  3608. W.model.venues.events.register("objectschanged", null, uroFilterPlaces);
  3609. W.model.venues.events.register("objectsadded", null, uroFilterPlaces);
  3610. W.model.venues.events.register("objectsremoved", null, uroFilterPlaces);
  3611.  
  3612. var userTabs = document.getElementById(uroUserTabId);
  3613. if(uroPracticeMode == false)
  3614. {
  3615. var navTabs = uroTimbonesGetElementsByClassName('nav-tabs', userTabs)[0];
  3616. var tabContent = uroTimbonesGetElementsByClassName('tab-content', userTabs)[0];
  3617. newtabUR = document.createElement('li');
  3618. newtabUR.innerHTML = '<a href="#sidepanel-uroverview" data-toggle="tab">URO+</a>';
  3619. navTabs.appendChild(newtabUR);
  3620. }
  3621. uroControls.id = "sidepanel-uroverview";
  3622. uroControls.className = "tab-pane";
  3623. if(uroPracticeMode == false)
  3624. {
  3625. tabContent.appendChild(uroControls);
  3626. }
  3627. else
  3628. {
  3629. userTabs.appendChild(uroControls);
  3630. }
  3631.  
  3632. uroAddEventListener('_btnUndoLastHide',"click", uroRemoveLastAddedIgnore, true);
  3633. uroAddEventListener('_btnClearSessionHides',"click", uroRemoveAllIgnores, true);
  3634. uroEnableIgnoreListControls();
  3635.  
  3636. uroAddEventListener('_btnClearCamWatchList',"click", uroClearCamWatchList, true);
  3637. uroAddEventListener('_btnSettingsToText',"click", uroSettingsToText, true);
  3638. uroAddEventListener('_btnTextToSettings',"click", uroTextToSettings, true);
  3639. uroAddEventListener('_btnClearSettingsText',"click", uroClearSettingsText, true);
  3640.  
  3641. uroSetOnClick("_linkSelectUserRequests",uroShowURTab);
  3642. uroSetOnClick("_linkSelectMapProblems",uroShowMPTab);
  3643. uroSetOnClick("_linkSelectPlaces",uroShowPlacesTab);
  3644. uroSetOnClick("_linkSelectCameras",uroShowCameraTab);
  3645. uroSetOnClick("_linkSelectMisc",uroShowMiscTab);
  3646. uroSetOnClick("_linkSelectCWL",uroShowCamWatchlistTab);
  3647.  
  3648. uroSetOnClick('_cbHideMyComments',uroExclusiveCB);
  3649. uroSetOnClick('_cbHideAnyComments',uroExclusiveCB);
  3650. uroSetOnClick('_cbHideIfLastCommenter',uroExclusiveCB);
  3651. uroSetOnClick('_cbHideIfNotLastCommenter',uroExclusiveCB);
  3652. uroSetOnClick('_cbHideIfReporterLastCommenter',uroExclusiveCB);
  3653. uroSetOnClick('_cbHideIfReporterNotLastCommenter',uroExclusiveCB);
  3654.  
  3655. var dbgMode = "none";
  3656. if(uroShowDebugOutput)
  3657. {
  3658. dbgMode = "inline";
  3659. }
  3660. document.getElementById('_uroDebugMode').style.display = dbgMode;
  3661. uroAddEventListener('_uroVersion',"click", uroToggleDebug, true);
  3662.  
  3663. uroAddLog('finalise onload');
  3664. uroLoadSettings();
  3665. uroNewLookCheckDetailsRequest();
  3666.  
  3667. if(uroGetCBChecked('_cbEnableDTE'))
  3668. {
  3669. if(dteControlsIdx != -1) dteSetNewTabLength();
  3670. else
  3671. {
  3672. uroAddLog('ERROR - archive panel not found!');
  3673. uroSetStyleDisplay(uroUserTabId,'');
  3674. }
  3675. }
  3676.  
  3677. if(uroGetCBChecked('_cbEnableSRS'))
  3678. {
  3679. selectionManager.events.register("selectionchanged", null, srsCheckSidePanel);
  3680. uroAddLog('added SRS event handler');
  3681. }
  3682.  
  3683. // filter markers as and when the map is moved
  3684. W.map.events.register("moveend", null, uroFilterItems);
  3685. W.map.events.register("mousemove", null, uroGetAMs);
  3686. W.map.events.register("mousemove", null, uroNewLookHighlightedItemsCheck);
  3687. W.map.events.registerPriority("mousedown", null, uroMouseDown);
  3688.  
  3689. // trap mousedown on Streetview marker drag
  3690. document.getElementsByClassName('street-view-control')[0].onmousedown = uroMouseDown;
  3691. W.map.events.register("mouseup", null, uroMouseUp);
  3692. uroSetStyles(uroCtrlURs);
  3693. uroSetStyles(uroCtrlMPs);
  3694. uroSetStyles(uroCtrlPlaces);
  3695. uroSetStyles(uroCtrlCameras);
  3696. uroSetStyles(uroCtrlMisc);
  3697. uroSetStyles(uroCamWatchlist);
  3698.  
  3699. uroShowURTab();
  3700. uroRestyleWMETabs();
  3701. uroUserID = loginManager.getLoggedInUser().id;
  3702. console.log('tenth second tick');
  3703. uroFilterItems();
  3704. }
  3705. }
  3706. else
  3707. {
  3708. var mousePos = document.getElementsByClassName('olControlMousePosition')[0].innerHTML;
  3709. if((mousePos == '00.00000, 00.00000') && (uroMouseInPopup == false) && (uroPopupShown == true))
  3710. {
  3711. uroHidePopup();
  3712. }
  3713. }
  3714. }
  3715.  
  3716. function uroToggleURCtrls()
  3717. {
  3718. uroCtrlsHidden = !uroCtrlsHidden;
  3719. if (!uroCtrlsHidden)
  3720. {
  3721. document.getElementById('_hideUCCtrl').innerHTML = "hide";
  3722. if(uroCurrentTab == 1) uroShowURTab();
  3723. else if(uroCurrentTab == 2) uroShowMPTab();
  3724. else if(uroCurrentTab == 3) uroShowPlacesTab();
  3725. else if(uroCurrentTab == 4) uroShowCameraTab();
  3726. else if(uroCurrentTab == 5) uroShowCamWatchlistTab();
  3727. else if(uroCurrentTab == 6) uroShowMiscTab();
  3728. }
  3729. else
  3730. {
  3731. document.getElementById('_hideUCCtrl').innerHTML = "show";
  3732. uroSetStyleDisplay('uroCtrlURs','none');
  3733. uroSetStyleDisplay('uroCtrlMPs','none');
  3734. uroSetStyleDisplay('uroCtrlCameras','none');
  3735. uroSetStyleDisplay('uroCtrlMisc','none');
  3736. uroSetStyleDisplay('uroCamWatchlist','none');
  3737. }
  3738.  
  3739. return false;
  3740. }
  3741.  
  3742. function uroActiveTab(_id)
  3743. {
  3744. var e = document.getElementById(_id);
  3745. e.style.backgroundColor = "aliceblue";
  3746. e.style.borderTop = "1px solid";
  3747. e.style.borderLeft = "1px solid";
  3748. e.style.borderRight = "1px solid";
  3749. e.style.borderBottom = "0px solid";
  3750. }
  3751.  
  3752. function uroInactiveTab(_id)
  3753. {
  3754. var e = document.getElementById(_id);
  3755. e.style.backgroundColor = "white";
  3756. e.style.borderTop = "0px solid";
  3757. e.style.borderLeft = "0px solid";
  3758. e.style.borderRight = "0px solid";
  3759. e.style.borderBottom = "1px solid";
  3760. }
  3761.  
  3762.  
  3763. function uroInactiveAllTabs()
  3764. {
  3765. uroInactiveTab("_tabSelectCameras");
  3766. uroInactiveTab("_tabSelectMapProblems");
  3767. uroInactiveTab("_tabSelectMisc");
  3768. uroInactiveTab("_tabSelectUserRequests");
  3769. uroInactiveTab("_tabSelectCWL");
  3770. uroInactiveTab("_tabSelectPlaces");
  3771. if(!uroCtrlsHidden)
  3772. {
  3773. uroSetStyleDisplay('uroCtrlURs','none');
  3774. uroSetStyleDisplay('uroCtrlMPs','none');
  3775. uroSetStyleDisplay('uroCtrlCameras','none');
  3776. uroSetStyleDisplay('uroCtrlMisc','none');
  3777. uroSetStyleDisplay('uroCamWatchlist','none');
  3778. uroSetStyleDisplay('uroCtrlPlaces','none');
  3779. }
  3780. }
  3781.  
  3782. function uroShowURTab()
  3783. {
  3784. uroInactiveAllTabs();
  3785. uroActiveTab("_tabSelectUserRequests");
  3786. uroCurrentTab = 1;
  3787. if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlURs','block');
  3788. return false;
  3789. }
  3790.  
  3791.  
  3792. function uroShowMPTab()
  3793. {
  3794. uroInactiveAllTabs();
  3795. uroActiveTab("_tabSelectMapProblems");
  3796. uroCurrentTab = 2;
  3797. if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlMPs','block');
  3798. return false;
  3799. }
  3800.  
  3801. function uroShowPlacesTab()
  3802. {
  3803. uroInactiveAllTabs();
  3804. uroActiveTab("_tabSelectPlaces");
  3805. uroCurrentTab = 3;
  3806. if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlPlaces','block');
  3807. return false;
  3808. }
  3809.  
  3810. function uroShowCameraTab()
  3811. {
  3812. uroInactiveAllTabs();
  3813. uroActiveTab("_tabSelectCameras");
  3814. uroCurrentTab = 4;
  3815. if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlCameras','block');
  3816. return false;
  3817. }
  3818.  
  3819. function uroShowCamWatchlistTab()
  3820. {
  3821. uroInactiveAllTabs();
  3822. uroActiveTab("_tabSelectCWL");
  3823. uroCurrentTab = 5;
  3824. if(!uroCtrlsHidden) uroSetStyleDisplay('uroCamWatchlist','block');
  3825. uroCWLUpdateHTML();
  3826. return false;
  3827. }
  3828. function uroShowMiscTab()
  3829. {
  3830. uroInactiveAllTabs();
  3831. uroActiveTab("_tabSelectMisc");
  3832. uroCurrentTab = 6;
  3833. if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlMisc','block');
  3834. return false;
  3835. }
  3836.  
  3837.  
  3838.  
  3839. function uroTimbonesGetElementsByClassName(classname, node) {
  3840. if(!node) node = document.getElementsByTagName("body")[0];
  3841. var a = [];
  3842. var re = new RegExp('\\b' + classname + '\\b');
  3843. var els = node.getElementsByTagName("*");
  3844. for (var i=0,j=els.length; i<j; i++)
  3845. if (re.test(els[i].className)) a.push(els[i]);
  3846. return a;
  3847. }
  3848.  
  3849. function uroNewLookCheckDetailsRequest()
  3850. {
  3851. var thisurl = document.location.href;
  3852. var doRetry = true;
  3853. endmarkerpos = thisurl.indexOf('&endshow');
  3854.  
  3855. showmarkerpos = thisurl.indexOf('&showturn=');
  3856. if((endmarkerpos != -1) && (showmarkerpos != -1))
  3857. {
  3858. showmarkerpos += 10;
  3859. uroAddLog('showturn tab opened');
  3860. var urID = thisurl.substr(showmarkerpos,endmarkerpos-showmarkerpos);
  3861. uroAddLog(' turn problem ID = '+urID);
  3862.  
  3863. try
  3864. {
  3865. W.map.problemLayer.markers[urID].icon.imageDiv.click();
  3866. doRetry = false;
  3867. }
  3868. catch(err)
  3869. {
  3870. uroAddLog('problems not fully loaded, retrying...');
  3871. }
  3872.  
  3873. if(doRetry) setTimeout(uroNewLookCheckDetailsRequest,500);
  3874. }
  3875. else
  3876. {
  3877. showmarkerpos = thisurl.indexOf('&showpur=');
  3878. if((endmarkerpos != -1) && (showmarkerpos != -1))
  3879. {
  3880. showmarkerpos += 9;
  3881. uroAddLog('showPUR tab opened');
  3882. var urID = thisurl.substr(showmarkerpos,endmarkerpos-showmarkerpos);
  3883. uroAddLog(' PUR ID = '+urID);
  3884.  
  3885. try
  3886. {
  3887. W.map.placeUpdatesLayer.markers[urID].icon.imageDiv.click();
  3888. doRetry = false;
  3889. }
  3890. catch(err)
  3891. {
  3892. uroAddLog('PURs not fully loaded, retrying...');
  3893. }
  3894.  
  3895. if(doRetry) setTimeout(uroNewLookCheckDetailsRequest,500);
  3896. }
  3897. }
  3898. }
  3899.  
  3900.  
  3901. function uroUpdateResolverList()
  3902. {
  3903. if(Object.keys(W.model.mapUpdateRequests.objects).length == 0)
  3904. {
  3905. console.log('no objects');
  3906. return;
  3907. }
  3908.  
  3909. var resolverList = [];
  3910. var selector = document.getElementById('_selectURResolverID');
  3911. var selectedUser = null;
  3912. if(selector.selectedOptions[0] != undefined)
  3913. {
  3914. selectedUser = parseInt(selector.selectedOptions[0].value);
  3915. }
  3916. while(selector.options.length > 0)
  3917. {
  3918. selector.options.remove(0);
  3919. }
  3920. var selectedIdx = 0;
  3921. var idx = 0;
  3922. for (var urobj in W.model.mapUpdateRequests.objects)
  3923. {
  3924. var ureq = W.model.mapUpdateRequests.objects[urobj];
  3925. if(ureq.attributes.resolvedBy != null)
  3926. {
  3927. var userID = ureq.attributes.resolvedBy;
  3928. var userName = W.model.users.objects[userID].userName;
  3929. if(resolverList.indexOf(userName) == -1)
  3930. {
  3931. resolverList.push(userName);
  3932. selector.options.add(new Option(userName, userID));
  3933. if(userID == selectedUser)
  3934. {
  3935. selectedIdx = idx;
  3936. }
  3937. idx++;
  3938. }
  3939. }
  3940. }
  3941. if(selectedIdx != null)
  3942. {
  3943. selector.selectedIndex = selectedIdx;
  3944. }
  3945. }
  3946.  
  3947. function uroUpdateUserList()
  3948. {
  3949. if(Object.keys(W.model.updateRequestSessions.objects).length == 0) return;
  3950. var selector = document.getElementById('_selectURUserID');
  3951.  
  3952. var selectedUser = null;
  3953. if(selector.selectedOptions[0] != undefined)
  3954. {
  3955. selectedUser = parseInt(selector.selectedOptions[0].value);
  3956. }
  3957. while(selector.options.length > 0)
  3958. {
  3959. selector.options.remove(0);
  3960. }
  3961. var selectedIdx = null;
  3962.  
  3963. var listedIDs = [];
  3964. for(var ursIdx in W.model.updateRequestSessions.objects)
  3965. {
  3966. var ursObj = W.model.updateRequestSessions.objects[ursIdx];
  3967. if(ursObj.comments.length > 0)
  3968. {
  3969. for(var cidx=0; cidx < ursObj.comments.length; cidx++)
  3970. {
  3971. var userID = ursObj.comments[cidx].userID;
  3972. if((listedIDs.indexOf(userID) == -1) && (userID != -1))
  3973. {
  3974. listedIDs.push(userID);
  3975. }
  3976. }
  3977. }
  3978. }
  3979.  
  3980. if(listedIDs.length > 0)
  3981. {
  3982. var users = W.model.users.getByIds(listedIDs);
  3983. for(var idx=0; idx<listedIDs.length; idx++)
  3984. {
  3985. selector.options.add(new Option(users[idx].userName, listedIDs[idx]));
  3986. if(listedIDs[idx] == selectedUser)
  3987. {
  3988. selectedIdx = idx;
  3989. }
  3990. }
  3991. }
  3992. if(selectedIdx != null)
  3993. {
  3994. selector.selectedIndex = selectedIdx;
  3995. }
  3996. }
  3997.  
  3998.  
  3999. function uroSetStyles(obj)
  4000. {
  4001. obj.style.fontSize = '12px';
  4002. obj.style.lineHeight = '100%';
  4003. obj.style.overflow = 'auto';
  4004. obj.style.height = (window.innerHeight * 0.55) + 'px';
  4005. }
  4006.  
  4007. function uroPopulatePlacesTab()
  4008. {
  4009. var tHTML = '';
  4010. tHTML += '<b>Filter PURs by category/status:</b><br>';
  4011. tHTML += '<input type="checkbox" id="_cbFilterUneditablePlaceUpdates">Ones I can\'t edit</input><br>';
  4012. tHTML += '<input type="checkbox" id="_cbFilterLockRankedPlaceUpdates">Ones with non-zero lockRanks</input><br>';
  4013. tHTML += '<input type="checkbox" id="_cbFilterNewPlacePUR">Ones for new places</input><br>';
  4014. tHTML += '<input type="checkbox" id="_cbFilterUpdatedDetailsPUR">Ones for updated place details</input><br>';
  4015. tHTML += '<input type="checkbox" id="_cbFilterNewPhotoPUR">Ones for new photos</input><br>';
  4016. tHTML += '<input type="checkbox" id="_cbFilterFlaggedPUR">Ones flagged for attention</input><br>';
  4017. tHTML += '<br><input type="checkbox" id="_cbLeavePURGeos">Don\'t hide place polygons/points</input><br>';
  4018. tHTML += '<br><input type="checkbox" id="_cbInvertPURFilters">Invert PUR filters</input><br>';
  4019. tHTML += '<hr>';
  4020. tHTML += '<br><b>Filter Places by state:</b><br>';
  4021. tHTML += 'Hide if last edited<br>';
  4022. tHTML += '<input type="checkbox" id="_cbPlaceFilterEditedLessThan"> less than </input>';
  4023. tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterPlaceEditMinDays"> days ago<br>';
  4024. tHTML += '<input type="checkbox" id="_cbPlaceFilterEditedMoreThan"> more than </input>';
  4025. tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterPlaceEditMaxDays"> days ago<br>';
  4026. tHTML += '<br>Hide if locked at level:<br>';
  4027. tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesL0">1</input>';
  4028. tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesL1">2</input>';
  4029. tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesL2">3</input>';
  4030. tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesL3">4</input>';
  4031. tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesL4">5</input>';
  4032. tHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHidePlacesL5">6</input>';
  4033. tHTML += '<br><br><input type="checkbox" id="_cbHidePhotoPlaces">Hide or </input>';
  4034. tHTML += '<input type="checkbox" id="_cbHideNoPhotoPlaces">show ones with photos</input><br>';
  4035. tHTML += '<br><br><b>Filter Places by category:</b><br>';
  4036. for(var i=0; i<W.Config.venues.categories.length; i++)
  4037. {
  4038. parentCategory = W.Config.venues.categories[i];
  4039. localisedName = I18n.translations[I18n.locale].venues.categories[parentCategory];
  4040. tHTML += '<input type="checkbox" id="_cbPlacesFilter-'+parentCategory+'"><b>'+localisedName+'</b></input><br>';
  4041. for(var ii=0; ii<W.Config.venues.subcategories[parentCategory].length; ii++)
  4042. {
  4043. subCategory = W.Config.venues.subcategories[parentCategory][ii];
  4044. localisedName = I18n.translations[I18n.locale].venues.categories[subCategory];
  4045. tHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbPlacesFilter-'+subCategory+'">'+localisedName+'</input><br>';
  4046. }
  4047. }
  4048. tHTML += '<input type="checkbox" id="_cbFilterPrivatePlaces"><b>Private Places</b></input><br>';
  4049. tHTML += '<br><input type="checkbox" id="_cbInvertPlacesFilter">Invert Place filters?</input>';
  4050. uroCtrlPlaces.innerHTML = tHTML;
  4051. }
  4052.  
  4053. function uroWazeBits()
  4054. {
  4055. // "fake" uroWazeBits() function which only performs layer scan, to stop the uroWazeBits() call in WMETB from
  4056. // messing around with other stuff in the actual uroWazeBits() function (now renamed uroRealWazeBits...) that
  4057. // really only ought to be called once.
  4058. for(i=0;i<W.map.layers.length;i++)
  4059. {
  4060. if(W.map.layers[i].uniqueName == 'update_requests') uroURLayerIdx = i;
  4061. if(W.map.layers[i].uniqueName == 'problems') uroProblemLayerIdx = i;
  4062. if(W.map.layers[i].name == 'Spotlight') uroMaskLayer = i;
  4063. if(W.map.layers[i].uniqueName == 'speed_cameras') uroCamLayer = i;
  4064. if(W.map.layers[i].name.indexOf('Waze.Control.SelectHighlightFeature') != -1) uroRootContainer = W.map.layers[i].div.id;
  4065. if(W.map.layers[i].uniqueName == 'area_managers') uroAMLayerIdx = i;
  4066. if(W.map.layers[i].uniqueName == 'landmarks') uroPlacesRoot = W.map.layers[i].id + '_vroot';
  4067. if(W.map.layers[i].name == 'Node Connections') uroTurnsLayerIdx = i;
  4068. }
  4069.  
  4070. for(i=0;i<W.map.controls.length;i++)
  4071. {
  4072. if(W.map.controls[i].CLASS_NAME == 'Waze.View.ArchivePanel') dteControlsIdx = i;
  4073. else if(W.map.controls[i].CLASS_NAME == 'Waze.Control.Archive') dteControlsIdx = i;
  4074.  
  4075. if(W.map.controls[i].id != null)
  4076. {
  4077. if(W.map.controls[i].id.indexOf('UpdateRequests') != -1) uroURControlsIdx = i;
  4078. if(W.map.controls[i].id.indexOf('MapProblems') != -1) uroProblemControlsIdx = i;
  4079. }
  4080. }
  4081. uroAddLog('UR layer at idx '+uroURLayerIdx);
  4082. uroAddLog('Problem layer at idx '+uroProblemLayerIdx);
  4083. uroAddLog('uroMaskLayer at idx '+uroMaskLayer);
  4084. uroAddLog('Camera layer at idx '+uroCamLayer);
  4085. uroAddLog('AM layer at idx '+uroAMLayerIdx);
  4086. uroAddLog('Turns layer at idx '+uroTurnsLayerIdx);
  4087. uroAddLog('uroRootContainer = '+uroRootContainer);
  4088. uroAddLog('Places root layer = '+uroPlacesRoot);
  4089. }
  4090.  
  4091.  
  4092. function uroRealWazeBits()
  4093. {
  4094. if(document.getElementsByClassName("sandbox-message").length > 0)
  4095. {
  4096. uroPracticeMode = true;
  4097. }
  4098. else
  4099. {
  4100. uroPracticeMode = false;
  4101. }
  4102. uroAddLog('adding WazeBits...'+uroToHex(uroWazeBitsPresent,4));
  4103. if((uroWazeBitsPresent & 0x0001) == 0)
  4104. {
  4105. if(typeof unsafeWindow.W != "undefined")
  4106. {
  4107. if(typeof unsafeWindow.W.controller != "undefined")
  4108. {
  4109. if(typeof unsafeWindow.W.controller.map != "undefined")
  4110. {
  4111. uroAddLog(' W.map OK');
  4112. W.map = unsafeWindow.W.controller.map;
  4113. uroWazeBitsPresent |= 0x0001;
  4114. }
  4115. }
  4116. }
  4117. }
  4118. if((uroWazeBitsPresent & 0x0002) == 0)
  4119. {
  4120. if(typeof unsafeWindow.W != "undefined")
  4121. {
  4122. if(typeof unsafeWindow.W.controller != "undefined")
  4123. {
  4124. if(typeof unsafeWindow.W.controller.model != "undefined")
  4125. {
  4126. uroAddLog(' W.model OK');
  4127. W.model = unsafeWindow.W.controller.model;
  4128. uroWazeBitsPresent |= 0x0002;
  4129. }
  4130. }
  4131. }
  4132. }
  4133. if((uroWazeBitsPresent & 0x0004) == 0)
  4134. {
  4135. if(typeof unsafeWindow.W != "undefined")
  4136. {
  4137. if(typeof unsafeWindow.W.app != "undefined")
  4138. {
  4139. if(typeof unsafeWindow.W.app.loginManager != "undefined")
  4140. {
  4141. uroAddLog(' loginManager OK');
  4142. loginManager = unsafeWindow.W.app.loginManager;
  4143. uroWazeBitsPresent |= 0x0004;
  4144. }
  4145. }
  4146. }
  4147. }
  4148. if((uroWazeBitsPresent & 0x0008) == 0)
  4149. {
  4150. if(typeof unsafeWindow.W != "undefined")
  4151. {
  4152. if(typeof unsafeWindow.W.geometryEditing != "undefined")
  4153. {
  4154. if(typeof unsafeWindow.W.geometryEditing.selectionManager != "undefined")
  4155. {
  4156. uroAddLog(' selectionManager OK');
  4157. selectionManager = unsafeWindow.W.geometryEditing.selectionManager;
  4158. uroWazeBitsPresent |= 0x0008;
  4159. }
  4160. }
  4161. }
  4162. }
  4163. if((uroWazeBitsPresent & 0x0010) == 0)
  4164. {
  4165. if(typeof unsafeWindow.OpenLayers != "undefined")
  4166. {
  4167. uroAddLog(' OpenLayers OK');
  4168. OpenLayers = unsafeWindow.OpenLayers;
  4169. uroWazeBitsPresent |= 0x0010;
  4170. }
  4171. }
  4172. if((uroWazeBitsPresent & 0x0020) == 0)
  4173. {
  4174. if(typeof unsafeWindow.Waze != "undefined")
  4175. {
  4176. uroAddLog(' Waze OK');
  4177. Waze = unsafeWindow.Waze;
  4178. uroWazeBitsPresent |= 0x0020;
  4179. }
  4180. }
  4181. if((uroWazeBitsPresent & 0x0040) == 0)
  4182. {
  4183. if(document.getElementById('user-tabs') != null)
  4184. {
  4185. uroUserTabId = 'user-tabs';
  4186. uroAddLog(' user-tabs OK');
  4187. uroWazeBitsPresent |= 0x0040;
  4188. }
  4189. else if(document.getElementById('user-info') != null)
  4190. {
  4191. uroUserTabId = 'user-info';
  4192. uroAddLog(' user-info OK');
  4193. uroWazeBitsPresent |= 0x0040;
  4194. }
  4195. }
  4196. if((uroWazeBitsPresent & 0x0080) == 0)
  4197. {
  4198. if(uroPracticeMode == true)
  4199. {
  4200. uroAddLog(' sidepanel-drives ignored in practice mode');
  4201. uroWazeBitsPresent |= 0x0080;
  4202. }
  4203. else
  4204. {
  4205. if(document.getElementById('sidepanel-drives') != null)
  4206. {
  4207. uroAddLog(' sidepanel-drives OK');
  4208. uroWazeBitsPresent |= 0x0080;
  4209. }
  4210. }
  4211. }
  4212. if((uroWazeBitsPresent & 0x0100) == 0)
  4213. {
  4214. if(typeof unsafeWindow.I18n != "undefined")
  4215. {
  4216. uroAddLog(' I18n OK');
  4217. uroWazeBitsPresent |= 0x0100;
  4218. }
  4219. }
  4220.  
  4221. if(uroWazeBitsPresent != 0x01FF) setTimeout(uroRealWazeBits,250);
  4222. else if((loginManager.isLoggedIn() == false) && (uroPracticeMode == false))
  4223. {
  4224. uroAddLog('Waiting for user log-in...');
  4225. setTimeout(uroRealWazeBits,1000);
  4226. }
  4227. else
  4228. {
  4229. uroAddLog('All WazeBits present and correct...');
  4230. uroPopulatePlacesTab();
  4231. uroControls.appendChild(uroCtrlURs);
  4232. uroControls.appendChild(uroCtrlMPs);
  4233. uroControls.appendChild(uroCtrlPlaces);
  4234. uroControls.appendChild(uroCtrlCameras);
  4235. uroControls.appendChild(uroCamWatchlist);
  4236. uroControls.appendChild(uroCtrlMisc);
  4237. uroControls.appendChild(uroCtrlHides);
  4238. uroControls.appendChild(uroAMList);
  4239.  
  4240. uroCtrlURs.onclick = uroFilterItems_URTabClick;
  4241. uroCtrlMPs.onclick = uroFilterItems_MPTabClick;
  4242. uroCtrlPlaces.onclick = uroFilterItems_PlacesTabClick;
  4243. uroCtrlCameras.onclick = uroFilterItems_CamerasTabClick;
  4244. uroCtrlMisc.onclick = uroFilterItems_MiscTabClick;
  4245.  
  4246. uroWazeBits();
  4247.  
  4248. uroDiv.addEventListener("mouseover", uroEnterPopup, false);
  4249. uroDiv.addEventListener("mouseout", uroExitPopup, false);
  4250.  
  4251. if(sessionStorage.UROverview_FID_IgnoreList == null) sessionStorage.UROverview_FID_IgnoreList = '';
  4252. if(sessionStorage.UROverview_FID_WatchList == null) sessionStorage.UROverview_FID_WatchList = '';
  4253. if(uroConfirmIntercepted == false) uroAddInterceptor();
  4254.  
  4255. setInterval(uroTenthSecondTick,100);
  4256. }
  4257. }
  4258.  
  4259.  
  4260. function uroAddInterceptor()
  4261. {
  4262. uroAddLog('Adding interceptor function...');
  4263. // add interceptor function for confirm(), so that we can auto-select the "OK" option when solving URs
  4264. // which have pending question...
  4265. _confirm = unsafeWindow.confirm;
  4266. unsafeWindow.confirm = function(msg)
  4267. {
  4268. if((I18n.translations[I18n.locale].update_requests.panel.confirm == msg) && (uroGetCBChecked('_cbDisablePendingQuestions') == true))
  4269. {
  4270. uroAddLog('Intercepted pending comments confirmation...');
  4271. return true;
  4272. }
  4273. else if(typeof(msg) == 'undefined')
  4274. {
  4275. uroAddLog('Intercepted blank confirmation...');
  4276. return true;
  4277. }
  4278. else
  4279. {
  4280. return _confirm(msg);
  4281. }
  4282. };
  4283. uroConfirmIntercepted = true;
  4284. }
  4285.  
  4286.  
  4287. function uroEnterPopup()
  4288. {
  4289. uroMouseInPopup = true;
  4290. }
  4291.  
  4292. function uroExitPopup()
  4293. {
  4294. uroMouseInPopup = false;
  4295. }
  4296.  
  4297. function uroToggleDebug()
  4298. {
  4299. uroShowDebugOutput = !uroShowDebugOutput;
  4300. var dbgMode = "none";
  4301. if(uroShowDebugOutput)
  4302. {
  4303. dbgMode = "inline";
  4304. }
  4305. document.getElementById('_uroDebugMode').style.display = dbgMode;
  4306. }
  4307.  
  4308. function uroInitialise()
  4309. {
  4310. uroGlobals();
  4311. if(document.URL.indexOf('editor-beta') != -1) uroBetaEditor = true;
  4312.  
  4313. // create a new div to display the UR details floaty-box
  4314. uroDiv = document.createElement('div');
  4315. uroDiv.id = "uroDiv";
  4316. uroDiv.style.position = 'absolute';
  4317. uroDiv.style.visibility = 'hidden';
  4318. uroDiv.style.top = '0';
  4319. uroDiv.style.left = '0';
  4320. uroDiv.style.zIndex = 100;
  4321. uroDiv.style.backgroundColor = 'aliceblue';
  4322. uroDiv.style.borderWidth = '3px';
  4323. uroDiv.style.borderStyle = 'ridge';
  4324. uroDiv.style.borderRadius = '10px';
  4325. uroDiv.style.boxShadow = '5px 5px 10px Silver';
  4326. uroDiv.style.padding = '4px';
  4327. document.body.appendChild(uroDiv);
  4328.  
  4329.  
  4330. uroControls = document.createElement('section');
  4331. uroControls.style.fontSize = '12px';
  4332. uroControls.id = 'uroControls';
  4333. if(navigator.userAgent.indexOf('Chrome') == -1)
  4334. {
  4335. var updateURL = 'https://greasyfork.org/scripts/1952-uroverview-plus-uro';
  4336. }
  4337. else
  4338. {
  4339. var updateURL = 'https://chrome.google.com/webstore/detail/uroverview/amdamgkgchnbaopmphhjapmjcdghdphi';
  4340. }
  4341. tabbyHTML = '<b><a href="'+updateURL+'" target="_blank">UROverview Plus</a></b> <label id="_uroVersion">'+uroVersion+'</label>';
  4342. tabbyHTML += '<label id="_uroDebugMode">(dbg)</label>';
  4343. tabbyHTML += '<p><table border=0 width="100%"><tr>';
  4344. tabbyHTML += '<td valign="center" align="center" id="_tabSelectUserRequests"><a href="#" id="_linkSelectUserRequests" style="text-decoration:none;font-size:12px">URs</a></td>';
  4345. tabbyHTML += '<td valign="center" align="center" id="_tabSelectMapProblems"><a href="#" id="_linkSelectMapProblems" style="text-decoration:none;font-size:12px">MPs</a></td>';
  4346. tabbyHTML += '<td valign="center" align="center" id="_tabSelectPlaces"><a href="#" id="_linkSelectPlaces" style="text-decoration:none;font-size:12px">Places</a></td>';
  4347. tabbyHTML += '<td valign="center" align="center" id="_tabSelectCameras"><a href="#" id="_linkSelectCameras" style="text-decoration:none;font-size:12px">Cams</a></td>';
  4348. tabbyHTML += '<td valign="center" align="center" id="_tabSelectCWL"><a href="#" id="_linkSelectCWL" style="text-decoration:none;font-size:12px">CWL</a></td>';
  4349. tabbyHTML += '<td valign="center" align="center" id="_tabSelectMisc"><a href="#" id="_linkSelectMisc" style="text-decoration:none;font-size:12px">Misc</a></td>';
  4350. tabbyHTML += '</tr></table>';
  4351. uroControls.innerHTML = tabbyHTML;
  4352.  
  4353.  
  4354. uroCtrlURs = document.createElement('p');
  4355. uroCtrlMPs = document.createElement('p');
  4356. uroCtrlCameras = document.createElement('p');
  4357. uroCamWatchlist = document.createElement('p');
  4358. uroCtrlMisc = document.createElement('p');
  4359. uroAMList = document.createElement('div');
  4360. uroCtrlHides = document.createElement('div');
  4361. uroCtrlPlaces = document.createElement('p');
  4362.  
  4363. // UR controls tab
  4364. uroCtrlURs.id = "uroCtrlURs";
  4365. uroCtrlURs.innerHTML = '<br>';
  4366.  
  4367. uroCtrlURs.innerHTML += '<b>Hide URs by type:</b><br>';
  4368. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterWazeAuto">Waze Automatic</input><br>';
  4369. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectTurn">Incorrect turn</input><br>';
  4370. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectAddress">Incorrect address</input><br>';
  4371. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectRoute">Incorrect route</input><br>';
  4372. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingRoundabout">Missing roundabout</input><br>';
  4373. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterGeneralError">General error</input><br>';
  4374. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterTurnNotAllowed">Turn not allowed</input><br>';
  4375. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectJunction">Incorrect junction</input><br>';
  4376. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingBridgeOverpass">Missing bridge overpass</input><br>';
  4377. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterWrongDrivingDirection">Wrong driving direction</input><br>';
  4378. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingExit">Missing exit</input><br>';
  4379. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingRoad">Missing road</input><br>';
  4380. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterBlockedRoad">Blocked road</input><br>';
  4381. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingLandmark">Missing Landmark</input><br>';
  4382. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterUndefined">Undefined</input><br>';
  4383.  
  4384. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<i>Specially tagged types</i><br>';
  4385. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterRoadworks">[ROADWORKS]</input><br>';
  4386. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterConstruction">[CONSTRUCTION]</input><br>';
  4387. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterClosure">[CLOSURE]</input><br>';
  4388. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterEvent">[EVENT]</input><br>';
  4389. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbFilterNote">[NOTE]</input><br><br>';
  4390. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbInvertURFilter">Invert operation of type filters?</input><br>';
  4391. uroCtrlURs.innerHTML += '<hr>';
  4392. uroCtrlURs.innerHTML += '<br><b>Hide by state:</b><br>';
  4393. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterOpenUR">Open</input><br>';
  4394. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterClosedUR">Closed</input><br>';
  4395. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterSolved">Solved</input><br>';
  4396. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterUnidentified">Not identified</input><br><br>';
  4397.  
  4398.  
  4399. uroCtrlURs.innerHTML += '<br><b>Filter URs by age of submission:</b><br>';
  4400. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMinAgeFilter">Hide URs less than </input>';
  4401. 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>';
  4402. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMaxAgeFilter">Hide URs more than </input>';
  4403. 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>';
  4404.  
  4405. uroCtrlURs.innerHTML += '<br><b>Filter URs by description text:</b><br>';
  4406. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURDescriptionMustBePresent">Hide</input> or ';
  4407. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURDescriptionMustBeAbsent">show</input> URs with no description<br>';
  4408. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableKeywordMustBePresent">Hide URs not including </input>';
  4409. uroCtrlURs.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textKeywordPresent"><br>';
  4410. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableKeywordMustBeAbsent">Hide URs including </input>';
  4411. uroCtrlURs.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textKeywordAbsent"><br>';
  4412. uroCtrlURs.innerHTML += '&nbsp;&nbsp;<input type="checkbox" id="_cbCaseInsensitive">Case-insensitive matches?</input><br>';
  4413. uroCtrlURs.innerHTML += '<br><b>Hide URs by comments/following:</b><br>';
  4414. uroCtrlURs.innerHTML += '<i>With comments from me?</i><br>';
  4415. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyComments">Yes </input>';
  4416. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideAnyComments">No</input><br>';
  4417. uroCtrlURs.innerHTML += '<i>If last comment made by me?</i><br>';
  4418. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfLastCommenter">Yes </input>';
  4419. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfNotLastCommenter">No </input><br>';
  4420. uroCtrlURs.innerHTML += '<i>If last comment made by UR reporter?</i><br>';
  4421. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfReporterLastCommenter">Yes </input>';
  4422. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfReporterNotLastCommenter">No</input><br>';
  4423.  
  4424. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMinCommentsFilter">With less than </input>';
  4425. uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMinComments"> comments<br>';
  4426. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMaxCommentsFilter">With more than </input>';
  4427. uroCtrlURs.innerHTML += '<input type="number" min="0" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMaxComments"> comments<br>';
  4428. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyFollowed">Ones I am or </input>';
  4429. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyUnfollowed">am not following</input><br>';
  4430.  
  4431. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableCommentAgeFilter2">Last comment less than </input>';
  4432. 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>';
  4433. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableCommentAgeFilter">Last comment more than </input>';
  4434. 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>';
  4435. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURUserIDFilter">Without comments from user</input>';
  4436. uroCtrlURs.innerHTML += '<select id="_selectURUserID" style="width:80%; height:22px;"></select><br>';
  4437. uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURResolverIDFilter">Not resolved by user</input>';
  4438. uroCtrlURs.innerHTML += '<select id="_selectURResolverID" style="width:80%; height:22px;"></select>';
  4439. uroCtrlURs.innerHTML += '<br><br><input type="checkbox" id="_cbNoFilterForTaggedURs"><b>Don\'t apply state/age filters to tagged URs</b></input><br>';
  4440.  
  4441.  
  4442. // Map problems controls tab
  4443. uroCtrlMPs.id = "uroCtrlMPs";
  4444. uroCtrlMPs.innerHTML = '<br>';
  4445.  
  4446. uroCtrlMPs.innerHTML += '<b>Filter MPs by type:</b><br>';
  4447. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterMissingJunction">Missing junction</input><br>';
  4448. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterMissingRoad">Missing road</input><br>';
  4449. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterCrossroadsJunctionMissing">Missing crossroads</input><br>';
  4450. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterDrivingDirectionMismatch">Driving direction mismatch</input><br>';
  4451. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterRoadTypeMismatch">Road type mismatch</input><br>';
  4452. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterRestrictedTurn">Restricted turn might be allowed</input><br>';
  4453. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterUnknownProblem">Unknown problem type</input><br><br>';
  4454. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterTurnProblem">Turn Problems</input><br><br>';
  4455.  
  4456. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterReopenedProblem">Reopened Problems</input><br><br>';
  4457. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbInvertMPFilter">Invert operation of type filters?</input><br>';
  4458.  
  4459. uroCtrlMPs.innerHTML += '<br><b>Hide closed/solved/unidentified Problems:</b><br>';
  4460. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterClosed">Closed</input><br>';
  4461. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterSolved">Solved</input><br>';
  4462. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterUnidentified">Not identified</input><br><br>';
  4463.  
  4464. uroCtrlMPs.innerHTML += '<br><b>Hide problems (not turn) by severity:</b><br>';
  4465. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterLowSeverity">Low</input>&nbsp;&nbsp;';
  4466. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterMediumSeverity">Medium</input>&nbsp;&nbsp;';
  4467. uroCtrlMPs.innerHTML += '<input type="checkbox" id="_cbMPFilterHighSeverity">High</input><br>';
  4468. // Places filtering tab
  4469. uroCtrlPlaces.id = "uroCtrlPlaces";
  4470. uroCtrlPlaces.innerHTML = 'Places filter list being populated, please wait...';
  4471.  
  4472.  
  4473. // Camera controls tab
  4474. uroCtrlCameras.id = "uroCtrlCameras";
  4475. uroCtrlCameras.innerHTML = '<br><b>Show Cameras by creator:</b><br>';
  4476. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowWorldCams" checked>world_* users</input><br>';
  4477. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowUSACams" checked>usa_* users</input><br>';
  4478. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowNonWorldCams" checked>other users</input><br>';
  4479. uroCtrlCameras.innerHTML += '<br><input type="checkbox" id="_cbShowOnlyMyCams">Show ONLY cameras created/edited by me</input><br>';
  4480.  
  4481.  
  4482. uroCtrlCameras.innerHTML += '<br><b>Show Cameras by approval status:</b><br>';
  4483. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowApprovedCams" checked>approved</input><br>';
  4484. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowNonApprovedCams" checked>non-approved</input><br>';
  4485. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowOlderCreatedNonApproved"> if created more than </input>';
  4486. 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>';
  4487. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowOlderUpdatedNonApproved"> if updated more than </input>';
  4488. 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>';
  4489.  
  4490. uroCtrlCameras.innerHTML += '<br><b>Show Cameras by type:</b><br>';
  4491. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowSpeedCams" checked>Speed</input><br>';
  4492. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowIfMPHSpeedSet" checked> with MPH speeds</input><br>';
  4493. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowIfKPHSpeedSet" checked> with KM/H speeds</input><br>';
  4494. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbShowIfNoSpeedSet" checked> with no speed</input><br>';
  4495. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowRedLightCams" checked>Red Light</input><br>';
  4496. uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowDummyCams" checked>Dummy</input><br>';
  4497.  
  4498. uroCtrlCameras.innerHTML += '<br><b>Hide Cameras by creator:</b><br>';
  4499. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByMe">me</input>';
  4500. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank0">L1</input>';
  4501. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank1">L2</input>';
  4502. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank2">L3</input>';
  4503. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank3">L4</input>';
  4504. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank4">L5</input>';
  4505. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideCreatedByRank5">L6</input>';
  4506.  
  4507. uroCtrlCameras.innerHTML += '<br><b>Hide Cameras by updater:</b><br>';
  4508. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByMe">me</input>';
  4509. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank0">L1</input>';
  4510. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank1">L2</input>';
  4511. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank2">L3</input>';
  4512. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank3">L4</input>';
  4513. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank4">L5</input>';
  4514. uroCtrlCameras.innerHTML += '&nbsp;&nbsp;&nbsp;<input type="checkbox" id="_cbHideUpdatedByRank5">L6</input>';
  4515.  
  4516. uroCtrlCameras.innerHTML += '<br><br><b><input type="checkbox" id="_cbHideCWLCams">Hide cameras on CWL</input></b><br>';
  4517.  
  4518. // Camera watchlist tab
  4519. uroCamWatchlist.id = "uroCamWatchlist";
  4520. uroCWLUpdateHTML();
  4521. // Misc controls tab
  4522. uroCtrlMisc.id = "uroCtrlMisc";
  4523. uroCtrlMisc.innerHTML = '<br><b>Use default conversation markers:</b><br>';
  4524. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbNativeConvoMarkers" checked>in public WME</input><br>';
  4525. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbNativeBetaConvoMarkers" checked>in beta WME</input><br>';
  4526. uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbCommentCount">Show comment count on UR markers</input></b><br>';
  4527.  
  4528. uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbURBackfill">Backfill UR data</input></b><br>';
  4529. uroCtrlMisc.innerHTML += '<br><br><b>Use custom marker for URs tagged as:</b><br>';
  4530. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomRoadworksMarkers">[ROADWORKS]</input><br>';
  4531. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomConstructionMarkers">[CONSTRUCTION]</input><br>';
  4532. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomClosuresMarkers">[CLOSURE]</input><br>';
  4533. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomEventsMarkers">[EVENT]</input><br>';
  4534. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomNotesMarkers">[NOTE]</input><br>';
  4535. uroCtrlMisc.innerHTML += '<br><br><b>Disable popup for:</b><br>';
  4536. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitURPopup">URs</input><br>';
  4537. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitMPPopup">MPs</input><br>';
  4538. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitCamPopup">Cameras</input><br>';
  4539. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitSegPopup">Segments</input><br>';
  4540. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitLandmarkPopup">Landmarks</input><br>';
  4541. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitPUPopup">Place Updates</input><br>';
  4542.  
  4543. uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbWhiteBackground">Use custom background colour</input></b><br>';
  4544. uroCtrlMisc.innerHTML += 'R:<input type="number" min="0" max="255" value="255" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCustomBackgroundRed">';
  4545. uroCtrlMisc.innerHTML += 'G:<input type="number" min="0" max="255" value="255" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCustomBackgroundGreen">';
  4546. uroCtrlMisc.innerHTML += 'B:<input type="number" min="0" max="255" value="255" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCustomBackgroundBlue"><br>';
  4547.  
  4548. uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbHideAMLayer">Hide Area Manager polygons</input></b><br>';
  4549.  
  4550. uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbDisablePlacesFiltering">Disable Places filtering</input></b><br>';
  4551.  
  4552. uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbDisablePendingQuestions">Disable UR Pending Questions confirmation</input></b><br>';
  4553. uroCtrlMisc.innerHTML += '<br><b>Enable integrated scripts:</b><br>';
  4554. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbEnableDTE">Drive Tab Enhancement</input><br>';
  4555. uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbEnableSRS">Select Roundabout Segments</input><br>';
  4556.  
  4557. uroCtrlMisc.innerHTML += '<br><br><b>Settings backup/restore:</b><br>';
  4558. uroCtrlMisc.innerHTML += '<input type="button" id="_btnSettingsToText" value="Backup">&nbsp;&nbsp;&nbsp;';
  4559. uroCtrlMisc.innerHTML += '<input type="button" id="_btnTextToSettings" value="Restore">&nbsp;&nbsp;|&nbsp;&nbsp;';
  4560. uroCtrlMisc.innerHTML += '<input type="button" id="_btnClearSettingsText" value="Clear"><br>';
  4561. uroCtrlMisc.innerHTML += '<textarea id="_txtSettings" value="">';
  4562. // footer for tabs container
  4563. uroCtrlHides.id = 'uroCtrlHides';
  4564. uroCtrlHides.innerHTML = '<input type="button" id="_btnUndoLastHide" value="Undo last hide">&nbsp;&nbsp;&nbsp;';
  4565. uroCtrlHides.innerHTML += '<input type="button" id="_btnClearSessionHides" value="Undo all hides"><p>';
  4566.  
  4567. // footer for AM list
  4568. uroAMList.id = 'uroAMList';
  4569.  
  4570. window.addEventListener("beforeunload", uroSaveSettings, false);
  4571. uroRealWazeBits();
  4572. }
  4573.  
  4574.  
  4575. function dteAddHeader()
  4576. {
  4577. rlcObj = document.getElementsByClassName("result-list-container");
  4578. if(typeof rlcObj == "undefined") return;
  4579. if(typeof rlcObj[0].children[0] == "undefined") return;
  4580. if(typeof rlcObj[0].children[0].innerHTML == "undefined") return;
  4581. var thtml = rlcObj[0].children[0].innerHTML;
  4582. if(thtml.indexOf('Full drive history') == -1)
  4583. {
  4584. thtml += '<br><br><i><small>Full drive history goes back to '+dteOldestFullDrive.toDateString()+'</small></i>';
  4585. rlcObj[0].children[0].innerHTML = thtml;
  4586. }
  4587. }
  4588.  
  4589.  
  4590. function dteSetNewTabLength()
  4591. {
  4592. uroAddLog('altering ResultsPerPage parameter...');
  4593.  
  4594. var t = document.getElementById('sidepanel-drives');
  4595. t.style.overflow = 'auto';
  4596. t.style.height = (window.innerHeight * 0.6) + 'px';
  4597.  
  4598. baseloc = 'https://'+window.location.hostname+Waze.Config.api_base+'/Archive/MyList?minDistance=1000';
  4599.  
  4600. var a = new XMLHttpRequest();
  4601. var idxCheckFullDrive = 0;
  4602. var fullDrives = 0;
  4603. var foundMissingDrive = false;
  4604.  
  4605. while(!foundMissingDrive)
  4606. {
  4607. uroSetStyleDisplay(uroUserTabId,'none');
  4608. var loc = baseloc+'&offset='+fullDrives+'&count=5';
  4609. uroAddLog('requesting '+loc);
  4610. a.open('GET',loc,false);
  4611. a.send();
  4612. var b = JSON.parse(a.responseText);
  4613. var loadedDrives = b.archives.objects.length;
  4614. uroAddLog('received '+loadedDrives+' drives');
  4615. if(loadedDrives != 5) foundMissingDrive = true;
  4616.  
  4617. for(var loop=0; loop < loadedDrives; loop++)
  4618. {
  4619. if(b.archives.objects[loop].hasFullSession == false) foundMissingDrive = true;
  4620. else
  4621. {
  4622. fullDrives++;
  4623. dteOldestFullDrive = new Date(b.archives.objects[loop].startTime);
  4624. }
  4625. }
  4626. }
  4627.  
  4628. uroAddLog(fullDrives+' full drives in history');
  4629. uroAddLog('oldest drives are on '+dteOldestFullDrive.toDateString());
  4630. if(fullDrives < 5)
  4631. {
  4632. fullDrives = 5;
  4633. uroAddLog('insufficient full drives, using standard drives tab');
  4634. }
  4635. else if(fullDrives > 50)
  4636. {
  4637. uroAddLog('too many full drives for a single tab page, splitting over multiple pages...');
  4638. fullDrives = Math.ceil(fullDrives/Math.ceil(fullDrives/50));
  4639. }
  4640. uroSetStyleDisplay(uroUserTabId,'');
  4641. if((dteOldestFullDrive - dteEpoch) > 0)
  4642. {
  4643. uroAddLog('updating drives tab...');
  4644. W.map.controls[dteControlsIdx].sidePanelView.ResultsPerPage = fullDrives;
  4645. setInterval(dteAddHeader,250);
  4646. }
  4647. }
  4648.  
  4649.  
  4650. function srsSelect()
  4651. {
  4652. if(selectionManager.selectedItems[0].fid == null) rbtID = selectionManager.selectedItems[0].model.attributes.junctionID;
  4653. else rbtID = selectionManager.selectedItems[0].attributes.junctionID;
  4654. uroAddLog('selecting roundabout ID '+rbtID);
  4655. selectionManager.selectControl.unselectAll();
  4656.  
  4657. for(var slIdx=0; slIdx < W.map.segmentLayer.features.length; slIdx++)
  4658. {
  4659. if(W.map.segmentLayer.features[slIdx].fid == null)
  4660. {
  4661. junctionID = W.map.segmentLayer.features[slIdx].model.attributes.junctionID;
  4662. segID = W.map.segmentLayer.features[slIdx].model.attributes.id;
  4663. }
  4664. else
  4665. {
  4666. junctionID = W.map.segmentLayer.features[slIdx].attributes.junctionID;
  4667. segID = W.map.segmentLayer.features[slIdx].fid;
  4668. }
  4669. if(junctionID == rbtID)
  4670. {
  4671. uroAddLog('...adding segment '+segID);
  4672. selectionManager.selectControl.select(W.map.segmentLayer.features[slIdx]);
  4673. }
  4674. }
  4675. }
  4676.  
  4677.  
  4678. function srsCheckSidePanel()
  4679. {
  4680. if(selectionManager.selectedItems.length == 0) return;
  4681. if(document.getElementById('srsCtrl') != null) return;
  4682. var junctionID = null;
  4683. if(selectionManager.selectedItems[0].fid == null) junctionID = selectionManager.selectedItems[0].model.attributes.junctionID;
  4684. else junctionID = selectionManager.selectedItems[0].attributes.junctionID;
  4685. if(junctionID == null) return;
  4686. srsCtrl = document.createElement('section');
  4687. srsCtrl.id = 'srsCtrl';
  4688. srsCtrl.innerHTML = '<button id="srsButton" class="btn">Select roundabout</button>';
  4689. document.getElementById('segment-edit-general').appendChild(srsCtrl);
  4690. uroSetOnClick('srsButton',srsSelect);
  4691. }
  4692.  
  4693. uroBootstrap();