WME Road Shield Assistant

Adds shield information display to WME

目前为 2021-06-13 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name WME Road Shield Assistant
  3. // @namespace https://gf.qytechs.cn/en/users/286957-skidooguy
  4. // @version 2021.05.11.01
  5. // @description Adds shield information display to WME
  6. // @author SkiDooGuy
  7. // @include /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor\/?.*$/
  8. // @require https://gf.qytechs.cn/scripts/24851-wazewrap/code/WazeWrap.js
  9. // @grant none
  10. // @contributionURL https://github.com/WazeDev/Thank-The-Authors
  11. // ==/UserScript==
  12.  
  13. /* global W */
  14. /* global WazeWrap */
  15. /* global $ */
  16. /* global OL */
  17. /* global _ */
  18. /* global require */
  19.  
  20. const debugLvl = 1;
  21. const GF_LINK = 'https://gf.qytechs.cn/en/scripts/425050-wme-road-shield-assisstant';
  22. const FORUM_LINK = 'https://www.waze.com/forum/viewtopic.php?f=1851&t=315748';
  23. const RSA_UPDATE_NOTES = `<b>NEW:</b><br>
  24. - Moved "Include Ramps" to top section as it applies to all features<br><br>
  25. <b>FIXES:</b><br>
  26. - <br><br>`;
  27.  
  28. const RoadAbbr = {
  29. // Canada
  30. // 5000: Trans-Canada Hwy
  31. // 5063: Ontario - Regional Hwy - Generic
  32. 40: {
  33. 'Ontario': {
  34. 'Hwy': 5063,
  35. 'Trans-Canada Hwy': 5000
  36. }
  37. },
  38.  
  39. // US
  40. 235: {
  41. "Alabama": {
  42. 'I-': 5,
  43. 'US-': 6,
  44. "CR-": 2002,
  45. "SR-": 2019
  46. },
  47. "Alaska": {
  48. 'I-': 5,
  49. 'US-': 6,
  50. "CR-": 2002,
  51. "SR-": 2017
  52. },
  53. "Arizona": {
  54. 'I-': 5,
  55. 'US-': 6,
  56. "CR-": 2002,
  57. "SR-": 2022
  58. },
  59. "Arkansas": {
  60. 'I-': 5,
  61. 'US-': 6,
  62. "CR-": 2002,
  63. "AR-": 2020,
  64. "AR-$1 SPUR": 2020
  65. },
  66. "California": {
  67. 'I-': 5,
  68. 'US-': 6,
  69. "CR-": 2002,
  70. "SH-": 1082,
  71. "SR-": 1082
  72. },
  73. "Colorado": {
  74. 'I-': 5,
  75. 'US-': 6,
  76. "CR-": 2002,
  77. "SH-": 2025,
  78. "SR-": 2025
  79. },
  80. "Connecticut": {
  81. 'I-': 5,
  82. 'US-': 6,
  83. "CR-": 2002,
  84. "SH-": 2027,
  85. "SR-": 2027
  86. },
  87. "Delaware": {
  88. 'I-': 5,
  89. 'US-': 6,
  90. "CR-": 2002,
  91. "SH-": 7,
  92. "SR-": 7
  93. },
  94. "District of Columbia": {
  95. "DC-": 7
  96. },
  97. "Florida": {
  98. 'I-': 5,
  99. 'US-': 6,
  100. "CR-": 2002,
  101. "SH-": 2030,
  102. "SR-": 2030
  103. },
  104. "Georgia": {
  105. 'I-': 5,
  106. 'US-': 6,
  107. "CR-": 2002,
  108. "SH-": 2036,
  109. "SR-": 2036
  110. },
  111. "Hawaii": {
  112. 'I-': 5,
  113. 'US-': 6,
  114. "CR-": 2002,
  115. "SH-": 2041,
  116. "SR-": 2041
  117. },
  118. "Idaho": {
  119. 'I-': 5,
  120. 'US-': 6,
  121. "CH-": 2002,
  122. "CR-": 2002,
  123. "SH-": 2043,
  124. "SR-": 2043
  125. },
  126. "Illinois": {
  127. 'I-': 5,
  128. 'US-': 6,
  129. "CH-": 2002,
  130. "CR-": 2002,
  131. "SH-": 2044,
  132. "SR-": 2044
  133. },
  134. "Indiana": {
  135. 'I-': 5,
  136. 'US-': 6,
  137. "CH-": 2002,
  138. "CR-": 2002,
  139. "SH-": 2045,
  140. "SR-": 2045,
  141. "IN-": 2045
  142. },
  143. "Iowa": {
  144. 'I-': 5,
  145. 'US-': 6,
  146. "CH-": 2002,
  147. "CR-": 2002,
  148. "SH-": 7,
  149. "SR-": 7,
  150. "IA-": 7
  151. },
  152. "Kansas": {
  153. 'I-': 5,
  154. 'US-': 6,
  155. "CH-": 2002,
  156. "CR-": 2002,
  157. "SH-": 2046,
  158. "SR-": 2046,
  159. "K-": 2046
  160. },
  161. "Kentucky": {
  162. 'I-': 5,
  163. 'US-': 6,
  164. "CH-": 2002,
  165. "CR-": 2002,
  166. "SH-": 7,
  167. "SR-": 7,
  168. },
  169. "Louisiana": {
  170. 'I-': 5,
  171. 'US-': 6,
  172. "CH-": 2002,
  173. "CR-": 2002,
  174. "SH-": 1117,
  175. "SR-": 1117,
  176. "LA-": 1117,
  177. "LA SPUR": 1115
  178. },
  179. "Maine": {
  180. 'I-': 5,
  181. 'US-': 6,
  182. "CH-": 2002,
  183. "CR-": 2002,
  184. "SH-": 2051,
  185. "SR-": 2051
  186. },
  187. "Maryland": {
  188. 'I-': 5,
  189. 'US-': 6,
  190. "CH-": 2002,
  191. "CR-": 2002,
  192. "SH-": 2053,
  193. "SR-": 2053,
  194. "MD-": 2053
  195. },
  196. "Massachusetts": {
  197. 'I-': 5,
  198. 'US-': 6,
  199. "CH-": 2002,
  200. "CR-": 2002,
  201. "SH-": 2055,
  202. "SR-": 2055
  203. },
  204. "Michigan": {
  205. 'I-': 5,
  206. 'US-': 6,
  207. 'CR-': 2056,
  208. 'M-': 2056,
  209. 'SR-': 2056
  210. },
  211. "Minnesota": {
  212. 'I-': 5,
  213. 'US-': 6,
  214. "CH-": 2002,
  215. "CR-": 2002,
  216. "SH-": 2060,
  217. "SR-": 2060,
  218. "MN-": 2060
  219. },
  220. "Mississippi": {
  221. 'I-': 5,
  222. 'US-': 6,
  223. "SH-": 7,
  224. "SR-": 7,
  225. "MS-": 7
  226. },
  227. "Missouri": {
  228. 'I-': 5,
  229. 'US-': 6,
  230. "CH-": 2002,
  231. "CR-": 2002,
  232. "SH-": 2061,
  233. "SR-": 2061,
  234. "MO-": 2061
  235. },
  236. "Montana": {
  237. 'I-': 5,
  238. 'US-': 6,
  239. "CH-": 2002,
  240. "CR-": 2002,
  241. "SH-": 2063,
  242. "SR-": 2063
  243. },
  244. "Nebraska": {
  245. 'I-': 5,
  246. 'US-': 6,
  247. "CH-": 2002,
  248. "CR-": 2002,
  249. "SH-": 7,
  250. "SR-": 7,
  251. "L-": 7,
  252. "N-": 7,
  253. "S-": 7
  254. },
  255. "Nevada": {
  256. 'I-': 5,
  257. 'US-': 6,
  258. "CH-": 2002,
  259. "CR-": 2002,
  260. "SH-": 2086,
  261. "SR-": 2086
  262. },
  263. "New Hampshire": {
  264. 'I-': 5,
  265. 'US-': 6,
  266. "CH-": 2002,
  267. "CR-": 2002,
  268. "SH-": 2076,
  269. "SR-": 2076
  270. },
  271. "New Jersey": {
  272. 'I-': 5,
  273. 'US-': 6,
  274. "CH-": 2002,
  275. "CR-": 2002,
  276. "SH-": 7,
  277. "SR-": 7
  278. },
  279. "New Mexico": {
  280. 'I-': 5,
  281. 'US-': 6,
  282. "CH-": 2002,
  283. "CR-": 2002,
  284. "SH-": 2085,
  285. "SR-": 2085
  286. },
  287. "New York": {
  288. 'I-': 5,
  289. 'US-': 6,
  290. "CH-": 2002,
  291. "CR-": 2002,
  292. "SH-": 2087,
  293. "SR-": 2087,
  294. "NY-": 2087,
  295. "NY SPUR": 2087
  296. },
  297. "North Carolina": {
  298. 'I-': 5,
  299. 'US-': 6,
  300. "CH-": 2002,
  301. "CR-": 2002,
  302. "SH-": 2065,
  303. "SR-": 2065
  304. },
  305. "North Dakota": {
  306. 'I-': 5,
  307. 'US-': 6,
  308. "CH-": 2002,
  309. "CR-": 2002,
  310. "SH-": 2070,
  311. "SR-": 2070,
  312. "ND-": 2070
  313. },
  314. "Ohio": {
  315. 'I-': 5,
  316. 'US-': 6,
  317. "CH-": 2002,
  318. "CR-": 2002,
  319. "SH-": 2095,
  320. "SR-": 2095
  321. },
  322. "Oklahoma": {
  323. 'I-': 5,
  324. 'US-': 6,
  325. "SH-": 2097,
  326. "SR-": 2097
  327. },
  328. "Oregon": {
  329. 'I-': 5,
  330. 'US-': 6,
  331. "CH-": 2002,
  332. "CR-": 2002,
  333. "SH-": 2099,
  334. "SR-": 2099
  335. },
  336. "Pennsylvania": {
  337. 'I-': 5,
  338. 'US-': 6,
  339. "CH-": 2002,
  340. "CR-": 2002,
  341. "SH-": 2101,
  342. "SR-": 2101
  343. },
  344. "Rhode Island": {
  345. 'I-': 5,
  346. 'US-': 6,
  347. "CH-": 2002,
  348. "CR-": 2002,
  349. "SH-": 2108,
  350. "SR-": 2108
  351. },
  352. "South Carolina": {
  353. 'I-': 5,
  354. 'US-': 6,
  355. "CH-": 2002,
  356. "CR-": 2002,
  357. "SH-": 2109,
  358. "SR-": 2109,
  359. "SC-": 2109
  360. },
  361. "South Dakota": {
  362. 'I-': 5,
  363. 'US-': 6,
  364. "CH-": 2002,
  365. "CR-": 2002,
  366. "SH-": 2114,
  367. "SR-": 2114,
  368. "SD-": 2114
  369. },
  370. "Tennessee": {
  371. 'I-': 5,
  372. 'US-': 6,
  373. "CH-": 2002,
  374. "CR-": 2002,
  375. "SH-": 2115,
  376. "SR-": 2115
  377. },
  378. "Texas": {
  379. 'I-': 5,
  380. 'US-': 6,
  381. "SH-": 2117,
  382. "SR-": 2117
  383. },
  384. "Utah": {
  385. 'I-': 5,
  386. 'US-': 6,
  387. "CH-": 2002,
  388. "CR-": 2002,
  389. "SH-": 2127,
  390. "SR-": 2127
  391. },
  392. "Vermont": {
  393. 'I-': 5,
  394. 'US-': 6,
  395. "CH-": 2002,
  396. "CR-": 2002,
  397. "SH-": 2131,
  398. "SR-": 2131
  399. },
  400. "Virginia": {
  401. 'I-': 5,
  402. 'US-': 6,
  403. "CH-": 2002,
  404. "CR-": 2002,
  405. "SH-": 2128,
  406. "SR-": 2128
  407. },
  408. "Washington": {
  409. 'I-': 5,
  410. 'US-': 6,
  411. "CH-": 2002,
  412. "CR-": 2002,
  413. "SH-": 2133,
  414. "SR-": 2133
  415. },
  416. "West Virginia": {
  417. 'I-': 5,
  418. 'US-': 6,
  419. "CH-": 2002,
  420. "CR-": 2002,
  421. "SH-": 2138,
  422. "SR-": 2138,
  423. "WV-": 2138,
  424. },
  425. "Wisconsin": {
  426. 'I-': 5,
  427. 'US-': 6,
  428. "CH-": 2137,
  429. "CR-": 2137,
  430. "SH-": 2135,
  431. "SR-": 2135,
  432. "WIS-": 2135,
  433. "WIS SPUR": 2135
  434. },
  435. "Wyoming": {
  436. 'I-': 5,
  437. 'US-': 6,
  438. "CH-": 2002,
  439. "CR-": 2002,
  440. "SH-": 2143,
  441. "SR-": 2143,
  442. "WY-": 2143,
  443. }
  444. }
  445. }
  446. const Strings = {
  447. 'en': {
  448. 'enableScript': 'Script enabled',
  449. 'HighSegShields': 'Segments with Shields',
  450. 'HighSegShieldsClr': 'Segments with Shields',
  451. 'ShowSegShields': 'Show Segment Shields on Map',
  452. 'SegShieldMissing': 'Segments that might be missing shields',
  453. 'SegShieldMissingClr': 'Segments that might be missing shields',
  454. 'SegShieldError': "Segments that have shields but maybe shouldn't",
  455. 'SegShieldErrorClr': "Segments that have shields but maybe shouldn't",
  456. 'HighNodeShields': 'Nodes with Shields (TG)',
  457. 'HighNodeShieldsClr': 'Nodes with Shields (TG)',
  458. 'ShowNodeShields': 'Show Node Shield Info',
  459. 'ShowExitShields': 'Include turn icons (if exists)',
  460. 'ShowTurnTTS': 'Include TTS',
  461. 'AlertTurnTTS': 'Alert if TTS is different from default',
  462. 'NodeShieldMissing': 'Nodes that might be missing shields',
  463. 'NodeShieldMissingClr': 'Nodes that might be missing shields',
  464. 'resetSettings': 'Reset Settings',
  465. 'disabledFeat': '(Feature not configured for this country)',
  466. 'ShowTowards': 'Include Towards (if exists)',
  467. 'ShowVisualInst': 'Include Visual Instruction',
  468. 'SegHasDir': 'Shields with direction',
  469. 'SegHasDirClr': 'Shields with direction',
  470. 'SegInvDir': 'Shields without direction',
  471. 'SegInvDirClr': 'Shields without direction',
  472. 'IconHead': 'Map Icons',
  473. 'HighlightHead': 'Highlights',
  474. 'HighlightColors': 'Highlight Colors',
  475. 'ShowRamps': 'Include Ramps'
  476. },
  477. 'en-us': {
  478. 'enableScript': 'Script enabled',
  479. 'HighSegShields': 'Segments with Shields',
  480. 'HighSegShieldsClr': 'Segments with Shields',
  481. 'ShowSegShields': 'Show Segment Shields on Map',
  482. 'SegShieldMissing': 'Segments that might be missing shields',
  483. 'SegShieldMissingClr': 'Segments that might be missing shields',
  484. 'SegShieldError': "Segments that have shields but maybe shouldn't",
  485. 'SegShieldErrorClr': "Segments that have shields but maybe shouldn't",
  486. 'HighNodeShields': 'Nodes with Shields (TG)',
  487. 'HighNodeShieldsClr': 'Nodes with Shields (TG)',
  488. 'ShowNodeShields': 'Show Node Shield Info',
  489. 'ShowExitShields': 'Include turn icons (if exists)',
  490. 'ShowTurnTTS': 'Include TTS',
  491. 'AlertTurnTTS': 'Alert if TTS is different from default',
  492. 'NodeShieldMissing': 'Nodes that might be missing shields',
  493. 'NodeShieldMissingClr': 'Nodes that might be missing shields',
  494. 'resetSettings': 'Reset Settings',
  495. 'disabledFeat': '(Feature not configured for this country)',
  496. 'ShowTowards': 'Include Towards (if exists)',
  497. 'ShowVisualInst': 'Include Visual Instruction',
  498. 'SegHasDir': 'Shields with direction',
  499. 'SegHasDirClr': 'Shields with direction',
  500. 'SegInvDir': 'Shields without direction',
  501. 'SegInvDirClr': 'Shields without direction',
  502. 'IconHead': 'Map Icons',
  503. 'HighlightHead': 'Highlights',
  504. 'HighlightColors': 'Highlight Colors',
  505. 'ShowRamps': 'Include Ramps'
  506. },
  507. 'es-419' : {
  508. 'enableScript': 'Script habilitado',
  509. 'HighSegShields': 'Segmentos con escudos',
  510. 'HighSegShieldsClr': 'Segmentos con escudos',
  511. 'ShowSegShields': 'Mostrar escudos de segmentos en el mapa',
  512. 'SegShieldMissing': 'Segmentos a los que les pueden faltar escudos',
  513. 'SegShieldMissingClr': 'Segmentos a los que les pueden faltar escudos',
  514. 'SegShieldError': "Segmentos que tienen escudos y quizá no deberían",
  515. 'SegShieldErrorClr': "Segmentos que tienen escudos y quizá no deberían",
  516. 'HighNodeShields': 'Nodos con escudos (TG)',
  517. 'HighNodeShieldsClr': 'Nodos con escudos (TG)',
  518. 'ShowNodeShields': 'Mostrar Info de Escudo en Nodo',
  519. 'ShowExitShields': 'Incluir iconos de giro (si existen)',
  520. 'ShowTurnTTS': 'Incuir TTS',
  521. 'AlertTurnTTS': 'Alertar si TTS fue modificado',
  522. 'NodeShieldMissing': 'Nodos a los que les pueden faltar escudos',
  523. 'NodeShieldMissingClr': 'Nodos a los que les pueden faltar escudos',
  524. 'resetSettings': 'Reiniciar ajustes',
  525. 'disabledFeat': '(Funcionalidad no configurada para ese país)',
  526. 'ShowTowards': 'Incluir dirección (si existe)',
  527. 'ShowVisualInst': 'Incluir instrucción visual',
  528. 'SegHasDir': 'Escudos con dirección',
  529. 'SegHasDirClr': 'Escudos con dirección',
  530. 'SegInvDir': 'Escudos sin dirección',
  531. 'SegInvDirClr': 'Escudos sin dirección',
  532. 'IconHead': 'Iconos en mapa',
  533. 'HighlightHead': 'Destacar',
  534. 'HighlightColors': 'Reseña de Colores',
  535. 'ShowRamps': 'Incluir Rampas'
  536. }
  537. }
  538.  
  539. let rsaSettings;
  540. let UpdateObj;
  541. let rsaMapLayer;
  542. let rsaIconLayer;
  543. let LANG;
  544.  
  545. console.log('RSA: initializing...');
  546.  
  547. function rsaBootstrap(tries = 0) {
  548. if (W && W.map && W.model && W.loginManager.user && $ && WazeWrap.Ready) {
  549. initRSA();
  550. } else if (tries < 500) {
  551. setTimeout(() => {
  552. rsaBootstrap(tries + 1);
  553. }, 200);
  554. } else {
  555. console.error('RSA: Failed to load');
  556. }
  557. }
  558.  
  559. function initRSA() {
  560. UpdateObj = require('Waze/Action/UpdateObject');
  561.  
  562. const rsaCss = [
  563. '.rsa-wrapper {position:relative;width:100%;font-size:12px;font-family:"Rubik", "Boing-light", sans-serif;user-select:none;}',
  564. '.rsa-section-wrapper {display:block;width:100%;padding:4px;}',
  565. '.rsa-section-wrapper.border {border-bottom:1px solid grey;margin-bottom:5px;}',
  566. '.rsa-header {font-weight:bold;}',
  567. '.rsa-option-container {padding:3px;}',
  568. '.rsa-option-container.no-display {display:none;}',
  569. '.rsa-option-container.sub {display:none;margin-left:10px;}',
  570. 'input[type="checkbox"].rsa-checkbox {display:inline-block;position:relative;top:3px;vertical-align:top;margin:0;}',
  571. 'input[type="color"].rsa-color-input {display:inline-block;position:relative;width:20px;padding:0px 1px;border:0px;vertical-align:top;cursor:pointer;}',
  572. 'input[type="color"].rsa-color-input:focus {outline-width:0;}',
  573. 'label.rsa-label {display:inline-block;position:relative;max-width:80%;vertical-align:top;font-weight:normal;padding-left:5px;word-wrap:break-word;}'
  574. ].join(' ');
  575.  
  576. const $rsaTab = $('<div>');
  577. $rsaTab.html = ([
  578. `<div class='rsa-wrapper' id='rsa-tab-wrapper'>
  579. <div style='margin-bottom:5px;border-bottom:1px solid black;'>
  580. <span style='font-weight:bold;'>
  581. <a href='https://www.waze.com/forum/viewtopic.php?f=1851&t=315748' target='_blank' style='text-decoration:none;'>Road Shield Assistant</a>
  582. </span> - v${GM_info.script.version}
  583. </div>
  584. <div class='rsa-option-container'>
  585. <input type=checkbox class='rsa-checkbox' id='rsa-enableScript' />
  586. <label class='rsa-label' for='rsa-enableScript'><span id='rsa-text-enableScript' /></label>
  587. </div>
  588. <div class='rsa-option-container'>
  589. <input type=checkbox class='rsa-checkbox' id='rsa-ShowRamps' />
  590. <label class='rsa-label' for='rsa-ShowRamps'><span id='rsa-text-ShowRamps' /></label>
  591. </div>
  592. <div id='rsa-text-IconHead' class='rsa-header' />
  593. <div style='border-top:2px solid black;'>
  594. <div class='rsa-option-container'>
  595. <input type=checkbox class='rsa-checkbox' id='rsa-ShowSegShields' />
  596. <label class='rsa-label' for='rsa-ShowSegShields'><span id='rsa-text-ShowSegShields' /></label>
  597. </div>
  598. </div>
  599. <div id='rsa-text-HighlightHead' class='rsa-header' />
  600. <div style='border-top:2px solid black;'>
  601. <div class='rsa-option-container'>
  602. <input type=checkbox class='rsa-checkbox' id='rsa-HighNodeShields' />
  603. <label class='rsa-label' for='rsa-HighNodeShields'><span id='rsa-text-HighNodeShields' /></label>
  604. </div>
  605. <div class='rsa-option-container'>
  606. <input type=checkbox class='rsa-checkbox' id='rsa-HighSegShields' />
  607. <label class='rsa-label' for='rsa-HighSegShields'><span id='rsa-text-HighSegShields' /></label>
  608. </div>
  609. <div class='rsa-option-container'>
  610. <input type=checkbox class='rsa-checkbox' id='rsa-SegHasDir' />
  611. <label class='rsa-label' for='rsa-SegHasDir'><span id='rsa-text-SegHasDir' /></label>
  612. </div>
  613. <div class='rsa-option-container'>
  614. <input type=checkbox class='rsa-checkbox' id='rsa-SegInvDir' />
  615. <label class='rsa-label' for='rsa-SegInvDir'><span id='rsa-text-SegInvDir' /></label>
  616. </div>
  617. <div class='rsa-option-container'>
  618. <input type=checkbox class='rsa-checkbox' id='rsa-SegShieldMissing' />
  619. <label class='rsa-label' for='rsa-SegShieldMissing'><span id='rsa-text-SegShieldMissing' /></label>
  620. </div>
  621. <div class='rsa-option-container'>
  622. <input type=checkbox class='rsa-checkbox' id='rsa-SegShieldError' />
  623. <label class='rsa-label' for='rsa-SegShieldError'><span id='rsa-text-SegShieldError' /></label>
  624. </div>
  625.  
  626. <div class='rsa-option-container no-display'>
  627. <input type=checkbox class='rsa-checkbox' id='rsa-NodeShieldMissing' />
  628. <label class='rsa-label' for='rsa-NodeShieldMissing'><span id='rsa-text-NodeShieldMissing' /></label>
  629. </div>
  630. <div class='rsa-option-container no-display'>
  631. <input type=checkbox class='rsa-checkbox' id='rsa-ShowNodeShields' />
  632. <label class='rsa-label' for='rsa-ShowNodeShields'><span id='rsa-text-ShowNodeShields' /></label>
  633. </div>
  634. <div class='rsa-option-container sub'>
  635. <input type=checkbox class='rsa-checkbox' id='rsa-ShowExitShields' />
  636. <label class='rsa-label' for='rsa-ShowExitShields'><span id='rsa-text-ShowExitShields' /></label>
  637. </div>
  638. <div class='rsa-option-container sub'>
  639. <input type=checkbox class='rsa-checkbox' id='rsa-ShowTurnTTS' />
  640. <label class='rsa-label' for='rsa-ShowTurnTTS'><span id='rsa-text-ShowTurnTTS' /></label>
  641. </div>
  642. <div class='rsa-option-container sub'>
  643. <input type=checkbox class='rsa-checkbox' id='rsa-ShowTowards' />
  644. <label class='rsa-label' for='rsa-ShowTowards'><span id='rsa-text-ShowTowards' /></label>
  645. </div>
  646. <div class='rsa-option-container sub'>
  647. <input type=checkbox class='rsa-checkbox' id='rsa-ShowVisualInst' />
  648. <label class='rsa-label' for='rsa-ShowVisualInst'><span id='rsa-text-ShowVisualInst' /></label>
  649. </div>
  650. <div class='rsa-option-container sub'>
  651. <input type=checkbox class='rsa-checkbox' id='rsa-AlertTurnTTS' />
  652. <label class='rsa-label' for='rsa-AlertTurnTTS'><span id='rsa-text-AlertTurnTTS' /></label>
  653. </div>
  654. </div>
  655. <div id='rsa-text-HighlightColors' class='rsa-header' />
  656. <div style='border-top:2px solid black;'>
  657. <div class='rsa-option-container'>
  658. <input type=color class='rsa-color-input' id='rsa-HighSegClr' />
  659. <label class='rsa-label' for='rsa-HighSegClr'><span id='rsa-text-HighSegShieldsClr' /></label>
  660. </div>
  661. <div class='rsa-option-container'>
  662. <input type=color class='rsa-color-input' id='rsa-SegHasDirClr' />
  663. <label class='rsa-label' for='rsa-SegHasDirClr'><span id='rsa-text-SegHasDirClr' /></label>
  664. </div>
  665. <div class='rsa-option-container'>
  666. <input type=color class='rsa-color-input' id='rsa-SegInvDirClr' />
  667. <label class='rsa-label' for='rsa-SegInvDirClr'><span id='rsa-text-SegInvDirClr' /></label>
  668. </div>
  669. <div class='rsa-option-container'>
  670. <input type=color class='rsa-color-input' id='rsa-MissSegClr' />
  671. <label class='rsa-label' for='rsa-MissSegClr'><span id='rsa-text-SegShieldMissingClr' /></label>
  672. </div>
  673. <div class='rsa-option-container'>
  674. <input type=color class='rsa-color-input' id='rsa-ErrSegClr' />
  675. <label class='rsa-label' for='rsa-ErrSegClr'><span id='rsa-text-SegShieldErrorClr' /></label>
  676. </div>
  677. <div class='rsa-option-container'>
  678. <input type=color class='rsa-color-input' id='rsa-HighNodeClr' />
  679. <label class='rsa-label' for='rsa-HighNodeClr'><span id='rsa-text-HighNodeShieldsClr' /></label>
  680. </div>
  681. <div class='rsa-option-container no-display'>
  682. <input type=color class='rsa-color-input' id='rsa-MissNodeClr' />
  683. <label class='rsa-label' for='rsa-MissNodeClr'><span id='rsa-text-NodeShieldMissingClr' /></label>
  684. </div>
  685. </div>
  686. <div style='border-top:2px solid black;'>
  687. <div class='rsa-option-container'>
  688. <input type=button id='rsa-resetSettings' />
  689. </div>
  690. </div>
  691. </div>`
  692. ].join(' '));
  693. new WazeWrap.Interface.Tab('RSA', $rsaTab.html, setupOptions);
  694. $(`<style type="text/css">${rsaCss}</style>`).appendTo('head');
  695. WazeWrap.Interface.ShowScriptUpdate(GM_info.script.name, GM_info.script.version, RSA_UPDATE_NOTES, GF_LINK, FORUM_LINK);
  696. console.log('RSA: loaded');
  697. }
  698.  
  699. async function setupOptions() {
  700. await loadSettings();
  701.  
  702. // Create OL layer for display
  703. rsaMapLayer = new OpenLayers.Layer.Vector('rsaMapLayer', { uniqueName: 'rsaMapLayer' });
  704. W.map.addLayer(rsaMapLayer);
  705. rsaMapLayer.setVisibility(true);
  706.  
  707. rsaIconLayer = new OpenLayers.Layer.Vector('rsaIconLayer', { uniqueName: 'rsaIconLayer' });
  708. W.map.addLayer(rsaIconLayer);
  709. rsaIconLayer.setVisibility(true);
  710.  
  711. // Set user options
  712. function setEleStatus() {
  713. setChecked('rsa-enableScript', rsaSettings.enableScript);
  714. setChecked('rsa-HighSegShields', rsaSettings.HighSegShields);
  715. setChecked('rsa-ShowSegShields', rsaSettings.ShowSegShields);
  716. setChecked('rsa-SegShieldMissing', rsaSettings.SegShieldMissing);
  717. setChecked('rsa-SegShieldError', rsaSettings.SegShieldError);
  718. setChecked('rsa-HighNodeShields', rsaSettings.HighNodeShields);
  719. setChecked('rsa-ShowNodeShields', rsaSettings.ShowNodeShields);
  720. setChecked('rsa-ShowExitShields', rsaSettings.ShowExitShields);
  721. setChecked('rsa-ShowTurnTTS', rsaSettings.ShowTurnTTS);
  722. setChecked('rsa-AlertTurnTTS', rsaSettings.AlertTurnTTS);
  723. setChecked('rsa-ShowTowards', rsaSettings.ShowTowards);
  724. setChecked('rsa-ShowVisualInst', rsaSettings.ShowVisualInst);
  725. setChecked('rsa-NodeShieldMissing', rsaSettings.NodeShieldMissing);
  726. setChecked('rsa-SegHasDir', rsaSettings.SegHasDir);
  727. setChecked('rsa-SegInvDir', rsaSettings.SegInvDir);
  728. setChecked('rsa-ShowRamps', rsaSettings.ShowRamps);
  729. setValue('rsa-HighSegClr', rsaSettings.HighSegClr);
  730. setValue('rsa-MissSegClr', rsaSettings.MissSegClr);
  731. setValue('rsa-ErrSegClr', rsaSettings.ErrSegClr);
  732. setValue('rsa-HighNodeClr', rsaSettings.HighNodeClr);
  733. setValue('rsa-MissNodeClr', rsaSettings.MissNodeClr);
  734. setValue('rsa-SegHasDirClr', rsaSettings.SegHasDirClr);
  735. setValue('rsa-SegInvDirClr', rsaSettings.SegInvDirClr);
  736.  
  737. function setChecked(ele, status) {
  738. $(`#${ele}`).prop('checked', status);
  739. }
  740.  
  741. function setValue(ele, value) {
  742. const inputElem = $(`#${ele}`);
  743. inputElem.attr('value', value);
  744. // inputElem.css('border', `1px solid ${value}`);
  745. }
  746. }
  747.  
  748. // Register event listeners
  749. WazeWrap.Events.register('selectionchanged', null, tryScan);
  750. WazeWrap.Events.register('moveend', null, tryScan);
  751. WazeWrap.Events.register('afteraction', null, tryScan);
  752. WazeWrap.Events.register('moveend', null, checkOptions);
  753.  
  754. setEleStatus();
  755.  
  756. $('.rsa-checkbox').change(function () {
  757. let settingName = $(this)[0].id.substr(4);
  758. rsaSettings[settingName] = this.checked;
  759.  
  760. // Check to ensure highlight nodes and show node shields don't onverlap each other
  761. // if (settingName = 'ShowNodeShields') {
  762. // if (this.checked) {
  763. // $('rsa-HighNodeShields').prop('checked', false);
  764. // rsaSettings.HighNodeShields = false;
  765. // }
  766. // } else if (settingName = 'HighNodeShields') {
  767. // if (this.checked) {
  768. // $('rsa-ShowNodeShields').prop('checked', false);
  769. // rsaSettings.ShowNodeShields = false;
  770. // }
  771. // }
  772.  
  773. saveSettings();
  774.  
  775. removeHighlights();
  776. tryScan();
  777. });
  778. $('.rsa-color-input').change(function () {
  779. let settingName = $(this)[0].id.substr(4);
  780. rsaSettings[settingName] = this.value;
  781. saveSettings();
  782. setEleStatus();
  783. removeHighlights();
  784. tryScan();
  785. });
  786. // $('#rsa-ShowNodeShields').click(function() {
  787. // if (!getId('rsa-ShowNodeShields').checked) $('.rsa-option-container.sub').hide();
  788. // else $('.rsa-option-container.sub').show();
  789. // });
  790. $('#rsa-resetSettings').click(function() {
  791. const defaultSettings = {
  792. lastSaveAction: 0,
  793. enableScript: true,
  794. HighSegShields: false,
  795. ShowSegShields: true,
  796. SegShieldMissing: false,
  797. SegShieldError: false,
  798. SegHasDir: false,
  799. SegInvDir: false,
  800. HighNodeShields: true,
  801. ShowNodeShields: false,
  802. ShowExitShields: false,
  803. ShowTurnTTS: false,
  804. AlertTurnTTS: false,
  805. ShowTowards: false,
  806. ShowVisualInst: false,
  807. NodeShieldMissing: false,
  808. HighSegClr: '#0066ff',
  809. MissSegClr: '#00ff00',
  810. ErrSegClr: '#cc00ff',
  811. HighNodeClr: '#ff00bf',
  812. MissNodeClr: '#ff0000',
  813. SegHasDirClr: '#ffff00',
  814. SegInvDirClr: '#66ffff'
  815. }
  816.  
  817. rsaSettings = defaultSettings;
  818. saveSettings();
  819. setEleStatus();
  820. });
  821. // Add translated UI text
  822. LANG = I18n.currentLocale().toLowerCase();
  823. if (!Strings[LANG]) LANG = 'en';
  824. for (let i=0; i < Object.keys(Strings[LANG]).length; i++) {
  825. let key = Object.keys(Strings[LANG])[i]
  826. $(`#rsa-text-${key}`).text(Strings[LANG][key]);
  827. }
  828. $('#rsa-resetSettings').attr('value', Strings[LANG]['resetSettings']);
  829.  
  830. checkOptions();
  831. }
  832.  
  833. async function loadSettings() {
  834. const localSettings = $.parseJSON(localStorage.getItem('RSA_Settings'));
  835. const serverSettings = await WazeWrap.Remote.RetrieveSettings('RSA_Settings');
  836. if (!serverSettings) {
  837. console.error('RSA: Error communicating with WW settings server');
  838. }
  839.  
  840. const defaultSettings = {
  841. lastSaveAction: 0,
  842. enableScript: true,
  843. HighSegShields: false,
  844. ShowSegShields: true,
  845. SegShieldMissing: false,
  846. SegShieldError: false,
  847. SegHasDir: false,
  848. SegInvDir: false,
  849. HighNodeShields: true,
  850. ShowNodeShields: false,
  851. ShowExitShields: false,
  852. ShowTurnTTS: false,
  853. AlertTurnTTS: false,
  854. ShowTowards: false,
  855. ShowVisualInst: false,
  856. NodeShieldMissing: false,
  857. HighSegClr: '#0066ff',
  858. MissSegClr: '#00ff00',
  859. ErrSegClr: '#cc00ff',
  860. HighNodeClr: '#ff00bf',
  861. MissNodeClr: '#ff0000',
  862. SegHasDirClr: '#ffff00',
  863. SegInvDirClr: '#66ffff',
  864. ShowRamps: true
  865. };
  866.  
  867. rsaSettings = $.extend({}, defaultSettings, localSettings);
  868. if (serverSettings && serverSettings.lastSaveAction > rsaSettings.lastSaveAction) {
  869. $.extend(rsaSettings, serverSettings);
  870. // console.log('RSA: server settings used');
  871. } else {
  872. // console.log('RSA: local settings used');
  873. }
  874.  
  875. // If there is no value set in any of the stored settings then use the default
  876. Object.keys(defaultSettings).forEach((funcProp) => {
  877. if (!rsaSettings.hasOwnProperty(funcProp)) {
  878. rsaSettings[funcProp] = defaultSettings[funcProp];
  879. }
  880. });
  881. }
  882.  
  883. async function saveSettings() {
  884. const {
  885. enableScript,
  886. HighSegShields,
  887. ShowSegShields,
  888. SegShieldMissing,
  889. SegShieldError,
  890. HighNodeShields,
  891. ShowNodeShields,
  892. ShowExitShields,
  893. SegHasDir,
  894. SegInvDir,
  895. ShowTurnTTS,
  896. AlertTurnTTS,
  897. ShowTowards,
  898. ShowVisualInst,
  899. NodeShieldMissing,
  900. HighSegClr,
  901. MissSegClr,
  902. ErrSegClr,
  903. HighNodeClr,
  904. MissNodeClr,
  905. SegHasDirClr,
  906. SegInvDirClr,
  907. ShowRamps
  908. } = rsaSettings;
  909.  
  910. const localSettings = {
  911. lastSaveAction: Date.now(),
  912. enableScript,
  913. HighSegShields,
  914. ShowSegShields,
  915. SegShieldMissing,
  916. SegShieldError,
  917. HighNodeShields,
  918. ShowNodeShields,
  919. ShowExitShields,
  920. SegHasDir,
  921. SegInvDir,
  922. ShowTurnTTS,
  923. AlertTurnTTS,
  924. ShowTowards,
  925. ShowVisualInst,
  926. NodeShieldMissing,
  927. HighSegClr,
  928. MissSegClr,
  929. ErrSegClr,
  930. HighNodeClr,
  931. MissNodeClr,
  932. SegHasDirClr,
  933. SegInvDirClr,
  934. ShowRamps
  935. };
  936.  
  937. /* // Grab keyboard shortcuts and store them for saving
  938. for (const name in W.accelerators.Actions) {
  939. const {shortcut, group} = W.accelerators.Actions[name];
  940. if (group === 'wmelt') {
  941. let TempKeys = '';
  942. if (shortcut) {
  943. if (shortcut.altKey === true) {
  944. TempKeys += 'A';
  945. }
  946. if (shortcut.shiftKey === true) {
  947. TempKeys += 'S';
  948. }
  949. if (shortcut.ctrlKey === true) {
  950. TempKeys += 'C';
  951. }
  952. if (TempKeys !== '') {
  953. TempKeys += '+';
  954. }
  955. if (shortcut.keyCode) {
  956. TempKeys += shortcut.keyCode;
  957. }
  958. } else {
  959. TempKeys = '-1';
  960. }
  961. localSettings[name] = TempKeys;
  962. }
  963. }
  964.  
  965. // Required for the instant update of changes to the keyboard shortcuts on the UI
  966. rsaSettings = localSettings; */
  967.  
  968. if (localStorage) {
  969. localStorage.setItem('RSA_Settings', JSON.stringify(localSettings));
  970. }
  971. const serverSave = await WazeWrap.Remote.SaveSettings('RSA_Settings', localSettings);
  972.  
  973. if (serverSave === null) {
  974. console.warn('RSA: User PIN not set in WazeWrap tab');
  975. } else {
  976. if (serverSave === false) {
  977. console.error('RSA: Unable to save settings to server');
  978. }
  979. }
  980. }
  981.  
  982. function getId(ele) {
  983. return document.getElementById(ele);
  984. }
  985.  
  986. function checkOptions() {
  987. const countries = W.model.countries.getObjectArray();
  988.  
  989. if (countries.length < 1) {
  990. setTimeout(checkOptions(), 500);
  991. return;
  992. } else {
  993. let allowFeat = false;
  994.  
  995. for (let i=0; i < countries.length; i++) {
  996. if (RoadAbbr[countries[i].id]) allowFeat = true;
  997. }
  998.  
  999. if (!allowFeat) {
  1000. $(`#rsa-text-SegShieldMissing`).prop('checked', false);
  1001. $(`#rsa-text-SegShieldError`).prop('checked', false);
  1002. $(`#rsa-text-NodeShieldMissing`).prop('checked', false);
  1003.  
  1004. $(`#rsa-text-SegShieldMissing`).text(Strings[LANG]['SegShieldMissing'] + ' ' + Strings[LANG]['disabledFeat']);
  1005. $(`#rsa-text-SegShieldError`).text(Strings[LANG]['SegShieldError'] + ' ' + Strings[LANG]['disabledFeat']);
  1006. $(`#rsa-text-NodeShieldMissing`).text(Strings[LANG]['NodeShieldMissing'] + ' ' + Strings[LANG]['disabledFeat']);
  1007.  
  1008. $(`#rsa-SegShieldMissing`).prop('disabled', true);
  1009. $(`#rsa-SegShieldError`).prop('disabled', true);
  1010. $(`#rsa-NodeShieldMissing`).prop('disabled', true);
  1011.  
  1012. rsaSettings.SegShieldMissing = false;
  1013. rsaSettings.SegShieldError = false;
  1014. rsaSettings.NodeShieldMissing = false;
  1015. saveSettings();
  1016. } else {
  1017. $(`#rsa-text-SegShieldMissing`).prop('checked', rsaSettings.SegShieldMissing);
  1018. $(`#rsa-text-SegShieldError`).prop('checked', rsaSettings.SegShieldError);
  1019. $(`#rsa-text-NodeShieldMissing`).prop('checked', rsaSettings.NodeShieldMissing);
  1020.  
  1021. $(`#rsa-text-SegShieldMissing`).text(Strings[LANG]['SegShieldMissing']);
  1022. $(`#rsa-text-SegShieldError`).text(Strings[LANG]['SegShieldError']);
  1023. $(`#rsa-text-NodeShieldMissing`).text(Strings[LANG]['NodeShieldMissing']);
  1024.  
  1025. $(`#rsa-SegShieldMissing`).prop('disabled', false);
  1026. $(`#rsa-SegShieldError`).prop('disabled', false);
  1027. $(`#rsa-NodeShieldMissing`).prop('disabled', false);
  1028. }
  1029. }
  1030. }
  1031.  
  1032. function tryScan() {
  1033. if (!rsaSettings.enableScript) return;
  1034.  
  1035. function scanNode(node) {
  1036. let conSegs = node.attributes.segIDs;
  1037.  
  1038. for (let i=0; i < conSegs.length; i++) {
  1039. let seg1 = W.model.segments.getObjectById(conSegs[i]);
  1040. for (let j=0; j < conSegs.length; j++) {
  1041. let seg2 = W.model.segments.getObjectById(conSegs[j]);
  1042. processNode(node, seg1, seg2);
  1043. }
  1044. }
  1045. }
  1046.  
  1047. function scanSeg(seg, showInfo = false) {
  1048. processSeg(seg, showInfo);
  1049. }
  1050.  
  1051. removeHighlights();
  1052. let selFea = W.selectionManager.getSelectedFeatures();
  1053. if (selFea && selFea.length > 0) {
  1054. // if (selFea.model.type === 'segment') scanSeg(selFea.model, true);
  1055. } else {
  1056. // Scan all segments on screen
  1057. if(rsaSettings.ShowSegShields || rsaSettings.SegShieldMissing || rsaSettings.SegShieldError || rsaSettings.HighSegShields) {
  1058. _.each(W.model.segments.getObjectArray(), s => {
  1059. scanSeg(s);
  1060. });
  1061. }
  1062. // Scan all nodes on screen
  1063. if(rsaSettings.HighNodeShields || rsaSettings.ShowNodeShields) {
  1064. _.each(W.model.nodes.getObjectArray(), n => {
  1065. scanNode(n);
  1066. });
  1067. }
  1068. }
  1069. }
  1070.  
  1071. function processSeg(seg, showNode = false) {
  1072. let segAtt = seg.attributes;
  1073. let street = W.model.streets.getObjectById(segAtt.primaryStreetID);
  1074. let cityID = W.model.cities.getObjectById(street.cityID);
  1075. let stateName = W.model.states.getObjectById(cityID.attributes.stateID).name;
  1076. let countryID = cityID.attributes.countryID;
  1077. let candidate = isStreetCandidate(street, stateName, countryID);
  1078. let hasShield = street.signType !== null;
  1079.  
  1080. if (segAtt.roadType === 4 && !rsaSettings.ShowRamps) return;
  1081.  
  1082. // Display shield on map
  1083. if (hasShield && rsaSettings.ShowSegShields) displaySegShields(seg, street.signType, street.signText, street.direction);
  1084.  
  1085. // If candidate and has shield
  1086. if (candidate.isCandidate && hasShield && rsaSettings.HighSegShields) createHighlight(seg, rsaSettings.HighSegClr);
  1087.  
  1088. // If candidate and missing shield
  1089. if (candidate.isCandidate && !hasShield && rsaSettings.SegShieldMissing) createHighlight(seg, rsaSettings.MissSegClr);
  1090.  
  1091. // If not candidate and has shield
  1092. if (!candidate.isCandidate && hasShield && rsaSettings.SegShieldError) createHighlight(seg, rsaSettings.ErrSegClr);
  1093.  
  1094. // Highlight seg shields with direction
  1095. if (hasShield && street.direction && rsaSettings.SegHasDir) createHighlight(seg, rsaSettings.SegHasDirClr);
  1096. if (hasShield && !street.direction && rsaSettings.SegInvDir) createHighlight(seg, rsaSettings.SegInvDirClr);
  1097.  
  1098. if (showNode) {
  1099. let toNode = W.model.nodes.getObjectById(segAtt.toNode);
  1100. let fromNode = W.model.nodes.getObjectById(segAtt.fromNode);
  1101.  
  1102.  
  1103. function getInfo(node) {
  1104. let conSegs = node.attributes.segIDs;
  1105.  
  1106. for (let i=0; i < conSegs.length; i++) {
  1107. let seg1 = W.model.segments.getObjectById(conSegs[i]);
  1108. for (let j=0; j < conSegs.length; j++) {
  1109. let seg2 = W.model.segments.getObjectById(conSegs[j]);
  1110. let turn = W.model.getTurnGraph().getTurnThroughNode(node,seg1,seg2);
  1111. let turnData = turn.getTurnData();
  1112. let hasGuidance = turnData.hasTurnGuidance();
  1113.  
  1114. if (hasGuidance) {
  1115. let turnGuidance = turnData.getTurnGuidance();
  1116. let exitSigns = turnGuidance.getExitSigns(); // Returns array of objects
  1117. let roadShields = turnGuidance.getRoadShields(); // Returns object of objects
  1118. let TTS = turnGuidance.getTTS(); // Returns string
  1119. let towards = turnGuidance.getTowards(); // Returns string
  1120. let visualInstruct = turnGuidance.getVisualInstruction(); // Returns string
  1121. }
  1122. }
  1123. }
  1124. }
  1125. }
  1126. }
  1127.  
  1128. function processNode(node, seg1, seg2) {
  1129. let turn = W.model.getTurnGraph().getTurnThroughNode(node,seg1,seg2);
  1130. let turnData = turn.getTurnData();
  1131. let hasGuidence = turnData.hasTurnGuidance();
  1132.  
  1133. if (hasGuidence) {
  1134. let hasExitShield = turnData.turnGuidance.exitSigns.length > 0;
  1135. let hasShields = !$.isEmptyObject(turnData.turnGuidance.roadShields)
  1136.  
  1137. if(rsaSettings.HighNodeShields) {
  1138. createHighlight(node, rsaSettings.HighNodeClr);
  1139. }
  1140.  
  1141. if(rsaSettings.ShowNodeShields) {
  1142. displayNodeShields(node, turnData);
  1143. }
  1144. }
  1145. }
  1146.  
  1147. function isStreetCandidate(s, state, country) {
  1148. let info = {
  1149. isCandidate: false,
  1150. iconID: null
  1151. }
  1152.  
  1153. if (!RoadAbbr[country]) {
  1154. return info;
  1155. }
  1156.  
  1157. let name = s.name;
  1158. let abbrvs = RoadAbbr[country][state];
  1159.  
  1160. for (let i=0; i < Object.keys(abbrvs).length; i++) {
  1161. let abbr = Object.keys(abbrvs)[i];
  1162. // console.log('name: ' + name + ' abbr: ' + abbr);
  1163. if (name && name.includes(abbr)) {
  1164. info.isCandidate = true;
  1165. info.iconID = abbrvs[i];
  1166. }
  1167. }
  1168. // console.log(info);
  1169. return info;
  1170. }
  1171.  
  1172. function displayNodeShields(node, turnDat) {
  1173. if(debugLvl === 1) return;
  1174. const geo = node.geometry.clone();
  1175. const trnGuid = turnDat.getTurnGuidance();
  1176. const GUIDANCE = {};
  1177.  
  1178. // Obj of objs - RS-0: direction: string, text: string, type: shield number
  1179. GUIDANCE.shields = trnGuid.getRoadShields();
  1180. // Array of objects - 'text': string, 'type': shield number
  1181. if (rsaSettings.ShowExitShields) { GUIDANCE.exitsigns = trnGuid.getExitSigns(); }
  1182. // String
  1183. if (rsaSettings.ShowTurnTTS) { GUIDANCE.tts = trnGuid.getTTS(); }
  1184. // String
  1185. if (rsaSettings.ShowTowards) { GUIDANCE.towards = trnGuid.getTowards(); }
  1186. // String
  1187. if (rsaSettings.ShowVisualInst) { GUIDANCE.visualIn = trnGuid.getVisualInstruction(); }
  1188. if (rsaSettings.AlertTurnTTS) {}
  1189.  
  1190.  
  1191. const styleNode = {
  1192. //strokeColor: color,
  1193. strokeOpacity: 0.75,
  1194. strokeWidth: 4,
  1195. //fillColor: color,
  1196. fillOpacity: 0.75,
  1197. pointRadius: 3
  1198. }
  1199. const styleLabel = {
  1200. externalGraphic: 'https://renderer.gcp.wazestg.com/renderer/v1/signs/6',
  1201. graphicHeight: 30,
  1202. graphicWidth: 30,
  1203. label: 'TG',
  1204. fontSize: 12,
  1205. graphicZIndex: 700
  1206. };
  1207.  
  1208. // Array of points for line connecting node to display box
  1209. let points = [];
  1210.  
  1211. // Point coords
  1212. let pointNode = new OpenLayers.Geometry.Point(geo.x, geo.y);
  1213. points.push(pointNode);
  1214. // Label coords
  1215. let pointLabel = new OpenLayers.Geometry.Point(geo.x + LabelDistance(), geo.y + LabelDistance());
  1216. points.push(pointLabel);
  1217.  
  1218. // Point on node
  1219. var pointFeature = new OpenLayers.Feature.Vector(pointNode, null, styleNode);
  1220. rsaIconLayer.addFeatures([pointFeature]);
  1221.  
  1222. // Line between node and label
  1223. var newline = new OpenLayers.Geometry.LineString(points);
  1224. var lineFeature = new OpenLayers.Feature.Vector(newline, null, styleNode);
  1225. rsaIconLayer.addFeatures([lineFeature]);
  1226.  
  1227. // Label
  1228. var pointFeature = new OpenLayers.Feature.Vector(pointLabel, null, styleLabel);
  1229. rsaIconLayer.addFeatures([pointFeature]);
  1230. }
  1231.  
  1232. function displaySegShields(segment, shieldID, shieldText, shieldDir) {
  1233. if (W.map.getZoom() < 2) return;
  1234.  
  1235. const iconURL = `https://renderer-am.waze.com/renderer/v1/signs/${shieldID}?text=${shieldText}`;
  1236. let SegmentPoints = [];
  1237. let oldparam = {};
  1238. let labelDis = LabelDistance();
  1239.  
  1240. oldparam.x = null;
  1241. oldparam.y = null;
  1242. let AtLeastOne = false;
  1243. $.each(segment.geometry.getVertices(), function(idx, param) {
  1244. // Build a new segment with same geometry
  1245. SegmentPoints.push(new OpenLayers.Geometry.Point(param.x, param.y));
  1246.  
  1247. // Shield icon style
  1248. const style = {
  1249. externalGraphic: iconURL,
  1250. graphicWidth: 37,
  1251. graphicHeight: 37,
  1252. graphicYOffset: -20,
  1253. graphicZIndex: 650
  1254. };
  1255. // Direction label styel
  1256. const style2 = {
  1257. label: shieldDir !== null ? shieldDir : '',
  1258. fontColor: 'green',
  1259. labelOutlineColor: 'white',
  1260. labelOutlineWidth: 1,
  1261. fontSize: 12
  1262. };
  1263.  
  1264. if (oldparam.x !== null && oldparam.y !== null) {
  1265. if ( Math.abs(oldparam.x - param.x) > labelDis.space || Math.abs(oldparam.y - param.y) > labelDis.space || AtLeastOne === false) {
  1266. let centerparam = {};
  1267. centerparam.x = ((oldparam.x + param.x) / 2);
  1268. centerparam.y = ((oldparam.y + param.y) / 2);
  1269. if ( Math.abs(centerparam.x - param.x) > labelDis.space || Math.abs(centerparam.y - param.y) > labelDis.space || AtLeastOne === false) {
  1270. LabelPoint = new OpenLayers.Geometry.Point(centerparam.x, centerparam.y);
  1271. const pointFeature = new OpenLayers.Feature.Vector(LabelPoint, null, style);
  1272. // Create point for direction label below shield icon
  1273. const labelPoint2 = new OpenLayers.Geometry.Point(centerparam.x, centerparam.y - labelDis.label);
  1274. const imageFeature2 = new OpenLayers.Feature.Vector(labelPoint2, null, style2);
  1275. rsaIconLayer.addFeatures([pointFeature, imageFeature2]);
  1276. AtLeastOne = true;
  1277. }
  1278. }
  1279. }
  1280. oldparam.x = param.x;
  1281. oldparam.y = param.y;
  1282. });
  1283. }
  1284.  
  1285. function createHighlight(obj, color, overSized = false) {
  1286. const geo = obj.geometry.clone();
  1287. let isNode = obj.type == 'node';
  1288. let labelDis = LabelDistance();
  1289.  
  1290. if(isNode) {
  1291. const styleNode = {
  1292. strokeColor: color,
  1293. strokeOpacity: 0.75,
  1294. strokeWidth: 4,
  1295. fillColor: color,
  1296. fillOpacity: 0.75,
  1297. pointRadius: 3
  1298. }
  1299. const styleLabel = {
  1300. externalGraphic: 'https://renderer.gcp.wazestg.com/renderer/v1/signs/6?text=TG',
  1301. graphicHeight: 30,
  1302. graphicWidth: 30,
  1303. graphicZIndex: 700
  1304. };
  1305.  
  1306. let points = [];
  1307. // Point coords
  1308. let pointNode = new OpenLayers.Geometry.Point(geo.x, geo.y);
  1309. points.push(pointNode);
  1310. // Label coords
  1311. let pointLabel = new OpenLayers.Geometry.Point(geo.x + labelDis.label, geo.y + labelDis.label);
  1312. points.push(pointLabel);
  1313.  
  1314. // Point on node
  1315. var pointFeature = new OpenLayers.Feature.Vector(pointNode, null, styleNode);
  1316. rsaIconLayer.addFeatures([pointFeature]);
  1317.  
  1318. // Line between node and label
  1319. var newline = new OpenLayers.Geometry.LineString(points);
  1320. var lineFeature = new OpenLayers.Feature.Vector(newline, null, styleNode);
  1321. rsaIconLayer.addFeatures([lineFeature]);
  1322.  
  1323. // Label
  1324. var pointFeature = new OpenLayers.Feature.Vector(pointLabel, null, styleLabel);
  1325. rsaIconLayer.addFeatures([pointFeature]);
  1326. } else {
  1327. // console.log('seg highlight')
  1328. const style = {
  1329. strokeColor: color,
  1330. strokeOpacity: 0.75,
  1331. strokeWidth: 4,
  1332. fillColor: color,
  1333. fillOpacity: 0.75
  1334. }
  1335. const newFeat = new OpenLayers.Geometry.LineString(geo.components, {});
  1336. const newVector = new OpenLayers.Feature.Vector(newFeat, null, style);
  1337. rsaMapLayer.addFeatures([newVector]);
  1338. }
  1339. }
  1340.  
  1341. function removeHighlights() {
  1342. rsaMapLayer.removeAllFeatures();
  1343. rsaIconLayer.removeAllFeatures();
  1344. }
  1345.  
  1346. function LabelDistance() {
  1347. // Return object with two variables - label is the distance used to place the direction below the icon,
  1348. // space is the space between geo points needed to render another icon
  1349. let label_distance = {};
  1350. switch (W.map.getOLMap().getZoom()) {
  1351. case 9:
  1352. label_distance.label = 2;
  1353. label_distance.space = 20;
  1354. break;
  1355. case 8:
  1356. label_distance.label = 4;
  1357. label_distance.space = 20;
  1358. break;
  1359. case 7:
  1360. label_distance.label = 7;
  1361. label_distance.space = 20;
  1362. break;
  1363. case 6:
  1364. label_distance.label = 12;
  1365. label_distance.space = 30;
  1366. break;
  1367. case 5:
  1368. label_distance.label = 30;
  1369. label_distance.space = 30;
  1370. break;
  1371. case 4:
  1372. label_distance.label = 40;
  1373. label_distance.space = 40;
  1374. break;
  1375. case 3:
  1376. label_distance.label = 70;
  1377. label_distance.space = 70;
  1378. break;
  1379. case 2:
  1380. label_distance.label = 150;
  1381. label_distance.space = 200;
  1382. break;
  1383. case 1:
  1384. label_distance.label = 200;
  1385. label_distance.space = 250;
  1386. break;
  1387. }
  1388. return label_distance;
  1389. }
  1390.  
  1391. rsaBootstrap();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址