WME Color Speeds

Adds colors to road segments to show their speed

目前为 2024-04-16 提交的版本。查看 最新版本

  1. /* eslint-disable max-len */
  2. // ==UserScript==
  3. // @name WME Color Speeds
  4. // @name:fr WME Color Speeds
  5. // @version 2024.04.15.01
  6. // @description Adds colors to road segments to show their speed
  7. // @description:fr Colorisation des segments selon leurs vitesses.
  8. // @include https://www.waze.com/editor*
  9. // @include https://www.waze.com/*/editor*
  10. // @include https://beta.waze.com/editor*
  11. // @include https://beta.waze.com/*/editor*
  12. // @exclude https://www.waze.com/user*
  13. // @exclude https://www.waze.com/*/user*
  14. // @grant GM_xmlhttpRequest
  15. // @connect gf.qytechs.cn
  16. // @namespace https://gf.qytechs.cn/scripts/14044-wme-color-speeds
  17. // @require https://gf.qytechs.cn/scripts/24851-wazewrap/code/WazeWrap.js
  18. // @author Created by French Script Team, Maintained by WazeDev
  19. // @copyright Sebiseba, seb-d59 & DummyD2 - 2015-2019
  20. // ==/UserScript==
  21.  
  22. /* global W */
  23. /* global WazeWrap */
  24. /* global GM_info */
  25. /* global CSpeedsWaze */
  26. /* global I18n */
  27. /* global $ */
  28.  
  29. // *********************
  30. // ** DECLARATIONS **
  31. // *********************
  32.  
  33. // eslint-disable-next-line camelcase
  34. const scriptName = GM_info.script.name;
  35. // eslint-disable-next-line camelcase
  36. const currentVersion = GM_info.script.version;
  37. const changelogFrench = 'MIS À JOUR : Traduction française et typographie.<br><br>AMÉLIORÉ : Nouvelles infobulles (traduites).<br><br>AMÉLIORÉ : Outils de diagnostic cachés. Vroum vroum !<br><br>';
  38. const changelogEnglish = 'UPDATED: French translation and typography<br><br>ENHANCEMENT: New localized tooltips<br><br>ENHANCEMENT: Under the hood diagnostic tools. Vroom vroom<br><br>';
  39. // eslint-disable-next-line camelcase
  40. const greasyForkUrl = GM_info.script.namespace;
  41. const downloadUrl = 'https://gf.qytechs.cn/scripts/14044-wme-color-speeds/code/wme-color-speeds.user.js';
  42. const forumUrl = 'https://www.waze.com/forum/viewtopic.php?t=167387';
  43. // let oldScriptVersion;
  44. const debug = false;
  45. let WMECSpeeds = {};
  46. let loadStartTime;
  47. let scriptStartTime;
  48.  
  49. const iconUndo = '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';
  50. const iconDelete = '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';
  51. const iconSubmit = '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';
  52. const iconEdit = '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';
  53.  
  54. const colors = [
  55. '(255,0,128)', '(255,0,160)', '(255,0,192)', '(255,0,224)', '(255,0,255)', '(224,0,255)',
  56. '(192,0,255)', '(160,0,255)', '(128,0,255)', '(96,0,255)', '(64,0,255)', '(32,0,255)',
  57. '(0,0,255)', '(0,32,255)', '(0,64,255)', '(0,96,255)', '(0,128,255)', '(0,160,255)',
  58. '(0,192,255)', '(0,224,255)', '(0,255,255)', '(0,255,224)', '(0,255,192)', '(0,255,160)',
  59. '(0,255,128)', '(0,255,96)', '(0,255,64)', '(0,255,32)', '(0,255,0)', '(32,255,0)',
  60. '(64,255,0)', '(96,255,0)', '(128,255,0)', '(160,255,0)', '(192,255,0)', '(224,255,0)',
  61. '(255,255,0)', '(255,224,0)', '(255,192,0)', '(255,160,0)', '(255,128,0)', '(255,96,0)',
  62. '(255,64,0)', '(255,0,0)', 'Pink', 'LightPink', 'HotPink', 'DeepPink', 'PaleVioletRed',
  63. 'MediumVioletRed', 'LightSalmon', 'Salmon', 'DarkSalmon', 'LightCoral', 'IndianRed', 'Crimson',
  64. 'FireBrick', 'DarkRed', 'Red', 'OrangeRed', 'Tomato', 'Coral', 'DarkOrange', 'Orange', 'Yellow',
  65. 'LightYellow', 'LemonChiffon', 'LightGoldenrodYellow', 'PapayaWhip', 'Moccasin', 'PeachPuff',
  66. 'PaleGoldenrod', 'Khaki', 'DarkKhaki', 'Gold', 'Cornsilk', 'BlanchedAlmond', 'Bisque',
  67. 'NavajoWhite', 'Wheat', 'BurlyWood', 'Tan', 'RosyBrown', 'SandyBrown', 'Goldenrod',
  68. 'DarkGoldenrod', 'Peru', 'Chocolate', 'SaddleBrown', 'Sienna', 'Brown', 'Maroon',
  69. 'DarkOliveGreen', 'Olive', 'OliveDrab', 'YellowGreen', 'LimeGreen', 'Lime', 'LawnGreen',
  70. 'Chartreuse', 'GreenYellow', 'SpringGreen', 'MediumSpringGreen', 'LightGreen', 'PaleGreen',
  71. 'DarkSeaGreen', 'MediumAquamarine', 'MediumSeaGreen', 'SeaGreen', 'ForestGreen', 'Green',
  72. 'DarkGreen', 'Aqua', 'Cyan', 'LightCyan', 'PaleTurquoise', 'Aquamarine', 'Turquoise',
  73. 'MediumTurquoise', 'DarkTurquoise', 'LightSeaGreen', 'CadetBlue', 'DarkCyan', 'Teal',
  74. 'LightSteelBlue', 'PowderBlue', 'LightBlue', 'SkyBlue', 'LightSkyBlue', 'DeepSkyBlue',
  75. 'DodgerBlue', 'CornflowerBlue', 'SteelBlue', 'RoyalBlue', 'Blue', 'MediumBlue', 'DarkBlue',
  76. 'Navy', 'MidnightBlue', 'Lavender', 'Thistle', 'Plum', 'Violet', 'Orchid', 'Fuchsia',
  77. 'Magenta', 'MediumOrchid', 'MediumPurple', 'BlueViolet', 'DarkViolet', 'DarkOrchid',
  78. 'DarkMagenta', 'Purple', 'Indigo', 'DarkSlateBlue', 'RebeccaPurple', 'SlateBlue',
  79. 'MediumSlateBlue', 'Snow', 'Honeydew', 'MintCream', 'Azure', 'AliceBlue', 'GhostWhite',
  80. 'WhiteSmoke', 'Seashell', 'Beige', 'OldLace', 'FloralWhite', 'Ivory', 'AntiqueWhite',
  81. 'Linen', 'LavenderBlush', 'MistyRose', 'LightSlateGray', 'SlateGray', 'DarkSlateGray',
  82. 'White', '#EEE', 'Gainsboro', '#DDD', 'LightGrey', '#CCC', 'Silver', '#BBB', '#AAA',
  83. 'DarkGray', '#999', '#888', 'Gray', '#777', 'DimGray', '#666', '#555', '#444', '#333',
  84. '#222', '#111', 'Black'
  85. ];
  86.  
  87. // speedColors[unit][speed] = color //-----> Default
  88. WMECSpeeds.speedColors = {
  89. kmh: {
  90. 10: '#ff6232', 20: '#ff6232', 30: '#ff6232', 40: '#f9805a', 45: '#fc9a3c', 50: '#ffad2d', 60: '#fffc28', 70: '#afff23', 80: '#09ff34', 90: '#14ff88', 100: '#0fffdf', 110: '#0ac2ff', 130: '#076aff'
  91. },
  92. mph: {
  93. 5: '#ff6232', 10: '#ff6232', 15: '#ff6232', 20: '#f9805a', 25: '#fc9a3c', 30: '#ffad2d', 35: '#fffc28', 40: '#afff23', 45: '#09ff34', 50: '#14ff88', 55: '#0fffdf', 60: '#0ac2ff', 65: '#076aff', 70: '#0055dd', 75: '#0036db', 80: '#0b07ff', 85: '#8f07ff'
  94. },
  95. Others: '#f00'
  96. };
  97.  
  98. const colorsUS = {
  99. Alabama: {},
  100. Alaska: {},
  101. Arizona: {},
  102. Arkansas: {},
  103. California: {},
  104. Colorado: {},
  105. Connecticut: {},
  106. Delaware: {},
  107. District_of_Columbia: {},
  108. Florida: {},
  109. Georgia: {},
  110. Hawaii: {},
  111. Idaho: {},
  112. Illinois: {},
  113. Indiana: {},
  114. Iowa: {},
  115. Kansas: {},
  116. Kentucky: {},
  117. Louisiana: {},
  118. Maine: {},
  119. Maryland: {},
  120. Massachusetts: {},
  121. Michigan: {},
  122. Minnesota: {},
  123. Mississippi: {},
  124. Missouri: {},
  125. Montana: {},
  126. Nebraska: {},
  127. Nevada: {},
  128. New_Hampshire: {},
  129. New_Jersey: {},
  130. New_Mexico: {},
  131. New_York: {},
  132. North_Carolina: {},
  133. North_Dakota: {},
  134. Ohio: {},
  135. Oklahoma: {},
  136. Oregon: {},
  137. Pennsylvania: {},
  138. Rhode_Island: {},
  139. South_Carolina: {},
  140. South_Dakota: {},
  141. Tennessee: {},
  142. Texas: {},
  143. Utah: {},
  144. Vermont: {},
  145. Virginia: {},
  146. Washington: {},
  147. West_Virginia: {},
  148. Wisconsin: {},
  149. Wyoming: {},
  150. United_States_Minor_Outlying_Islands: {},
  151. United_States_Virgin_Islands: {}
  152. };
  153.  
  154. const multiplePalette = false;
  155. const paletteByCountry = false;
  156. let unit;
  157. let selectedState;
  158. let selectedCountry;
  159.  
  160. let mapLayer = [];
  161. let toggler;
  162. let groupToggler;
  163.  
  164. let zoom = 0;
  165. const RoadToScan = [3, 6, 7, 4, 2, 1, 22, 20, 17, 8, 999];
  166. // var RoadUpToStreet = [2,3,6,7];
  167. // var highway = [3,6,7];
  168.  
  169. const typeOfRoad = {
  170. 3: { name: 'Freeways', checked: true, zoom: 14 },
  171. 6: { name: 'Major Highway', checked: true, zoom: 14 },
  172. 7: { name: 'Minor Highway', checked: true, zoom: 14 },
  173. 4: { name: 'Ramps', checked: true, zoom: 15 },
  174. 2: { name: 'Primary Street', checked: false, zoom: 15 },
  175. 1: { name: 'Streets', checked: false, zoom: 16 },
  176. 22: { name: 'Narrow Streets', checked: false, zoom: 16 },
  177. 20: { name: 'Parking Lot Road', checked: false, zoom: 16 },
  178. 17: { name: 'Private Road', checked: false, zoom: 16 },
  179. 8: { name: 'Off Road', checked: false, zoom: 16 },
  180. 999: { name: 'Roundabout', checked: false, zoom: false }
  181. };
  182.  
  183. WMECSpeeds.typeOfRoad = typeOfRoad;
  184.  
  185. const roadTypeZoomInfo = {
  186. 3: { en: 'Freeway highlights require zoom of 14+', fr: 'Surligner les autoroutes nécessite un niveau de zoom supérieur ou égal à 14' },
  187. 6: { en: 'Major Highway highlights require zoom of 14+', fr: 'Surligner les routes majeures nécessite un niveau de zoom supérieur ou égal à 14' },
  188. 7: { en: 'Minor Highway highlights require zoom of 14+', fr: 'Surligner les routes mineures nécessite un niveau de zoom supérieur ou égal à 14' },
  189. 4: { en: 'Ramp highlights require zoom of 14+', fr: 'Surligner les bretelles nécessite un niveau de zoom supérieur ou égal à 14' },
  190. 2: { en: 'Primary Street highlights require zoom of 14+', fr: 'Surligner les rue principales nécessite un niveau de zoom supérieur ou égal à 14' },
  191. 1: { en: 'Street highlights require zoom of 16+', fr: 'Surligner les rues nécessite un niveau de zoom supérieur ou égal à 16' },
  192. 22: { en: 'Narrow Street highlights require zoom of 15+', fr: 'Surligner les rues étroites nécessite un niveau de zoom supérieur ou égal à 15' },
  193. 20: { en: 'Parking Lot Road highlights require zoom of 15+', fr: 'Surligner les voies de parking nécessite un niveau de zoom supérieur ou égal à 15' },
  194. 17: { en: 'Private Road highlights require zoom of 15+', fr: 'Surligner les voies privées nécessite un niveau de zoom supérieur ou égal à 15' },
  195. 8: { en: 'Off Road highlights require zoom of 15+', fr: 'Surligner les chemins de terre nécessite un niveau de zoom supérieur ou égal à 15' },
  196. 999: { en: 'Roundabouts are highlighted based on their Road Type', fr: 'Les ronds-points sont surlignés en fonction de leur type de route' }
  197. };
  198.  
  199. // 5: "Walking Trails",
  200. // 10: "Pedestrian Bw",
  201. // 14: "Ferry",
  202. // 16: "Stairway",
  203. // 17: "Private Road",
  204. // 18: "Railroad",
  205. // 19: "Runway/Taxiway"
  206. // 21: "Service Road"
  207.  
  208. // WMECSpeeds.selectedRoadType = [];
  209. /*
  210. const dashStyles = [
  211. 'Solid',
  212. 'ShortDash',
  213. 'ShortDot',
  214. 'ShortDashDot',
  215. 'ShortDashDotDot',
  216. 'Dot',
  217. 'Dash',
  218. 'LongDash',
  219. 'DashDot',
  220. 'LongDashDot',
  221. 'LongDashDotDot'
  222. ];
  223. */
  224. let CSI18n = 'en';
  225.  
  226. const CSlang = {
  227. 1: { fr: 'Vitesses&nbsp;:', en: 'Speeds:' },
  228. 2: { fr: 'Configuration des couleurs&nbsp;:', en: 'Color Control Panel:' },
  229. 3: { fr: 'Couleurs&nbsp;:', en: 'Colors:' },
  230. 4: { fr: 'Ajouter une vitesse', en: 'Add new speed' },
  231. 5: { fr: 'Supprimer', en: 'Delete' },
  232. 6: { fr: 'Annuler', en: 'Cancel' },
  233. 7: { fr: 'Autres', en: 'Others' },
  234. 8: { fr: 'Modifier', en: 'Edit' },
  235. 9: { fr: 'Type de route', en: 'Road type' },
  236. 10: { fr: 'Zoom', en: 'Zoom' },
  237. 11: { fr: 'Rouge&nbsp;:', en: 'Red:' },
  238. 12: { fr: 'Vert&nbsp;:', en: 'Green:' },
  239. 13: { fr: 'Bleu&nbsp;:', en: 'Blue:' },
  240. 14: { fr: 'Valider', en: 'Validate' },
  241. 15: { fr: 'Décalage&nbsp;:', en: 'Offset:' },
  242. 16: { fr: 'Opacité&nbsp;:', en: 'Opacity:' },
  243. 17: { fr: 'Épaisseur&nbsp;:', en: 'Thickness:' },
  244. 18: { fr: 'Rond-point', en: 'Roundabout' },
  245. 19: { fr: 'Une palette par pays', en: 'One palette by country' },
  246. 20: { fr: 'Une palette par état (USA uniquement)', en: 'One Palette by State (US only)' },
  247. 21: { fr: 'pour', en: 'for' },
  248. 22: { fr: 'Autoroute', en: 'Freeway' },
  249. 23: { fr: 'Route majeure', en: 'Major Highway' },
  250. 24: { fr: 'Route mineure', en: 'Minor Highway' },
  251. 25: { fr: 'Bretelle', en: 'Ramps' },
  252. 26: { fr: 'Rue principale', en: 'Primary Street' },
  253. 27: { fr: 'Rue', en: 'Street' },
  254. 28: { fr: 'Rue étroite', en: 'Narrow Street' },
  255. 29: { fr: 'Voie de parking', en: 'Parking Lot Road' },
  256. 30: { fr: 'Voie privée', en: 'Private Road' },
  257. 31: { fr: 'Chemin de terre', en: 'Off Road' },
  258. 32: { fr: 'Vitesses', en: 'Speeds' },
  259. 33: { fr: 'Couleurs', en: 'Colors' },
  260. };
  261.  
  262. WMECSpeeds.visibility = true;
  263.  
  264. const offsetValue = 3;
  265. const opacityValue = 0.8;
  266. const thicknessValue = 6;
  267. let newspeedColorDialog;
  268.  
  269. // **********************
  270. // ** HELPER FUNCTIONS **
  271. // **********************
  272.  
  273. function log(msg, obj) {
  274. if (obj == null) {
  275. // eslint-disable-next-line camelcase, no-undef
  276. console.log(`${GM_info.script.name} v${currentVersion} - ${msg}`);
  277. } else if (debug) {
  278. // eslint-disable-next-line camelcase, no-undef
  279. console.debug(`${GM_info.script.name} v${currentVersion} - ${msg} `, obj);
  280. }
  281. }
  282.  
  283. function getId(node) {
  284. return document.getElementById(node);
  285. }
  286.  
  287. function getElementsByClassName(classname, node) {
  288. node = node || document.body;
  289. return Array.from(node.querySelectorAll(`.${classname}`));
  290. }
  291.  
  292. function getFunctionWithArgs(func, args) {
  293. return (
  294. function() {
  295. const jsonArgs = JSON.stringify(args);
  296. return function() {
  297. args = JSON.parse(jsonArgs);
  298. func.apply(this, args);
  299. };
  300. }
  301. )();
  302. }
  303.  
  304. function IsJsonString(str) {
  305. try {
  306. JSON.parse(str);
  307. } catch (e) {
  308. return false;
  309. }
  310. return true;
  311. }
  312.  
  313. function cloneObj(obj) {
  314. const copy = JSON.parse(JSON.stringify(obj));
  315. return copy;
  316. }
  317.  
  318. function Rgb2String(rgb) {
  319. rgb = roundDecimals(rgb);
  320. return `rgb(${rgb.r},${rgb.g},${rgb.b})`;
  321. // return "rgb(" + Math.round(rgb.r) +","+ Math.round(rgb.g) +","+ Math.round(rgb.b) +")";
  322. }
  323.  
  324. function color2Rgb(c) {
  325. c = c.toLowerCase();
  326.  
  327. function parseRgb(arr) {
  328. const rgb = {
  329. r: parseInt(arr[0], 10) || 0,
  330. g: parseInt(arr[1], 10) || 0,
  331. b: parseInt(arr[2], 10) || 0,
  332. name: null
  333. };
  334. rgb.r = Math.min(255, rgb.r);
  335. rgb.g = Math.min(255, rgb.g);
  336. rgb.b = Math.min(255, rgb.b);
  337. if (debug) log(`Red: ${rgb.r}, Green: ${rgb.g}, Blue: ${rgb.b}`);
  338. return rgb;
  339. }
  340.  
  341. if (c.substr(0, 3) === 'rgb') {
  342. const arr = c
  343. .substring(3)
  344. .replace('(', '')
  345. .replace(')', '')
  346. .split(',')
  347. .map(val => val.trim());
  348.  
  349. if (arr.length === 3 && arr.every(val => !isNaN(val))) {
  350. const colorrgbs = getColorArr('rgbs');
  351. const colornames = getColorArr('names');
  352. const matchIndex = colorrgbs.findIndex(color => JSON.stringify(arr) === JSON.stringify(color));
  353.  
  354. if (matchIndex !== -1) {
  355. return {
  356. r: arr[0],
  357. g: arr[1],
  358. b: arr[2],
  359. name: colornames[matchIndex]
  360. };
  361. }
  362.  
  363. return parseRgb(arr);
  364. }
  365. } else {
  366. let colornames = getColorArr('names');
  367. const matchIndex = colornames.findIndex(name => c === name.toLowerCase());
  368.  
  369. if (matchIndex !== -1) {
  370. const colorrgbs = getColorArr('rgbs');
  371. if (debug) log(`${colornames}`);
  372. return {
  373. r: colorrgbs[matchIndex][0],
  374. g: colorrgbs[matchIndex][1],
  375. b: colorrgbs[matchIndex][2],
  376. name: colornames[matchIndex]
  377. };
  378. }
  379.  
  380. c = c.replace('#', '');
  381. const colorHex = getColorArr('hexs');
  382. const hexMatchIndex = colorHex.findIndex(hex => c === hex);
  383.  
  384. if (hexMatchIndex !== -1) {
  385. colornames = getColorArr('names');
  386. return { name: colornames[hexMatchIndex] };
  387. }
  388.  
  389. if (c.length === 3) {
  390. c = c[0] + c[0] + c[1] + c[1] + c[2] + c[2];
  391. }
  392.  
  393. const arr = [
  394. parseInt(c.substr(0, 2), 16),
  395. parseInt(c.substr(2, 2), 16),
  396. parseInt(c.substr(4, 2), 16)
  397. ];
  398. return parseRgb(arr);
  399. }
  400. return {
  401. r: 0,
  402. g: 0,
  403. b: 0,
  404. name: null
  405. };
  406. }
  407.  
  408. // eslint-disable-next-line consistent-return
  409. function getColorArr(x) {
  410. if (x === 'names') {
  411. return ['AliceBlue', 'AntiqueWhite', 'Aqua', 'Aquamarine', 'Azure', 'Beige', 'Bisque', 'Black', 'BlanchedAlmond',
  412. 'Blue', 'BlueViolet', 'Brown', 'BurlyWood', 'CadetBlue', 'Chartreuse', 'Chocolate', 'Coral', 'CornflowerBlue', 'Cornsilk', 'Crimson',
  413. 'Cyan', 'DarkBlue', 'DarkCyan', 'DarkGoldenRod', 'DarkGray', 'DarkGrey', 'DarkGreen', 'DarkKhaki', 'DarkMagenta', 'DarkOliveGreen',
  414. 'DarkOrange', 'DarkOrchid', 'DarkRed', 'DarkSalmon', 'DarkSeaGreen', 'DarkSlateBlue', 'DarkSlateGray', 'DarkSlateGrey', 'DarkTurquoise',
  415. 'DarkViolet', 'DeepPink', 'DeepSkyBlue', 'DimGray', 'DimGrey', 'DodgerBlue', 'FireBrick', 'FloralWhite', 'ForestGreen', 'Fuchsia',
  416. 'Gainsboro', 'GhostWhite', 'Gold', 'GoldenRod', 'Gray', 'Grey', 'Green', 'GreenYellow', 'HoneyDew', 'HotPink', 'IndianRed', 'Indigo',
  417. 'Ivory', 'Khaki', 'Lavender', 'LavenderBlush', 'LawnGreen', 'LemonChiffon', 'LightBlue', 'LightCoral', 'LightCyan',
  418. 'LightGoldenRodYellow', 'LightGray', 'LightGrey', 'LightGreen', 'LightPink', 'LightSalmon', 'LightSeaGreen', 'LightSkyBlue',
  419. 'LightSlateGray', 'LightSlateGrey', 'LightSteelBlue', 'LightYellow', 'Lime', 'LimeGreen', 'Linen', 'Magenta', 'Maroon',
  420. 'MediumAquaMarine', 'MediumBlue', 'MediumOrchid', 'MediumPurple', 'MediumSeaGreen', 'MediumSlateBlue', 'MediumSpringGreen',
  421. 'MediumTurquoise', 'MediumVioletRed', 'MidnightBlue', 'MintCream', 'MistyRose', 'Moccasin', 'NavajoWhite', 'Navy', 'OldLace',
  422. 'Olive', 'OliveDrab', 'Orange', 'OrangeRed', 'Orchid', 'PaleGoldenRod', 'PaleGreen', 'PaleTurquoise', 'PaleVioletRed',
  423. 'PapayaWhip', 'PeachPuff', 'Peru', 'Pink', 'Plum', 'PowderBlue', 'Purple', 'RebeccaPurple', 'Red', 'RosyBrown', 'RoyalBlue',
  424. 'SaddleBrown', 'Salmon', 'SandyBrown', 'SeaGreen', 'SeaShell', 'Sienna', 'Silver', 'SkyBlue', 'SlateBlue', 'SlateGray', 'SlateGrey',
  425. 'Snow', 'SpringGreen', 'SteelBlue', 'Tan', 'Teal', 'Thistle', 'Tomato', 'Turquoise', 'Violet', 'Wheat', 'White', 'WhiteSmoke',
  426. 'Yellow', 'YellowGreen'];
  427. }
  428. if (x === 'hexs') {
  429. return ['f0f8ff', 'faebd7', '00ffff', '7fffd4', 'f0ffff', 'f5f5dc', 'ffe4c4', '000000', 'ffebcd', '0000ff', '8a2be2', 'a52a2a', 'deb887',
  430. '5f9ea0', '7fff00', 'd2691e', 'ff7f50', '6495ed', 'fff8dc', 'dc143c', '00ffff', '00008b', '008b8b', 'b8860b', 'a9a9a9', 'a9a9a9', '006400',
  431. 'bdb76b', '8b008b', '556b2f', 'ff8c00', '9932cc', '8b0000', 'e9967a', '8fbc8f', '483d8b', '2f4f4f', '2f4f4f', '00ced1', '9400d3', 'ff1493',
  432. '00bfff', '696969', '696969', '1e90ff', 'b22222', 'fffaf0', '228b22', 'ff00ff', 'dcdcdc', 'f8f8ff', 'ffd700', 'daa520', '808080', '808080',
  433. '008000', 'adff2f', 'f0fff0', 'ff69b4', 'cd5c5c', '4b0082', 'fffff0', 'f0e68c', 'e6e6fa', 'fff0f5', '7cfc00', 'fffacd', 'add8e6', 'f08080',
  434. 'e0ffff', 'fafad2', 'd3d3d3', 'd3d3d3', '90ee90', 'ffb6c1', 'ffa07a', '20b2aa', '87cefa', '778899', '778899', 'b0c4de', 'ffffe0', '00ff00',
  435. '32cd32', 'faf0e6', 'ff00ff', '800000', '66cdaa', '0000cd', 'ba55d3', '9370db', '3cb371', '7b68ee', '00fa9a', '48d1cc', 'c71585', '191970',
  436. 'f5fffa', 'ffe4e1', 'ffe4b5', 'ffdead', '000080', 'fdf5e6', '808000', '6b8e23', 'ffa500', 'ff4500', 'da70d6', 'eee8aa', '98fb98', 'afeeee',
  437. 'db7093', 'ffefd5', 'ffdab9', 'cd853f', 'ffc0cb', 'dda0dd', 'b0e0e6', '800080', '663399', 'ff0000', 'bc8f8f', '4169e1', '8b4513', 'fa8072',
  438. 'f4a460', '2e8b57', 'fff5ee', 'a0522d', 'c0c0c0', '87ceeb', '6a5acd', '708090', '708090', 'fffafa', '00ff7f', '4682b4', 'd2b48c', '008080',
  439. 'd8bfd8', 'ff6347', '40e0d0', 'ee82ee', 'f5deb3', 'ffffff', 'f5f5f5', 'ffff00', '9acd32'];
  440. }
  441. if (x === 'rgbs') {
  442. return [[240, 248, 255], [250, 235, 215], [0, 255, 255], [127, 255, 212], [240, 255, 255], [245, 245, 220], [255, 228, 196], [0, 0, 0],
  443. [255, 235, 205], [0, 0, 255], [138, 43, 226], [165, 42, 42], [222, 184, 135], [95, 158, 160], [127, 255, 0], [210, 105, 30], [255, 127, 80],
  444. [100, 149, 237], [255, 248, 220], [220, 20, 60], [0, 255, 255], [0, 0, 139], [0, 139, 139], [184, 134, 11], [169, 169, 169], [169, 169, 169],
  445. [0, 100, 0], [189, 183, 107], [139, 0, 139], [85, 107, 47], [255, 140, 0], [153, 50, 204], [139, 0, 0], [233, 150, 122], [143, 188, 143],
  446. [72, 61, 139], [47, 79, 79], [47, 79, 79], [0, 206, 209], [148, 0, 211], [255, 20, 147], [0, 191, 255], [105, 105, 105], [105, 105, 105],
  447. [30, 144, 255], [178, 34, 34], [255, 250, 240], [34, 139, 34], [255, 0, 255], [220, 220, 220], [248, 248, 255], [255, 215, 0], [218, 165, 32],
  448. [128, 128, 128], [128, 128, 128], [0, 128, 0], [173, 255, 47], [240, 255, 240], [255, 105, 180], [205, 92, 92], [75, 0, 130], [255, 255, 240],
  449. [240, 230, 140], [230, 230, 250], [255, 240, 245], [124, 252, 0], [255, 250, 205], [173, 216, 230], [240, 128, 128], [224, 255, 255],
  450. [250, 250, 210], [211, 211, 211], [211, 211, 211], [144, 238, 144], [255, 182, 193], [255, 160, 122], [32, 178, 170], [135, 206, 250],
  451. [119, 136, 153], [119, 136, 153], [176, 196, 222], [255, 255, 224], [0, 255, 0], [50, 205, 50], [250, 240, 230], [255, 0, 255],
  452. [128, 0, 0], [102, 205, 170], [0, 0, 205], [186, 85, 211], [147, 112, 219], [60, 179, 113], [123, 104, 238], [0, 250, 154],
  453. [72, 209, 204], [199, 21, 133], [25, 25, 112], [245, 255, 250], [255, 228, 225], [255, 228, 181], [255, 222, 173], [0, 0, 128],
  454. [253, 245, 230], [128, 128, 0], [107, 142, 35], [255, 165, 0], [255, 69, 0], [218, 112, 214], [238, 232, 170], [152, 251, 152],
  455. [175, 238, 238], [219, 112, 147], [255, 239, 213], [255, 218, 185], [205, 133, 63], [255, 192, 203], [221, 160, 221], [176, 224, 230],
  456. [128, 0, 128], [102, 51, 153], [255, 0, 0], [188, 143, 143], [65, 105, 225], [139, 69, 19], [250, 128, 114], [244, 164, 96],
  457. [46, 139, 87], [255, 245, 238], [160, 82, 45], [192, 192, 192], [135, 206, 235], [106, 90, 205], [112, 128, 144], [112, 128, 144],
  458. [255, 250, 250], [0, 255, 127], [70, 130, 180], [210, 180, 140], [0, 128, 128], [216, 191, 216], [255, 99, 71], [64, 224, 208],
  459. [238, 130, 238], [245, 222, 179], [255, 255, 255], [245, 245, 245], [255, 255, 0], [154, 205, 50]];
  460. }
  461. }
  462. // I don't think this is needed anymore
  463. function roundDecimals(c) {
  464. c.r = Math.round(c.r);
  465. c.g = Math.round(c.g);
  466. c.b = Math.round(c.b);
  467. return c;
  468. }
  469.  
  470. function checkUnit() {
  471. // eslint-disable-next-line no-undef
  472. if (CSpeedsModel.isImperial) {
  473. unit = 'mph';
  474. } else {
  475. unit = 'kmh';
  476. }
  477. log(unit);
  478. if (getId('CStable')) {
  479. getId('CStable').innerHTML = '';
  480. getId('CSroadType').innerHTML = '';
  481. LoadSettings();
  482. getId('unitvalue').innerHTML = `(${unit})`;
  483. }
  484. }
  485.  
  486. function createToggler() {
  487. // Layers switcher
  488. // test with script toggler----------------
  489. const oldTogglers = document.querySelectorAll('.togglers');
  490. oldTogglers.forEach((elt, idx) => {
  491. if (elt.id !== 'toolboxUl') {
  492. if (oldTogglers[idx].querySelector('.layer-switcher-group_scripts') === null) {
  493. const newScriptsToggler = document.createElement('li');
  494. newScriptsToggler.className = 'group';
  495. newScriptsToggler.innerHTML = '<div class="controls-container main toggler">\
  496. <input class="layer-switcher-group_scripts toggle" id="layer-switcher-group_scripts" type="checkbox">\
  497. <label for="layer-switcher-group_scripts">\
  498. <span class="label-text">Scripts</span>\
  499. </label>\
  500. </div>\
  501. <ul class="children">\
  502. </ul>';
  503. oldTogglers[idx].appendChild(newScriptsToggler);
  504. }
  505.  
  506. const layerSwitcher = document.createElement('li');
  507. layerSwitcher.innerHTML = '<div class="controls-container toggler">\
  508. <input class="layer-switcher-item_WME_Color_Speeds toggle" id="layer-switcher-item_WME_Color_Speeds" type="checkbox">\
  509. <label for="layer-switcher-item_WME_Color_Speeds">\
  510. <span class="label-text">Color Speeds</span>\
  511. </label>\
  512. </div>';
  513.  
  514. let groupScripts = document.querySelector('.layer-switcher-group_scripts').parentNode.parentNode;
  515. let newScriptsChildren = getElementsByClassName('children', groupScripts)[0];
  516. newScriptsChildren.appendChild(layerSwitcher);
  517.  
  518. toggler = getId('layer-switcher-item_WME_Color_Speeds');
  519. groupToggler = getId('layer-switcher-group_scripts');
  520. groupToggler.checked = (typeof (localStorage.groupScriptsToggler) !== 'undefined'
  521. ? JSON.parse(localStorage.groupScriptsToggler) : true);
  522.  
  523. toggler.checked = WMECSpeeds.togglerChecked;
  524. toggler.disabled = !groupToggler.checked;
  525.  
  526. toggler.addEventListener('click', e => {
  527. mapLayer.setVisibility(e.target.checked);
  528. saveOption();
  529. });
  530.  
  531. groupToggler.addEventListener('click', e => {
  532. toggler.disabled = !e.target.checked;
  533. mapLayer.setVisibility(toggler.checked ? e.target.checked : toggler.checked);
  534. localStorage.setItem('groupScriptsToggler', e.target.checked);
  535. });
  536. }
  537. });
  538. }
  539.  
  540. function changelogLocalizer() {
  541. let changelog;
  542. // eslint-disable-next-line no-undef
  543. CSpeedI18n = I18n.locale;
  544. // eslint-disable-next-line no-undef
  545. if (CSpeedI18n === 'fr') {
  546. changelog = changelogFrench;
  547. } else {
  548. changelog = changelogEnglish;
  549. }
  550. return changelog;
  551. }
  552.  
  553. function getTopCountry() {
  554. // eslint-disable-next-line no-undef
  555. return CSpeedsModel.getTopCountry();
  556. }
  557.  
  558. function getTopState() {
  559. // eslint-disable-next-line no-undef
  560. return CSpeedsModel.getTopState();
  561. }
  562.  
  563. function saveOption() {
  564. WMECSpeeds.togglerChecked = getId('layer-switcher-item_WME_Color_Speeds').checked;
  565. localStorage.setItem('WMEColorSpeeds', JSON.stringify(WMECSpeeds));
  566. }
  567. function destroyTab() {
  568. W.userscripts.removeSidebarTab('ColorSpeeds');
  569. if (debug) log('Sidebar tab removed');
  570. }
  571.  
  572. // *************
  573. // ** INIT **
  574. // *************
  575. function counterStart() {
  576. loadStartTime = performance.now();
  577. bootstrap();
  578. }
  579.  
  580. function bootstrap() {
  581. scriptStartTime = performance.now();
  582. // eslint-disable-next-line no-undef
  583. if (WazeWrap?.Ready && W?.userscripts?.state.isReady) {
  584. log('Starting');
  585. init();
  586. } else {
  587. if (debug) log('WME and WW not ready');
  588. setTimeout(bootstrap, 500);
  589. }
  590. }
  591.  
  592. function showScriptInfoAlert() {
  593. WazeWrap.Interface.ShowScriptUpdate(
  594. // eslint-disable-next-line camelcase
  595. GM_info.script.name,
  596. // eslint-disable-next-line camelcase
  597. GM_info.script.version,
  598. changelogLocalizer(),
  599. greasyForkUrl,
  600. forumUrl
  601. );
  602. }
  603.  
  604. function loadScriptUpdateMonitor() {
  605. try {
  606. const updateMonitor = new WazeWrap.Alerts.ScriptUpdateMonitor(scriptName, currentVersion, downloadUrl, GM_xmlhttpRequest);
  607. if (debug) log('Checked for update');
  608. updateMonitor.start();
  609. } catch (ex) {
  610. // Report the error, but not a critical failure.
  611. console.error(scriptName, ex);
  612. }
  613. }
  614.  
  615. function init() {
  616. loadScriptUpdateMonitor();
  617. showScriptInfoAlert();
  618. // Waze object needed
  619. // eslint-disable-next-line no-undef
  620. CSpeedsWaze = unsafeWindow.W;
  621. if (typeof (CSpeedsWaze) === 'undefined') {
  622. if (debug) { console.error('WME ColorSpeeds - CSpeedsWaze : NOK'); }
  623. window.setTimeout(init, 500);
  624. return;
  625. }
  626. // eslint-disable-next-line no-undef
  627. CSpeedsMap = CSpeedsWaze.map;
  628. if (typeof (CSpeedsMap) === 'undefined') {
  629. if (debug) { console.error('WME ColorSpeeds - CSpeedsmap : NOK'); }
  630. window.setTimeout(init, 500);
  631. return;
  632. }
  633. // eslint-disable-next-line no-undef
  634. CSpeedsModel = CSpeedsWaze.model;
  635. if (typeof (CSpeedsModel) === 'undefined') {
  636. if (debug) { console.error('WME ColorSpeeds - CSpeedsModel DOM : NOK'); }
  637. window.setTimeout(init, 500);
  638. return;
  639. }
  640.  
  641. // eslint-disable-next-line no-undef
  642. CSpeedsCountries = CSpeedsModel.countries;
  643. if (typeof (CSpeedsCountries) === 'undefined') {
  644. if (debug) { console.error('WME ColorSpeeds - CSpeedsCountries DOM : NOK'); }
  645. window.setTimeout(init, 500);
  646. return;
  647. }
  648. CSpeedsTopCountries = getTopCountry();
  649. if (typeof (CSpeedsTopCountries) === 'undefined' || getTopCountry() === null) {
  650. if (debug) { console.error('WME ColorSpeeds - CSpeedsCountries.top DOM : NOK'); }
  651. window.setTimeout(init, 500);
  652. return;
  653. }
  654. if (typeof (getTopCountry().attributes.name) === 'undefined') {
  655. if (debug) { console.error('WME ColorSpeeds - CSpeedsCountries.top.name DOM : NOK'); }
  656. window.setTimeout(init, 500);
  657. return;
  658. }
  659. // OpenLayers
  660. CSpeedOpenLayers = unsafeWindow.OpenLayers;
  661. if (typeof (CSpeedOpenLayers) === 'undefined') {
  662. if (debug) { console.error('WME ColorSpeeds - OpenLayers : NOK'); }
  663. window.setTimeout(init, 500);
  664. return;
  665. }
  666. // Traductions
  667. CSpeedI18n = I18n.locale;
  668. if (typeof(CSpeedI18n) === 'undefined') {
  669. if (debug) { console.error('WME ColorSpeeds - CSpeedI18n : NOK'); }
  670. setTimeout(init, 500);
  671. return;
  672. }
  673.  
  674. // Verify localStorage. Init if empty or not correct
  675. if (typeof (localStorage.WMEColorSpeeds) !== 'undefined' && IsJsonString(localStorage.getItem('WMEColorSpeeds'))) {
  676. WMECSpeeds = JSON.parse(localStorage.WMEColorSpeeds);
  677. if (WMECSpeeds.speedColors.Others === undefined) WMECSpeeds.speedColors.Others = '#f00';
  678. if (WMECSpeeds.speedColors.US === undefined) WMECSpeeds.speedColors.US = cloneObj(colorsUS);
  679. if (WMECSpeeds.speedColors.Countries === undefined) WMECSpeeds.speedColors.Countries = {};
  680. if (WMECSpeeds.multiplePalette === undefined) WMECSpeeds.multiplePalette = multiplePalette;
  681. if (WMECSpeeds.PaletteByCountrie === undefined) WMECSpeeds.PaletteByCountrie = paletteByCountry;
  682. if (WMECSpeeds.offsetValue === undefined) WMECSpeeds.offsetValue = offsetValue;
  683. if (WMECSpeeds.opacityValue === undefined) WMECSpeeds.opacityValue = opacityValue;
  684. if (WMECSpeeds.thicknessValue === undefined) WMECSpeeds.thicknessValue = thicknessValue;
  685. for (const key in typeOfRoad) {
  686. if (WMECSpeeds.typeOfRoad.hasOwnProperty(key) === false ) {
  687. WMECSpeeds.typeOfRoad[key] = cloneObj(typeOfRoad[key]);
  688. }
  689. }
  690. if (WMECSpeeds.togglerChecked === undefined) WMECSpeeds.togglerChecked = WMECSpeeds.visibility;
  691. /* this if statement is no longer needed with WW
  692. if (WMECSpeeds.version === undefined) {
  693. oldScriptVersion = 0;
  694. } else if (WMECSpeeds.version !== undefined) {
  695. oldScriptVersion = WMECSpeeds.version;
  696. }
  697. */
  698. WMECSpeeds.MultiplePalette = (getTopCountry().attributes.name === 'United States') ? WMECSpeeds.MultiplePalette : false;
  699. // WMECSpeeds.MultiplePalette = (CSpeedsCountries.top.name == "United States")? WMECSpeeds.MultiplePalette : false;
  700.  
  701. log('Init ok');
  702. log('WMECSpeeds = ', WMECSpeeds);
  703. } else {
  704. localStorage.setItem('WMEColorSpeeds', JSON.stringify(WMECSpeeds));
  705. setTimeout(init, 500);
  706. return;
  707. }
  708. // ======================================================
  709.  
  710. // Translation
  711. if (CSpeedI18n === 'fr') {
  712. CSI18n = CSpeedI18n;
  713. } else CSI18n = 'en';
  714.  
  715. // ======================================================
  716.  
  717. checkUnit();
  718.  
  719. // WME Layers check
  720. let layers = CSpeedsMap.getLayersBy('uniqueName', 'WME_Color_Speeds');
  721. if (layers.length === 0) {
  722. I18n.translations[CSpeedI18n].layers.name['WME_Color_Speeds'] = 'Color Speeds';
  723.  
  724. const colorspeedsStyle = new CSpeedOpenLayers.Style({
  725. pointRadius: 2,
  726. fontWeight: 'normal',
  727. label: '${labelText}',
  728. fontFamily: 'Tahoma, Courier New',
  729. labelOutlineColor: '#FFFFFF',
  730. labelOutlineWidth: 2,
  731. fontColor: '#000000',
  732. fontSize: '10px'
  733. });
  734.  
  735. mapLayer = new CSpeedOpenLayers.Layer.Vector(I18n.t('layers.name.WME_Color_Speeds'), {
  736. displayInLayerSwitcher: true,
  737. uniqueName: 'WME_Color_Speeds',
  738. styleMap: new CSpeedOpenLayers.StyleMap(colorspeedsStyle)
  739. });
  740.  
  741. CSpeedsMap.addUniqueLayer(mapLayer);
  742. mapLayer.setVisibility(WMECSpeeds.visibility);
  743. }
  744.  
  745. createToggler();
  746.  
  747. // MTE mode event
  748. /*
  749. W.app.modeController.model.bind('change:mode', function(){
  750. if (W.app.modeController.getState() !== undefined){
  751. eventUnRegister();
  752. try { colorspeeds_mapLayer.destroyFeatures();
  753. }catch(err){log('err destroyFeatures: ',err);}
  754. }
  755. if (W.app.modeController.getState() === undefined){
  756. eventUnRegister();
  757. createToggler();
  758. CSpeeds_css();
  759. }
  760. });
  761. */
  762. // reload after changing WME units
  763. W.prefs.on('change:isImperial', () => {
  764. destroyTab();
  765. eventUnRegister();
  766. checkUnit();
  767. createToggler();
  768. createCSS();
  769. });
  770.  
  771. // log('colorspeeds_mapLayer ',colorspeeds_mapLayer);
  772.  
  773. // Then running
  774. createCSS();
  775. }
  776.  
  777. function createCSS() {
  778. let CSpeedsCSS = getId('CSpeedsCSS');
  779. if (CSpeedsCSS === null) {
  780. CSpeedsCSS = document.createElement('style');
  781. CSpeedsCSS.type = 'text/css';
  782. CSpeedsCSS.id = 'CSpeedsCSS';
  783. }
  784.  
  785. let css = '.CScontent {width:255px; margin-left:10px; box-shadow: 0 4px 10px #aaa;}';
  786. css += '.divStateChoise {width:250px; margin-left:10px; color:#59899e; font-weight:bold; vertical-align: middle;}';
  787. css += '.divHeadline {height:26px; font-weight:bold; padding-top:2px; border:2px solid #3d3d3d; background-color:#BEDCE5;}';
  788. css += '.divContent {clear:both;height:26px; border:2px solid #3d3d3d; border-top:0;}';
  789. css += '.divContentZoom { clear:both; height:26px; border:2px solid #3d3d3d; border-top:0;}';
  790. css += '.divc {float:center; text-align:center;}';
  791. css += '.divl {float:left; text-align:center;}';
  792. css += '.divll {float:left; text-align:left;}';
  793. css += '.divr {float:right; text-align:center;}';
  794. css += '.speed {margin-top:2px; width:65px; height:20px; color:#59899e; font-weight:bold; vertical-align: middle;}';
  795. css += '.divcolor { width:80px; height:17px; margin:4px 0 0 0; vertical-align: middle;}';
  796. css += '.CStype {margin-top:2px; margin-left:10px; height:20px; color:#59899e; font-weight:bold; text-align:left; vertical-align: middle;}';
  797. css += '.CScheckLabel {margin-top:5px; margin-left:10px; height:22px; color:#59899e; font-weight:bold; text-align:left; vertical-align: middle;}';
  798. css += '.CScheck { float:left; width:22px; height:22px;}';
  799. css += '.CSzoom {margin-top:2px; height:20px; color:#59899e; font-weight:bold; vertical-align: middle}';
  800. css += '#newspeed {width:65px; height:26px; font-weight:bold;text-align:center;}';
  801. css += '#editzoom { display:none;}';
  802. css += '#newvalzoom {width:45px; height:24px; font-weight:bold;text-align:center;}';
  803. css += '.CScontentConf {width:280px; margin-left:5px;}';
  804. css += '.divContentConf {clear:both; line-height:24px; height:28px;}';
  805. css += '.valColor {color:#59899e; font-weight:bold;}';
  806. css += '#valRed {width:80px; height:28px; font-weight:bold; color:red;text-align:center;}';
  807. css += '#valGreen {width:80px; height:28px; font-weight:bold; color:green;text-align:center;}';
  808. css += '#valBlue {width:80px; height:28px; font-weight:bold; color:blue;text-align:center;}';
  809. css += '#valOffset {width:80px; height:28px; font-weight:bold;text-align:center;}';
  810. css += '#valOpacity {width:80px; height:28px; font-weight:bold;text-align:center;}';
  811. css += '#valThickness {width:80px; height:28px; font-weight:bold;text-align:center;}';
  812. css += '#ConfColor.dropdown-menu li:hover, #ConfColor+.dropdown-menu li:active, #ConfColor+.dropdown-menu li:focus { cursor: pointer; outline: #3B99FC dotted 1px; }';
  813. css += '#ConfColor.btn { box-shadow: inset 0px -1px 0px rgba(0,0,0,0.2); border-radius: 4px; border: 1px solid rgba(0,0,0,0.25); height:22px; width:90px; }';
  814. css += '#nameColor {width:120px; height:22px;}';
  815. // css +="#ConfDash.dropdown-menu li:hover, #ConfDash+.dropdown-menu li:active, #ConfDash+.dropdown-menu li:focus { cursor: pointer; outline: #3B99FC dotted 1px; }";
  816. // css +="#ConfDash.btn { box-shadow: inset 0px -1px 0px rgba(0,0,0,0.2); border-radius: 4px; border: 1px solid rgba(0,0,0,0.25); height:22px; width:90px; }";
  817. CSpeedsCSS.innerHTML = css;
  818. document.body.appendChild(CSpeedsCSS);
  819. createTab();
  820. }
  821.  
  822. function createNewSpeedColorDialog() {
  823. newspeedColorDialog = getId('newspeedColorDialog');
  824. if (newspeedColorDialog === null) {
  825. newspeedColorDialog = document.createElement('div');
  826. newspeedColorDialog.id = 'newspeedColorDialog';
  827. }
  828.  
  829. // newspeedColorDialog.style.fontSize = '90%';
  830. newspeedColorDialog.style.display = 'none';
  831. newspeedColorDialog.style.top = '10px';
  832. // newspeedColorDialog.style.left = '15px';
  833. newspeedColorDialog.style.width = '300px';
  834. newspeedColorDialog.style.height = '500px';
  835. newspeedColorDialog.style.margin = '10px 10px 10px 0px';
  836. newspeedColorDialog.style.borderRadius = '10px';
  837. newspeedColorDialog.style.border = '1px solid #BEDCE5';
  838. newspeedColorDialog.style.position = 'relative';
  839. newspeedColorDialog.style.padding = '5px';
  840. newspeedColorDialog.style.overflow = 'auto';
  841. newspeedColorDialog.style.background = 'rgba(255, 255, 255, 1)';
  842.  
  843. let content = "<div style='clear:both;'></div>";
  844. content += `<div class='divc' style='width:200px; font-weight:bold;'>${CSlang[2][CSI18n]}</div>`;
  845. content += "<div style='clear:both; padding-top:10px;'></div>";
  846.  
  847. // header table
  848. content += "<div class='CScontentConf'>";
  849.  
  850. // Edit other color
  851. content += "<div class='divContentConf' id='Conf_Others' style='display:none;'>";
  852. content += `<div class='divll' style='width:70px;font-weight:bold;'>${CSlang[1][CSI18n]} </div>`;
  853. content += `<div class='divll' style='width:60px;font-weight:bold;'>${CSlang[7][CSI18n]}</div>`;
  854. content += "<div class='divl' style='width:45px;'>&nbsp;</div>";
  855. content += "<div style='clear:both; padding-top:10px;'></div>";
  856. content += `<div class='divll' style='width:70px;font-weight:bold;'>${CSlang[3][CSI18n]}: </div>`;
  857. content += '</div>';
  858.  
  859. // Edit speed color
  860. content += "<div class='divContentConf' id='Conf_Color' style='display:none;'>";
  861. content += `<div class='divll' style='width:75px;font-weight:bold;'>${CSlang[1][CSI18n]} </div>`;
  862. content += "<div class='divll speed' style='width:60px;'><input type='text' value='' id='newspeed'/></div>";
  863. content += `<div class='divl' id='unitvalue' style='width:45px;font-size:11px;font-weight:bold;line-height:20px;'>(${unit})</div>`;
  864. content += "<div style='clear:both; padding-top:10px;'></div>";
  865. content += `<div class='divll' style='width:75px;font-weight:bold;'>${CSlang[3][CSI18n]} </div>`;
  866. content += '</div>';
  867.  
  868. content += `<div class='divl dropdown' style='width:90px; text-align:left;'><button id='ConfColor' class='btn dropdown-toggle' style='background-color:${WMECSpeeds.speedColors.Others};' type='button' data-toggle='dropdown'></button><ul class='dropdown-menu' style='height: 400px; overflow: auto; margin: 0; padding: 0; min-width: 90px;'>`;
  869. for (let i = 0; colors[i]; ++i) {
  870. let test = (colors[i].match(/\(/)) ? true : false;
  871. switch (test) {
  872. case true:
  873. content += "<li style='background-color:rgb" + colors[i] + "'>&nbsp;</li>";
  874. break;
  875. case false:
  876. content += "<li style='background-color:" + colors[i] + "'>&nbsp;</li>";
  877. break;
  878. }
  879. }
  880. content += '</ul></div>';
  881. content += "<span class='divl valColor' id=nameColor></span>";
  882. content += '</div>';
  883. content += "<div style='clear:both; padding-top:10px;'></div>";
  884.  
  885. // Red Value
  886. content += "<div class='CScontentConf'>";
  887. content += "<div class='divContentConf'>";
  888. content += `<div class='divll' style='width:60px;font-weight:bold; color:red;'>${CSlang[11][CSI18n]}</div>`;
  889. content += "<div style='clear:both; padding-top:2px;'></div>";
  890. content += "<div class='divl valColor' style='width:80px; height:28px;'><input type='number' max='255' min='0' value='' id='valRed' pattern='[0-9]{3}' /></div>";
  891. content += "<div class='divr'><input id='sliderRed' type='range' max='255' min='0' style='width:180px;height:24px;'></div>";
  892. content += '</div>';
  893.  
  894. // Green Value
  895. content += "<div style='clear:both; padding-top:10px;'></div>";
  896. content += "<div class='divContentConf'>";
  897. content += `<div class='divll' style='width:60px;font-weight:bold; color:green;'>${CSlang[12][CSI18n]}</div>`;
  898. content += "<div style='clear:both; padding-top:2px;'></div>";
  899. content += "<div class='divl valColor' style='width:80px; height:28px;'><input type='number' max='255' min='0' value='' id='valGreen' pattern='[0-9]{3}' /></div>";
  900. content += "<div class='divr'><input id='sliderGreen' type='range' max='255' min='0' style='width:180px;height:24px;'></div>";
  901. content += '</div>';
  902. content += "<div style='clear:both; padding-top:10px;'></div>";
  903.  
  904. // Bleu Value
  905. content += "<div class='divContentConf'>";
  906. content += `<div class='divll' style='width:60px;font-weight:bold; color:blue;'>${CSlang[13][CSI18n]}</div>`;
  907. content += "<div style='clear:both; padding-top:2px;'></div>";
  908. content += "<div class='divl valColor' style='width:80px; height:28px;'><input type='number' max='255' min='0' value='' id='valBlue' pattern='[0-9]{3}' /></div>";
  909. content += "<div class='divr'><input id='sliderBlue' type='range' max='255' min='0' style='width:180px;height:24px;'></div>";
  910. content += '</div>';
  911.  
  912. content += "<div style='clear:both; padding-top:10px;'></div>";
  913. content += `<div class='divr' style='width:40px; height:40x'><a href='#'><img id='cancel' style='width:20px;' title='${CSlang[6][CSI18n]}' src='data:image/png;base64,${iconUndo}' /></a></div>`;
  914. content += `<div class='divr' style='width:40px; height:40x;'><a href='#'><img id='submit' style='width:20px;' title='${CSlang[14][CSI18n]}' src='data:image/png;base64,${iconSubmit}' /></a></div>`;
  915. // content += "<div class='divc' style='width:270px; font-weight:bold;'><button id='OkButton'>Ok</button></div>";
  916. content += '</div>';
  917.  
  918. newspeedColorDialog.innerHTML = content;
  919. // document.body.appendChild(newspeedColorDialog);
  920. // CSpeedshandleClass2.appendChild(newspeedColorDialog);
  921. getId('tab-colorspeeds').appendChild(newspeedColorDialog);
  922. }
  923.  
  924. // *************
  925. // ** HTML **
  926. // *************
  927.  
  928. async function createTab() {
  929. const { tabLabel, tabPane } = W.userscripts.registerSidebarTab('ColorSpeeds');
  930. if (debug) log('Starting tab creation');
  931. const labelText = $('<div>').append(
  932. $('<span>', {
  933. id: 'cspeedstablabel',
  934. class: 'fa fa-dashboard',
  935. title: `${CSlang[32][CSI18n]}`
  936. })
  937. ).html();
  938.  
  939. tabLabel.innerHTML = labelText;
  940.  
  941. // colorspeeds header
  942. let content = `<div style='float:left; margin-left:5px;'><b><a href='https://gf.qytechs.cn/scripts/14044-wme-color-speeds' target='_blank'><u>WME Color Speeds</u></a></b> v${currentVersion}</div>`;
  943. content += "<div id='colorspeedsDiv'>";
  944.  
  945. // Countries pallete
  946. content += "<div style='clear:both; padding-top:10px;'></div>";
  947. content += `<div class='divStateChoise' id='countrieChoise' style='display:block;'><input type='checkbox' class='CScheck' id='cbPaletteByCountrie'><div class='divl CScheckLabel' style='width:210px;'>${CSlang[19][CSI18n]}</div>`;
  948. content += "<div style='clear:both; padding-top:10px;'></div>"; // Couleurs pour </div>";
  949. content += "<select id='selectCountrie' style='height:22px; width:250px; active:none;'>";
  950. Object.keys(WMECSpeeds.speedColors.Countries).forEach(countrie => {
  951. content += `<option value='${countrie}'>${countrie.replace(/_/g, ' ')}</option>`;
  952. });
  953. content += '</select></div>';
  954.  
  955. // Mutiple pallete
  956. content += "<div style='clear:both; padding-top:10px;'></div>";
  957. content += `<div class='divStateChoise' id='stateChoise' style='display:block;'><input type='checkbox' class='CScheck' id='cbMultiplePalette'><div class='divl CScheckLabel' style='width:210px;'>${CSlang[20][CSI18n]}</div>`;
  958. content += "<div style='clear:both; padding-top:20px;'></div>"; // Couleurs pour </div>";
  959. content += "<select id='selectState' style='height:22px; active:none;'>";
  960. Object.keys(WMECSpeeds.speedColors.US).forEach(state => {
  961. content += `<option value='${state}'>${state.replace(/_/g, ' ')}</option>`;
  962. });
  963. content += '</select></div>';
  964.  
  965. // Speed table header
  966. content += "<div style='clear: both; padding-top:10px;'></div><div class='CScontent'>";
  967. content += `<div class='divHeadline'><div class='divl' style='width:60px;'>${CSlang[32][CSI18n]}</div><div class='divr' id='unitvalue' style='width:45px;font-size:11px;line-height:20px;'>(${unit})</div><div class='divr' style='width:130px;'>${CSlang[33][CSI18n]}</div></div>`;
  968.  
  969. // Speed table
  970. content += `<div class='divContent'><div class='divl speed' style='width:60px;'>${CSlang[7][CSI18n]}</div>`;
  971. content += "<div class='divr' style='width:20px;'>&nbsp;</div>";
  972. content += `<div class='divr' style='width:20px;'><a href='#'><img id='edit_others' style='width:16px;' title='${CSlang[8][CSI18n]}' src='data:image/png;base64,${iconEdit}' /></a></div>`;
  973. content += `<div class='divr' style='width:120px;'><div id='color_others' class='divcolor' style='background-color:${WMECSpeeds.speedColors.Others};'>&nbsp;</div></div></div>`;
  974. content += "<div id='CStable'></div></div><div id='divadd'></div>";
  975.  
  976. // Road type header
  977. content += "<br><div style='clear:both; padding-top:10px;'></div><div class='CScontent'>";
  978. content += `<div class='divHeadline'><div class='divl' style='width:120px;'>${CSlang[9][CSI18n]}</div><div class='divr' style='width:60px; margin-right:20px;'>${CSlang[10][CSI18n]}</div></div>`;
  979. // edit zoom
  980. content += "<div class='divContent' id='editzoom'><div class='divl speed' style='width:110px;'><span id='texttype'></span></div>";
  981. content += `<div class='divr' style='width:20px;'><a href='#'><img id='cancelZoom' style='width:20px;' title='${CSlang[6][CSI18n]}' src='data:image/png;base64,${iconUndo}' /></a></div>`;
  982. content += `<div class='divr' style='width:20px;'><a href='#'><img id='submitZoom' style='width:20px;' title='${CSlang[14][CSI18n]}' src='data:image/png;base64,${iconSubmit}' /></a></div>`;
  983. content += "<div class='divr speed' style='width:60px;'><input type='text' value='' id='newvalzoom'/></div>";
  984. content += '</div>';
  985. content += "<div id='CSroadType'></div></div>";
  986.  
  987. // Offset Value
  988. content += "<br><div style='clear:both; padding-top:10px;'></div>";
  989. content += "<div class='divContentConf'>";
  990. content += `<div class='divll' style='width:65px;font-weight:bold;color:#59899e;'>${CSlang[15][CSI18n]}</div>`;
  991. content += "<div style='clear:both; padding-top:2px;'></div>";
  992. content += "<div class='divl valColor' style='width:80px; height:28px;'><input type='number' id='valOffset' min='1' max='10' value='' pattern='[0-9]{2}'/></div>";
  993. content += "<div class='divr'><input id='sliderOffset' type='range' max='10' min='1' step='1' style='width:180px;height:24px;margin-right:20px;'></div>";
  994. content += '</div>';
  995.  
  996. // Opacity Value
  997. content += "<div style='clear:both; padding-top:10px;'></div>";
  998. content += "<div class='divContentConf'>";
  999. content += `<div class='divll' style='width:65px;font-weight:bold;color:#59899e;'>${CSlang[16][CSI18n]}</div>`;
  1000. content += "<div style='clear:both; padding-top:2px;'></div>";
  1001. content += "<div class='divl valColor' style='width:80px; height:28px;'><input type='number' id='valOpacity' min='20' max='100' value='' pattern='[0-9]{3}'/></div>";
  1002. content += "<div class='divr'><input id='sliderOpacity' type='range' max='100' min='20' step='1' style='width:180px;height:24px;margin-right:20px;'></div>";
  1003. content += '</div>';
  1004.  
  1005. // Thickness Value
  1006. content += "<div style='clear:both; padding-top:10px;'></div>";
  1007. content += "<div class='divContentConf'>";
  1008. content += `<div class='divll' style='width:65px;font-weight:bold;color:#59899e;'>${CSlang[17][CSI18n]}</div>`;
  1009. content += "<div style='clear:both; padding-top:2px;'></div>";
  1010. content += "<div class='divl valColor' style='width:80px; height:28px;'><input type='number' id='valThickness' min='2' max='10' value='' pattern='[0-9]{2}'/></div>";
  1011. content += "<div class='divr'><input id='sliderThickness' type='range' max='10' min='2' step='1' style='width:180px;height:24px;margin-right:20px;'></div>";
  1012. content += '</div>';
  1013.  
  1014. /*
  1015. // 2023-09-26 SS28 I haven't taken the time to see what is wrong here. Maybe we can resurrect it
  1016. // Dash Style
  1017. content += "<div class='divContentConf'>";
  1018. content += "<div style='clear:both; padding-top:10px;'></div>";
  1019. content += "<div class='divll' style='width:140px;font-weight:bold;color:#59899e;'>Dash Style:</div>";
  1020. content += "<div class='divl dropdown' style='width:90px; text-align:left;'><button id='ConfDash' class='btn dropdown-toggle' style='background-color:rgb(255,255,255);' type='button' data-toggle='dropdown'></button><ul class='dropdown-menu' style='height: 400px; overflow: scroll; margin: 0; padding: 0; min-width: 90px;'>";
  1021. for (let i = 0; i <= dashStyles.length; ++i) {
  1022. content += `<li>&nbsp;${dashStyles[i]}&nbsp;</li>`;
  1023. }
  1024. content += '</ul></div>';
  1025. content += '</div>';
  1026. */
  1027.  
  1028. tabPane.innerHTML = content;
  1029. tabPane.id = 'tab-colorspeeds';
  1030.  
  1031. // Fix tab content div spacing.
  1032. // $(tabPane).parent().css({ width: 'auto', padding: '4px' });
  1033.  
  1034. await W.userscripts.waitForElementConnected(tabPane);
  1035. if (debug) log('Tab loaded');
  1036.  
  1037. createNewSpeedColorDialog();
  1038.  
  1039. getId('divadd').innerHTML += (`<br/><center><input type='button' id='addbutton' name='add' value='${CSlang[4][CSI18n]}' /></center>`);
  1040.  
  1041. getId('addbutton').onclick = (() => {
  1042. getId('Conf_Others').style.display = 'none';
  1043. getId('Conf_Color').style.display = 'block';
  1044. getId('colorspeedsDiv').style.display = 'none';
  1045. getId('newspeed').value = '';
  1046. getId('ConfColor').style.backgroundColor = '#fff';
  1047. newspeedColorDialog.style.display = 'block';
  1048. let c = getId('ConfColor').style.backgroundColor;
  1049. c = color2Rgb(c);
  1050. actualiseColorRGB(c);
  1051. });
  1052.  
  1053. if (debug) log(`Country = ${getTopCountry().attributes.name}`);
  1054.  
  1055. getId('cbPaletteByCountrie').checked = WMECSpeeds.PaletteByCountrie;
  1056. getId('selectCountrie').style.display = (WMECSpeeds.PaletteByCountrie) ? 'block' : 'none';
  1057.  
  1058. getId('stateChoise').style.display = (getTopCountry().attributes.name === 'United States') ? 'block' : 'none';
  1059.  
  1060. if (WMECSpeeds.MultiplePalette === true) {
  1061. let index = 0;
  1062. const stateToSelect = getTopState().attributes.name.replace(/ /g, '_');
  1063. for (index; getId('selectState').options[index].value !== stateToSelect; index++) { /* empty */ }
  1064. getId('selectState').options[index].selected = true;
  1065. }
  1066.  
  1067. getId('valOffset').value = WMECSpeeds.offsetValue;
  1068. getId('sliderOffset').value = WMECSpeeds.offsetValue;
  1069.  
  1070. getId('valOpacity').value = Number(WMECSpeeds.opacityValue * 100).toFixed(0);
  1071. getId('sliderOpacity').value = Number(WMECSpeeds.opacityValue * 100).toFixed(0);
  1072.  
  1073. getId('valThickness').value = WMECSpeeds.thicknessValue;
  1074. getId('sliderThickness').value = WMECSpeeds.thicknessValue;
  1075.  
  1076. LoadSettings();
  1077.  
  1078. eventRegister();
  1079.  
  1080. SCColor();
  1081. }
  1082.  
  1083. function eventRegister() {
  1084. CSpeedsWaze.selectionManager.events.register('selectionchanged', null, SCColor);
  1085. CSpeedsModel.actionManager.events.register('afterclearactions', null, SCColor);
  1086. CSpeedsModel.actionManager.events.register('afterundoaction', null, SCColor);
  1087. CSpeedsMap.olMap.events.register('zoomend', null, SCColor);
  1088. CSpeedsMap.olMap.events.register('moveend', null, SCColor);
  1089.  
  1090. CSpeedsModel.events.register('mergeend', null, SCColor);
  1091. window.addEventListener('beforeunload', saveOption, false);
  1092. }
  1093.  
  1094. function eventUnRegister() {
  1095. CSpeedsWaze.selectionManager.events.unregister('selectionchanged', null, SCColor);
  1096. CSpeedsModel.actionManager.events.unregister('afterclearactions', null, SCColor);
  1097. CSpeedsModel.actionManager.events.unregister('afterundoaction', null, SCColor);
  1098. CSpeedsMap.olMap.events.unregister('zoomend', null, SCColor);
  1099. CSpeedsMap.olMap.events.unregister('moveend', null, SCColor);
  1100. CSpeedsModel.events.unregister('mergeend', null, SCColor);
  1101. window.removeEventListener('beforeunload', saveOption, false);
  1102. }
  1103.  
  1104. function LoadSettings() {
  1105. getId('cbPaletteByCountrie').checked = WMECSpeeds.PaletteByCountrie;
  1106. getId('selectCountrie').style.display = (WMECSpeeds.PaletteByCountrie) ? 'block' : 'none';
  1107.  
  1108. getId('cbMultiplePalette').checked = WMECSpeeds.MultiplePalette;
  1109. getId('selectState').style.display = (WMECSpeeds.MultiplePalette) ? 'block' : 'none';
  1110.  
  1111. if (WMECSpeeds.MultiplePalette === false && WMECSpeeds.PaletteByCountrie === false) {
  1112. Object.keys(WMECSpeeds.speedColors[unit]).forEach(valSpeed => {
  1113. const color = WMECSpeeds.speedColors[unit][valSpeed];
  1114. const div = document.createElement('div');
  1115. div.className = 'divContent';
  1116.  
  1117. const divspeed = document.createElement('div');
  1118. divspeed.className = 'divl speed';
  1119. divspeed.style.width = '60px';
  1120. divspeed.innerHTML = valSpeed;
  1121. div.appendChild(divspeed);
  1122.  
  1123. const divsuppr = document.createElement('div');
  1124. divsuppr.className = 'divr';
  1125. divsuppr.style.width = '20px';
  1126.  
  1127. const divsuppra = document.createElement('a');
  1128. divsuppra.innerHTML = `<img style='width:20px;' title='${CSlang[5][CSI18n]}' src='data:image/png;base64,${iconDelete}' />`;
  1129. divsuppra.href = '#';
  1130. divsuppra.className = 'delSpeed';
  1131. divsuppra.id = `delSpeed_${valSpeed}`;
  1132. divsuppr.appendChild(divsuppra);
  1133. div.appendChild(divsuppr);
  1134.  
  1135. const divedit = document.createElement('div');
  1136. divedit.className = 'divr';
  1137. divedit.style.width = '20px';
  1138.  
  1139. const divedita = document.createElement('a');
  1140. divedita.innerHTML = `<img style='width:16px;' title='${CSlang[8][CSI18n]}' src='data:image/png;base64,${iconEdit}' />`;
  1141. divedita.href = '#';
  1142. divedita.onclick = getFunctionWithArgs(CSModifCouleur, [unit, valSpeed, color, null]);
  1143. divedit.appendChild(divedita);
  1144. div.appendChild(divedit);
  1145.  
  1146. const divcolor = document.createElement('div');
  1147. divcolor.className = 'divr';
  1148. divcolor.style.width = '120px';
  1149. divcolor.innerHTML = `<div class='divcolor' style='background-color:${color};'>&nbsp;</div>`;
  1150. div.appendChild(divcolor);
  1151.  
  1152. getId('CStable').appendChild(div);
  1153. });
  1154.  
  1155. // log("LoadSettings WMECSpeeds.speedColors."+unit+" = ",WMECSpeeds.speedColors[unit]);
  1156. }
  1157. if (WMECSpeeds.MultiplePalette === true && WMECSpeeds.PaletteByCountrie === false) {
  1158. selectedState = getId('selectState').options[getId('selectState').selectedIndex].value;
  1159. if (debug) log('selectedState = ', selectedState);
  1160.  
  1161. if (WMECSpeeds.speedColors.US[selectedState][unit] === undefined) {
  1162. WMECSpeeds.speedColors.US[selectedState][unit] = cloneObj(WMECSpeeds.speedColors[unit]);
  1163. }
  1164.  
  1165. Object.keys(WMECSpeeds.speedColors.US[selectedState][unit]).forEach(valSpeed => {
  1166. const color = WMECSpeeds.speedColors.US[selectedState][unit][valSpeed];
  1167. const div = document.createElement('div'); div.className = 'divContent';
  1168. const divspeed = document.createElement('div'); divspeed.className = 'divl speed'; divspeed.style.width = '60px'; divspeed.innerHTML = valSpeed;
  1169. div.appendChild(divspeed);
  1170.  
  1171. const divsuppr = document.createElement('div'); divsuppr.className = 'divr'; divsuppr.style.width = '20px';
  1172. const divsuppra = document.createElement('a');
  1173. divsuppra.innerHTML = `<img style='width:20px;' title='${CSlang[5][CSI18n]}' src='data:image/png;base64,${iconDelete}' />`;
  1174. divsuppra.href = '#'; divsuppra.className = 'delSpeed'; divsuppra.id = `delSpeed_${valSpeed}`;
  1175. divsuppr.appendChild(divsuppra);
  1176. div.appendChild(divsuppr);
  1177.  
  1178. const divedit = document.createElement('div'); divedit.className = 'divr'; divedit.style.width = '20px';
  1179. const divedita = document.createElement('a');
  1180. divedita.innerHTML = `<img style='width:16px;' title='${CSlang[8][CSI18n]}' src='data:image/png;base64,${iconEdit}' />`;
  1181. divedita.href = '#';
  1182. divedita.onclick = getFunctionWithArgs(CSModifCouleur, [unit, valSpeed, color, selectedState]);
  1183. divedit.appendChild(divedita);
  1184. div.appendChild(divedit);
  1185.  
  1186. const divcolor = document.createElement('div'); divcolor.className = 'divr'; divcolor.style.width = '120px';
  1187. divcolor.innerHTML = `<div class='divcolor' style='background-color:${color};'>&nbsp;</div>`;
  1188. div.appendChild(divcolor);
  1189. getId('CStable').appendChild(div);
  1190. });
  1191. if (debug) log(`LoadSettings WMECSpeeds.speedColors.US.${selectedState}.${unit} = `, WMECSpeeds.speedColors.US[selectedState][unit]);
  1192. }
  1193.  
  1194. if (WMECSpeeds.PaletteByCountrie === true && WMECSpeeds.MultiplePalette === false) {
  1195. if (getId('selectCountrie').options[getId('selectCountrie').selectedIndex] !== undefined) {
  1196. selectedCountry = getId('selectCountrie').options[getId('selectCountrie').selectedIndex].value;
  1197. } else selectedCountry = getTopCountry().attributes.name.replace(/ /g, '_');
  1198.  
  1199. log('selectCountrie = ', selectedCountry);
  1200.  
  1201. if (WMECSpeeds.speedColors.Countries[selectedCountry] === undefined || WMECSpeeds.speedColors.Countries[selectedCountry][unit] === undefined) {
  1202. WMECSpeeds.speedColors.Countries[selectedCountry] = {};
  1203. WMECSpeeds.speedColors.Countries[selectedCountry][unit] = cloneObj(WMECSpeeds.speedColors[unit]);
  1204. updateCountrieList();
  1205. // log("LoadSettings création WMECSpeeds.speedColors.Countries."+selectedCountrie+"."+unit+" = ",WMECSpeeds.speedColors.Countries[selectedCountrie][unit]);
  1206. }
  1207.  
  1208. Object.keys(WMECSpeeds.speedColors.Countries[selectedCountry][unit]).forEach(valSpeed => {
  1209. const color = WMECSpeeds.speedColors.Countries[selectedCountry][unit][valSpeed];
  1210. const div = document.createElement('div'); div.className = 'divContent';
  1211. const divspeed = document.createElement('div'); divspeed.className = 'divl speed'; divspeed.style.width = '60px'; divspeed.innerHTML = valSpeed;
  1212. div.appendChild(divspeed);
  1213.  
  1214. const divsuppr = document.createElement('div'); divsuppr.className = 'divr'; divsuppr.style.width = '20px';
  1215. const divsuppra = document.createElement('a');
  1216.  
  1217. divsuppra.innerHTML = `<img style='width:20px;' title='${CSlang[5][CSI18n]}' src='data:image/png;base64,${iconDelete}' />`;
  1218. divsuppra.href = '#'; divsuppra.className = 'delSpeed'; divsuppra.id = `delSpeed_${valSpeed}`;
  1219. divsuppr.appendChild(divsuppra);
  1220. div.appendChild(divsuppr);
  1221.  
  1222. const divedit = document.createElement('div'); divedit.className = 'divr'; divedit.style.width = '20px';
  1223. const divedita = document.createElement('a');
  1224. divedita.innerHTML = `<img style='width:16px;' title='${CSlang[8][CSI18n]}' src='data:image/png;base64,${iconEdit}' />`;
  1225. divedita.href = '#';
  1226. divedita.onclick = getFunctionWithArgs(CSModifCouleur, [unit, valSpeed, color, selectedCountry]);
  1227. divedit.appendChild(divedita);
  1228. div.appendChild(divedit);
  1229.  
  1230. const divcolor = document.createElement('div'); divcolor.className = 'divr'; divcolor.style.width = '120px';
  1231. divcolor.innerHTML = `<div class='divcolor' style='background-color:${color};'>&nbsp;</div>`;
  1232. div.appendChild(divcolor);
  1233. getId('CStable').appendChild(div);
  1234. });
  1235.  
  1236. // log("LoadSettings WMECSpeeds.speedColors.Countries."+selectedCountrie+"."+unit+" = ",WMECSpeeds.speedColors.Countries[selectedCountrie][unit]);
  1237. }
  1238.  
  1239. for (let i = 0; i < RoadToScan.length; ++i) {
  1240. const type = RoadToScan[i];
  1241. const div = document.createElement('div'); div.className = 'divContentZoom';
  1242.  
  1243. const divcheck = document.createElement('div'); divcheck.className = 'divl';
  1244. divcheck.innerHTML = `<input type="checkbox" style="margin:1px 1px;" class="CScheck" id="cbRoad${type}">`;
  1245. div.appendChild(divcheck);
  1246.  
  1247. const divtype = document.createElement('div');
  1248. divtype.className = 'divl CStype';
  1249. divtype.style.width = '130px';
  1250.  
  1251. const divedit = document.createElement('div');
  1252. divedit.className = 'divr';
  1253. divedit.style.width = '20px';
  1254. const divedita = document.createElement('a');
  1255. divedita.innerHTML = `<img style='width:16px;' title='${CSlang[8][CSI18n]}' src='data:image/png;base64,${iconEdit}' />`;
  1256. divedita.href = '#';
  1257. divedita.className = 'modifyZoom';
  1258. divedita.id = `zoom_${type}`;
  1259. divedit.appendChild(divedita);
  1260.  
  1261. const divzoom = document.createElement('div');
  1262. divzoom.className = 'divr CSzoom';
  1263. divzoom.style.width = '60px';
  1264. divzoom.innerHTML = WMECSpeeds.typeOfRoad[type].zoom;
  1265. divzoom.title = `${roadTypeZoomInfo[type][CSI18n]}`;
  1266.  
  1267. if (type === 3) {
  1268. divtype.innerHTML = CSlang[22][CSI18n];
  1269. div.appendChild(divtype);
  1270. div.appendChild(divedit);
  1271. div.appendChild(divzoom);
  1272. } else if (type === 6) {
  1273. divtype.innerHTML = CSlang[23][CSI18n];
  1274. div.appendChild(divtype);
  1275. div.appendChild(divedit);
  1276. div.appendChild(divzoom);
  1277. } else if (type === 7) {
  1278. divtype.innerHTML = CSlang[24][CSI18n];
  1279. div.appendChild(divtype);
  1280. div.appendChild(divedit);
  1281. div.appendChild(divzoom);
  1282. } else if (type === 4) {
  1283. divtype.innerHTML = CSlang[25][CSI18n];
  1284. div.appendChild(divtype);
  1285. div.appendChild(divedit);
  1286. div.appendChild(divzoom);
  1287. } else if (type === 2) {
  1288. divtype.innerHTML = CSlang[26][CSI18n];
  1289. div.appendChild(divtype);
  1290. div.appendChild(divedit);
  1291. div.appendChild(divzoom);
  1292. } else if (type === 1) {
  1293. divtype.innerHTML = CSlang[27][CSI18n];
  1294. div.appendChild(divtype);
  1295. div.appendChild(divedit);
  1296. div.appendChild(divzoom);
  1297. } else if (type === 22) {
  1298. divtype.innerHTML = CSlang[28][CSI18n];
  1299. div.appendChild(divtype);
  1300. div.appendChild(divedit);
  1301. div.appendChild(divzoom);
  1302. } else if (type === 20) {
  1303. divtype.innerHTML = CSlang[29][CSI18n];
  1304. div.appendChild(divtype);
  1305. div.appendChild(divedit);
  1306. div.appendChild(divzoom);
  1307. } else if (type === 17) {
  1308. divtype.innerHTML = CSlang[30][CSI18n];
  1309. div.appendChild(divtype);
  1310. div.appendChild(divedit);
  1311. div.appendChild(divzoom);
  1312. } else if (type === 8) {
  1313. divtype.innerHTML = CSlang[31][CSI18n];
  1314. div.appendChild(divtype);
  1315. div.appendChild(divedit);
  1316. div.appendChild(divzoom);
  1317. } else if (type === 999) {
  1318. divtype.innerHTML = CSlang[18][CSI18n];
  1319. div.appendChild(divtype);
  1320. }
  1321.  
  1322. getId('CSroadType').appendChild(div);
  1323. getId(`cbRoad${type}`).checked = WMECSpeeds.typeOfRoad[type].checked;
  1324. // getId(`cbRoad${type}`).style.marginLeft = '2px';
  1325. // getId(`cbRoad${type}`).style.marginTop = '2px';
  1326. // getId(`cbRoad${type}`).style.width = '15px';
  1327. // getId(`cbRoad${type}`).style.height = '15px';
  1328.  
  1329. getId(`cbRoad${type}`).onclick = (() => {
  1330. SCColor();
  1331. });
  1332. }
  1333. if (debug) log('Settings Loaded');
  1334. setupHandler();
  1335. }
  1336.  
  1337. function setupHandler() {
  1338. let rgb = {
  1339. r: 0, g: 0, b: 0, name: null
  1340. };
  1341. const listeDelSpeed = getId('CStable');
  1342. const btnDelSpeed = getElementsByClassName('delSpeed', listeDelSpeed);
  1343.  
  1344. for (let i = 0; i < btnDelSpeed.length; i++) {
  1345. const target = btnDelSpeed[i];
  1346. const index = target.id.split('_')[1];
  1347. target.onclick = getFunctionWithArgs(SCSpeeds, [unit, index, selectedState, selectedCountry]);
  1348. }
  1349.  
  1350. const listeEditZoom = getId('CSroadType');
  1351. const btnEditZoom = getElementsByClassName('modifyZoom', listeEditZoom);
  1352.  
  1353. for (let i = 0; i < btnEditZoom.length; i++) {
  1354. const target = btnEditZoom[i];
  1355. const index = target.id.split('_')[1];
  1356. const val = WMECSpeeds.typeOfRoad[parseInt(index, 10)].zoom;
  1357. target.onclick = getFunctionWithArgs(SCEditZoom, [index, val]);
  1358. }
  1359.  
  1360. getId('cbPaletteByCountrie').onclick = (() => {
  1361. getId('selectCountrie').style.display = (getId('cbPaletteByCountrie').checked) ? 'block' : 'none';
  1362. WMECSpeeds.PaletteByCountrie = getId('cbPaletteByCountrie').checked;
  1363. WMECSpeeds.MultiplePalette = false;
  1364. updateCountrieList();
  1365. getId('CStable').innerHTML = '';
  1366. getId('CSroadType').innerHTML = '';
  1367. LoadSettings();
  1368. SCColor();
  1369. });
  1370. getId('selectCountrie').onclick = (() => {
  1371. updateCountrieList();
  1372. getId('CStable').innerHTML = '';
  1373. getId('CSroadType').innerHTML = '';
  1374. LoadSettings();
  1375. });
  1376.  
  1377. getId('cbMultiplePalette').onclick = (() => {
  1378. getId('selectState').style.display = (getId('cbMultiplePalette').checked) ? 'block' : 'none';
  1379. WMECSpeeds.MultiplePalette = getId('cbMultiplePalette').checked;
  1380. WMECSpeeds.PaletteByCountrie = false;
  1381. if (WMECSpeeds.MultiplePalette === true) {
  1382. const stateToSelect = getTopState().attributes.name.replace(/ /g, '_');
  1383. let index;
  1384. for (index = 0; getId('selectState').options[index].value !== stateToSelect; index++) { /* empty */ }
  1385. getId('selectState').options[index].selected = true;
  1386. }
  1387. getId('CStable').innerHTML = '';
  1388. getId('CSroadType').innerHTML = '';
  1389. LoadSettings();
  1390. SCColor();
  1391. });
  1392.  
  1393. getId('selectState').onclick = (() => {
  1394. getId('CStable').innerHTML = '';
  1395. getId('CSroadType').innerHTML = '';
  1396. LoadSettings();
  1397. });
  1398.  
  1399. getId('edit_others').onclick = (() => {
  1400. getId('Conf_Others').style.display = 'block';
  1401. getId('Conf_Color').style.display = 'none';
  1402. getId('colorspeedsDiv').style.display = 'none';
  1403. getId('newspeed').value = null;
  1404. getId('ConfColor').style.backgroundColor = WMECSpeeds.speedColors.Others;
  1405. getId('newspeedColorDialog').style.display = 'block';
  1406. rgb = color2Rgb(WMECSpeeds.speedColors.Others);
  1407. actualiseColorRGB(rgb);
  1408. });
  1409.  
  1410. getId('cancel').onclick = (() => {
  1411. getId('Conf_Others').style.display = 'none';
  1412. getId('Conf_Color').style.display = 'none';
  1413. getId('newspeedColorDialog').style.display = 'none';
  1414. getId('colorspeedsDiv').style.display = 'block';
  1415. getId('newspeed').value = '';
  1416. });
  1417.  
  1418. getId('submit').onclick = (() => {
  1419. let newSpeed = getId('newspeed').value;
  1420. let newColor = getId('ConfColor').style.backgroundColor;
  1421. // log("newSpeed = ", newSpeed);log("newColor = ", newColor);
  1422. if (getId('Conf_Color').style.display === 'block' && newSpeed && newColor) {
  1423. if (WMECSpeeds.MultiplePalette === true) {
  1424. WMECSpeeds.speedColors.US[selectedState][unit][newSpeed] = newColor;
  1425. } else if (WMECSpeeds.PaletteByCountrie === true) {
  1426. WMECSpeeds.speedColors.Countries[selectedCountry][unit][newSpeed] = newColor;
  1427. } else if (WMECSpeeds.MultiplePalette === false && WMECSpeeds.PaletteByCountrie === false) {
  1428. WMECSpeeds.speedColors[unit][newSpeed] = newColor;
  1429. }
  1430. }
  1431. if (getId('Conf_Others').style.display === 'block' && newColor) {
  1432. WMECSpeeds.speedColors.Others = newColor;
  1433. getId('color_others').style.backgroundColor = WMECSpeeds.speedColors.Others;
  1434. }
  1435. getId('newspeed').value = '';
  1436. newSpeed = null;
  1437. newColor = null;
  1438. getId('CStable').innerHTML = '';
  1439. getId('CSroadType').innerHTML = '';
  1440. getId('Conf_Others').style.display = 'none';
  1441. getId('Conf_Color').style.display = 'none';
  1442. getId('newspeedColorDialog').style.display = 'none';
  1443. getId('colorspeedsDiv').style.display = 'block';
  1444. LoadSettings();
  1445. SCColor();
  1446. });
  1447.  
  1448. $('#ConfColor.dropdown-toggle').dropdown();
  1449. $('#ConfColor+.dropdown-menu li').click(function() {
  1450. getId('ConfColor').style.backgroundColor = this.style.backgroundColor;
  1451. rgb = color2Rgb(this.style.backgroundColor);
  1452. actualiseColorRGB(rgb);
  1453. });
  1454. /*
  1455. $("#ConfDash.dropdown-toggle").dropdown();
  1456. $('#ConfDash+.dropdown-menu li').click(function(){
  1457. getId('ConfDash').text=this.text;
  1458. });
  1459. */
  1460. getId('sliderRed').onmousemove = () => {
  1461. getId('valRed').value = getId('sliderRed').value;
  1462. rgb.r = getId('valRed').value;
  1463. rgb.g = getId('valGreen').value;
  1464. rgb.b = getId('valBlue').value;
  1465. rgb = color2Rgb(Rgb2String(rgb));
  1466. actualiseColorRGB(rgb);
  1467. };
  1468. getId('sliderGreen').onmousemove = () => {
  1469. getId('valGreen').value = getId('sliderGreen').value;
  1470. rgb.r = getId('valRed').value;
  1471. rgb.g = getId('valGreen').value;
  1472. rgb.b = getId('valBlue').value;
  1473. rgb = color2Rgb(Rgb2String(rgb));
  1474. actualiseColorRGB(rgb);
  1475. };
  1476. getId('sliderBlue').onmousemove = () => {
  1477. getId('valBlue').value = getId('sliderBlue').value;
  1478. rgb.r = getId('valRed').value;
  1479. rgb.g = getId('valGreen').value;
  1480. rgb.b = getId('valBlue').value;
  1481. rgb = color2Rgb(Rgb2String(rgb));
  1482. actualiseColorRGB(rgb);
  1483. };
  1484. getId('sliderOffset').onmousemove = () => {
  1485. WMECSpeeds.offsetValue = getId('sliderOffset').value;
  1486. getId('valOffset').value = getId('sliderOffset').value;
  1487. SCColor();
  1488. };
  1489. getId('sliderOpacity').onmousemove = () => {
  1490. WMECSpeeds.opacityValue = Number(getId('sliderOpacity').value / 100).toFixed(2);
  1491. getId('valOpacity').value = getId('sliderOpacity').value;
  1492. SCColor();
  1493. };
  1494. getId('sliderThickness').onmousemove = () => {
  1495. WMECSpeeds.thicknessValue = getId('sliderThickness').value;
  1496. getId('valThickness').value = getId('sliderThickness').value;
  1497. SCColor();
  1498. };
  1499.  
  1500. getId('valRed').onchange = () => {
  1501. const R = parseInt(getId('valRed').value, 10);
  1502. if ((R >= 0) && (R <= 255)) {
  1503. getId('sliderRed').value = getId('valRed').value;
  1504. rgb.r = getId('valRed').value;
  1505. rgb.g = getId('valGreen').value;
  1506. rgb.b = getId('valBlue').value;
  1507. rgb = color2Rgb(Rgb2String(rgb));
  1508. actualiseColorRGB(rgb);
  1509. } else {
  1510. getId('valRed').value = getId('sliderRed').value;
  1511. }
  1512. };
  1513.  
  1514. getId('valGreen').onchange = () => {
  1515. const G = parseInt(getId('valGreen').value, 10);
  1516. if ((G >= 0) && (G <= 255)) {
  1517. getId('sliderGreen').value = getId('valGreen').value;
  1518. rgb.r = getId('valRed').value;
  1519. rgb.g = getId('valGreen').value;
  1520. rgb.b = getId('valBlue').value;
  1521. rgb = color2Rgb(Rgb2String(rgb));
  1522. actualiseColorRGB(rgb);
  1523. } else {
  1524. getId('valGreen').value = getId('sliderGreen').value;
  1525. }
  1526. };
  1527. getId('valBlue').onchange = () => {
  1528. const B = parseInt(getId('valBlue').value, 10);
  1529. if ((B >= 0) && (B <= 255)) {
  1530. getId('sliderBlue').value = getId('valBlue').value;
  1531. rgb.r = getId('valRed').value;
  1532. rgb.g = getId('valGreen').value;
  1533. rgb.b = getId('valBlue').value;
  1534. rgb = color2Rgb(Rgb2String(rgb));
  1535. actualiseColorRGB(rgb);
  1536. } else {
  1537. getId('valBlue').value = getId('sliderBlue').value;
  1538. }
  1539. };
  1540. getId('valOffset').onchange = () => {
  1541. const R = parseInt(getId('valOffset').value, 10);
  1542. if ((R >= 1) && (R <= 10)) {
  1543. getId('sliderOffset').value = getId('valOffset').value;
  1544. WMECSpeeds.offsetValue = getId('valOffset').value;
  1545. SCColor();
  1546. } else {
  1547. getId('valOffset').value = getId('sliderOffset').value;
  1548. }
  1549. };
  1550. getId('valOpacity').onchange = () => {
  1551. const R = parseInt(getId('valOpacity').value, 10);
  1552. if ((R >= 0) && (R <= 100)) {
  1553. getId('sliderOpacity').value = getId('valOpacity').value;
  1554. WMECSpeeds.opacityValue = Number(getId('valOpacity').value / 100).toFixed(2);
  1555. SCColor();
  1556. } else {
  1557. getId('valOpacity').value = getId('sliderOpacity').value;
  1558. }
  1559. };
  1560. getId('valThickness').onchange = () => {
  1561. const R = parseInt(getId('valThickness').value, 10);
  1562. if ((R >= 2) && (R <= 10)) {
  1563. getId('sliderThickness').value = getId('valThickness').value;
  1564. WMECSpeeds.thicknessValue = getId('valThickness').value;
  1565. SCColor();
  1566. } else {
  1567. getId('valThickness').value = getId('sliderThickness').value;
  1568. }
  1569. };
  1570. }
  1571.  
  1572. function updateCountrieList() {
  1573. const selectCountrie = getId('selectCountrie');
  1574. let current = null;
  1575. if (selectCountrie.selectedIndex >= 0) current = selectCountrie.options[selectCountrie.selectedIndex].value;
  1576. if (current === null) current = getTopCountry().attributes.name.replace(/ /g, '_');
  1577.  
  1578. selectCountrie.options.length = 0;
  1579.  
  1580. for (var countrie in WMECSpeeds.speedColors.Countries) {
  1581. // create option in select menu
  1582. if (countrie === undefined) countrie = getTopCountry().attributes.name.replace(/ /g, '_');
  1583. var countrieOption = document.createElement('option');
  1584. var countrieText = document.createTextNode(countrie.replace(/_/g, ' '));
  1585.  
  1586. if (current !== null && countrie == current)
  1587. countrieOption.setAttribute('selected', true);
  1588. countrieOption.setAttribute('value', countrie);
  1589. countrieOption.appendChild(countrieText);
  1590. selectCountrie.appendChild(countrieOption);
  1591.  
  1592. }
  1593. }
  1594.  
  1595. function CSModifCouleur(unit, id, color, state) {
  1596. getId('Conf_Others').style.display = 'none';
  1597. getId('Conf_Color').style.display = 'block';
  1598. getId('colorspeedsDiv').style.display = 'none';
  1599. getId('newspeed').value = id;
  1600. getId('ConfColor').style.backgroundColor = color;
  1601. newspeedColorDialog.style.display = 'block';
  1602. const c = color2Rgb(color);
  1603. actualiseColorRGB(c);
  1604. }
  1605.  
  1606. function actualiseColorRGB(c) {
  1607. log('color: ', c);
  1608. getId('valRed').value = c.r;
  1609. getId('valGreen').value = c.g;
  1610. getId('valBlue').value = c.b;
  1611.  
  1612. getId('sliderRed').value = c.r;
  1613. getId('sliderGreen').value = c.g;
  1614. getId('sliderBlue').value = c.b;
  1615. getId('ConfColor').style.backgroundColor = Rgb2String(c);
  1616. getId('nameColor').innerHTML = c.name;
  1617. }
  1618.  
  1619. function SCSpeeds(unit, idx, state, contrie){
  1620. if (WMECSpeeds.MultiplePalette === true){
  1621. var answer = window.confirm(CSlang[5][CSI18n] + ' ' + idx + ' ' + unit + ' ' + CSlang[21][CSI18n] + ' ' + state + ' ?');
  1622. }else if (WMECSpeeds.PaletteByCountrie === true){
  1623. var answer = window.confirm(CSlang[5][CSI18n] + ' ' + idx + ' ' + unit + ' ' + CSlang[21][CSI18n] + ' ' + contrie + ' ?');
  1624. }else{var answer = window.confirm(CSlang[5][CSI18n] + ' ' + idx + ' ' + unit + ' ?');}
  1625.  
  1626. if (answer){
  1627. if (WMECSpeeds.MultiplePalette === true){
  1628. delete WMECSpeeds.speedColors.US[state][unit][idx];
  1629. }else if (WMECSpeeds.PaletteByCountrie === true){
  1630. delete WMECSpeeds.speedColors.Countries[contrie][unit][idx];
  1631. }else {delete WMECSpeeds.speedColors[unit][idx];}
  1632.  
  1633. getId('CStable').innerHTML = '';
  1634. getId('CSroadType').innerHTML = '';
  1635. LoadSettings();
  1636. }
  1637. }
  1638.  
  1639. function SCEditZoom(idx, val){
  1640. getId('editzoom').style.display = 'block';
  1641. getId('newvalzoom').value = val;
  1642. getId('texttype').textContent = WMECSpeeds.typeOfRoad[idx].name;
  1643.  
  1644. getId('submitZoom').onclick = (function(){
  1645. var newValZoom = getId('newvalzoom').value;
  1646. if (newValZoom) {
  1647. WMECSpeeds.typeOfRoad[idx].zoom = newValZoom;
  1648. }
  1649. getId('editzoom').style.display = 'none';
  1650. getId('newvalzoom').value = '';
  1651. getId('CStable').innerHTML = '';
  1652. getId('CSroadType').innerHTML = '';
  1653. LoadSettings();
  1654. });
  1655. getId('cancelZoom').onclick = (function(){
  1656. getId('editzoom').style.display = 'none';
  1657. getId('newvalzoom').value = '';
  1658. getId('CStable').innerHTML = '';
  1659. getId('CSroadType').innerHTML = '';
  1660. LoadSettings();
  1661. });
  1662. }
  1663.  
  1664. function shiftGeometry(d, line, trigo) // d=distance to shift, line=collection of OL points, trigo=boolean: true=left(trigo=CCW) false=right(CW) : fwd is CW, rev is trigo
  1665. {
  1666. if (!trigo)
  1667. d = -d;
  1668.  
  1669. function getOrthoVector(p1, p2)
  1670. {
  1671. return [p1.y - p2.y, p2.x - p1.x];
  1672. }
  1673.  
  1674. function normalizeVector(v)
  1675. {
  1676. if (v[0] * v[0] + v[1] * v[1] == 0)
  1677. return v;
  1678. var l = Math.sqrt(v[0] * v[0] + v[1] * v[1]);
  1679. return [v[0] / l, v[1] / l];
  1680. }
  1681.  
  1682. var points = [];
  1683. for (var i = 0; i < line.length; i++)
  1684. {
  1685. var vcount = 0;
  1686. // compute orthogonal vectors:
  1687. var prevVector = [0, 0];
  1688. var nextVector = [0, 0];
  1689. if (i > 0) // can compute prev
  1690. {
  1691. var p1 = line[i - 1];
  1692. var p2 = line[i];
  1693. prevVector = getOrthoVector(p1, p2);
  1694. prevVector = normalizeVector(prevVector);
  1695. vcount++;
  1696. }
  1697. if (i < line.length - 1) // can compute next
  1698. {
  1699. var p1 = line[i];
  1700. var p2 = line[i + 1];
  1701. nextVector = getOrthoVector(p1, p2);
  1702. nextVector = normalizeVector(nextVector);
  1703. vcount++;
  1704. }
  1705. // sum vectors and normalize
  1706. var v = [0, 0];
  1707. if (vcount != 0)
  1708. v = [(prevVector[0] + nextVector[0]) / vcount, (prevVector[1] + nextVector[1]) / vcount];
  1709. //v=normalizeVector(v);
  1710. points.push(new CSpeedOpenLayers.Geometry.Point(line[i].x + v[0] * d, line[i].y + v[1] * d));
  1711. }
  1712. return points;
  1713. }
  1714.  
  1715. function SCColor() {
  1716. function getByID(obj, id){
  1717. if (typeof(obj.getObjectById) == 'function'){
  1718. return obj.getObjectById(id);
  1719. }else if (typeof(obj.getObjectById) == 'undefined'){
  1720. return obj.get(id);
  1721. }
  1722. }
  1723. //log('SCColor');
  1724. try { mapLayer.destroyFeatures();
  1725. }catch(err){log('err destroyFeatures: ', err);}
  1726.  
  1727. if (getTopCountry() === null) return;
  1728.  
  1729. if ( CSpeedsCountries !== undefined && /*CSpeedsCountries.top*/getTopCountry() !== undefined){
  1730. getId('stateChoise').style.display = (/*CSpeedsCountries.top*/getTopCountry().attributes.name == 'United States') ? 'block' : 'none';
  1731. }
  1732. var lineFeature = [];
  1733.  
  1734. for (var i = 0; i < RoadToScan.length; ++i){
  1735. var type = RoadToScan[i];
  1736. WMECSpeeds.typeOfRoad[type].checked = getId('cbRoad' + type).checked;
  1737. }
  1738.  
  1739. for (var seg in CSpeedsModel.segments.objects) {
  1740. var segment = getByID(CSpeedsModel.segments, seg);
  1741. var attributes = segment.attributes;
  1742. var roadType = attributes.roadType;
  1743. var roundabout = (attributes.junctionID === null) ? false : true;
  1744. var line = getId(segment.getOLGeometry().id);
  1745. var fwdspeed = attributes.fwdMaxSpeed;
  1746. var revspeed = attributes.revMaxSpeed;
  1747. var fwdspeedUnverified = attributes.fwdMaxSpeedUnverified;
  1748. var revspeedUnverified = attributes.revMaxSpeedUnverified;
  1749. var fwddir = attributes.fwdDirection;
  1750. var revdir = attributes.revDirection;
  1751. //var fwdID = "",revID="";
  1752. var isSelected = (segment.selected == true) ? true : false;
  1753. var isModified = (segment.state == 'Update') ? true : false;
  1754.  
  1755. if (attributes.primaryStreetID === null || attributes.primaryStreetID === undefined) continue;
  1756.  
  1757. if (getByID(CSpeedsModel.streets, attributes.primaryStreetID) === null || getByID(CSpeedsModel.streets, attributes.primaryStreetID) === undefined){
  1758. if (debug) log('CSpeedsModel.streets.get(' + attributes.primaryStreetID + ') =', getByID(CSpeedsModel.streets, attributes.primaryStreetID));
  1759. continue;
  1760. }
  1761.  
  1762. var cid = getByID(CSpeedsModel.streets, attributes.primaryStreetID).attributes.cityID;
  1763. var stateID = null;
  1764. var countryID = null;
  1765.  
  1766. if (getByID(CSpeedsModel.cities, cid) === null || getByID(CSpeedsModel.cities, cid) === undefined){
  1767. if (debug) log('CSpeedsModel.cities.get(' + cid + ') =', getByID(CSpeedsModel.cities, cid));
  1768. continue;
  1769. }
  1770.  
  1771. stateID = getByID(CSpeedsModel.cities, cid).attributes.stateID;
  1772. countryID = getByID(CSpeedsModel.cities, cid).attributes.countryID;
  1773.  
  1774. var state = getByID(CSpeedsModel.states, stateID).attributes.name.replace(/ /g, '_');
  1775. var countrie = getByID(CSpeedsModel.countries, countryID).attributes.name.replace(/ /g, '_');
  1776.  
  1777. if (WMECSpeeds.PaletteByCountrie == true && WMECSpeeds.speedColors.Countries[countrie] === undefined){
  1778. WMECSpeeds.speedColors.Countries[countrie] = {};
  1779. WMECSpeeds.speedColors.Countries[countrie][unit] = cloneObj(WMECSpeeds.speedColors[unit]);
  1780. updateCountrieList();
  1781. LoadSettings();
  1782. log('SCColor WMECSpeeds.speedColors.Countries.' + countrie + '.' + unit + ' = ', WMECSpeeds.speedColors.Countries[countrie][unit]);
  1783. }
  1784.  
  1785. if (WMECSpeeds.MultiplePalette == true && WMECSpeeds.speedColors.US[state] !== undefined && WMECSpeeds.speedColors.US[state][unit] === undefined){
  1786. WMECSpeeds.speedColors.US[state][unit] = cloneObj(WMECSpeeds.speedColors[unit]);
  1787. //log("SCColor WMECSpeeds.speedColors.US."+state+"."+unit+" = ",WMECSpeeds.speedColors.US[state][unit]);
  1788. }
  1789.  
  1790. // check that WME hasn't highlighted this segment
  1791. if (isSelected || isModified) continue;
  1792.  
  1793. if (zoom != CSpeedsMap.olMap.zoom) {
  1794. zoom = CSpeedsMap.olMap.zoom;
  1795. //log('zoom = ' + zoom + 'W.map.getResolution() = '+W.map.getResolution());
  1796. }
  1797. var shiftValue = WMECSpeeds.offsetValue * W.map.getResolution();
  1798.  
  1799. if (RoadToScan.indexOf(roadType) == -1 ) continue;
  1800. if ((roundabout != false) && (WMECSpeeds.typeOfRoad['999'].checked == false)) continue;
  1801.  
  1802. if (unit == 'mph'){
  1803. fwdspeed = (fwdspeed != null) ? (Math.trunc(fwdspeed * 0.625)) : null;
  1804. revspeed = (revspeed != null) ? (Math.trunc(revspeed * 0.625)) : null;
  1805. }
  1806. //log("fwdspeed= "+ fwdspeed + " " + unit + " ; revspeed= " + revspeed + " " + unit);
  1807.  
  1808. // turn off highlights when roads are no longer visible
  1809.  
  1810. if ((zoom < WMECSpeeds.typeOfRoad[roadType].zoom) || !WMECSpeeds.typeOfRoad[roadType].checked) {
  1811. continue;
  1812. }
  1813. WMECSpeeds.visibility = mapLayer.visibility;
  1814.  
  1815. if (fwdspeed && WMECSpeeds.visibility) {
  1816. //Color for forward speed
  1817. var newWidth = '', newColor = '', newDashes = '', newOpacity = '';
  1818.  
  1819. if (WMECSpeeds.MultiplePalette === false && WMECSpeeds.PaletteByCountrie === false){
  1820. if (WMECSpeeds.speedColors[unit].hasOwnProperty(fwdspeed)) newColor = WMECSpeeds.speedColors[unit][fwdspeed];
  1821. }else if (WMECSpeeds.PaletteByCountrie === true){
  1822. if (WMECSpeeds.speedColors.Countries[countrie][unit].hasOwnProperty(fwdspeed)) newColor = WMECSpeeds.speedColors.Countries[countrie][unit][fwdspeed];
  1823. }else if (WMECSpeeds.MultiplePalette === true && WMECSpeeds.speedColors.US[state] !== undefined){
  1824. if (WMECSpeeds.speedColors.US[state][unit].hasOwnProperty(fwdspeed)) newColor = WMECSpeeds.speedColors.US[state][unit][fwdspeed];
  1825. }
  1826. /*
  1827. if (newColor!=""){
  1828. //Dashes
  1829. if (fwddir==true && fwdspeed && !fwdspeedUnverified) { newWidth = 6; newOpacity = 0.8; newDashes = "5 10"; } // verified speed
  1830. else if (fwddir==true && fwdspeed && fwdspeedUnverified) { newColor = WMECSpeeds.speedColors.Others; newWidth = 4; newOpacity = 0.8; newDashes = "2 10";} // unverified speed
  1831. }else if (fwddir==true && fwdspeed) { newWidth = 4; newColor = WMECSpeeds.speedColors.Others; newOpacity = 0.9; newDashes = "5 5"; } // other
  1832. */
  1833. if (newColor != ''){
  1834. //Dashes
  1835. if (fwddir == true && fwdspeed && !fwdspeedUnverified) { newWidth = WMECSpeeds.thicknessValue; newOpacity = WMECSpeeds.opacityValue; newDashes = '5 10'; } // verified speed
  1836. else if (fwddir == true && fwdspeed && fwdspeedUnverified) { newColor = WMECSpeeds.speedColors.Others; newWidth = WMECSpeeds.thicknessValue; newOpacity = 0.8; newDashes = '2 10';} // unverified speed
  1837. }else if (fwddir == true && fwdspeed) { newWidth = WMECSpeeds.thicknessValue; newColor = WMECSpeeds.speedColors.Others; newOpacity = WMECSpeeds.opacityValue; newDashes = '5 5'; } // other
  1838.  
  1839. if (newColor != ''){
  1840. var style = {
  1841. strokeColor: newColor,
  1842. strokeOpacity: newOpacity,
  1843. strokeWidth: newWidth,
  1844. strokeDashstyle: newDashes
  1845. };
  1846.  
  1847. var points = [];
  1848. var segID = attributes.id;
  1849. points = shiftGeometry(shiftValue, segment.getOLGeometry().getVertices(), CSpeedsModel.getTopCountry().getAttribute('leftHandTraffic'));
  1850.  
  1851. var newline = new CSpeedOpenLayers.Geometry.LineString(points);
  1852.  
  1853. lineFeature.push(new CSpeedOpenLayers.Feature.Vector(newline, null, style));
  1854. //log("segment id: " + attributes.id + ' newColor: '+ newColor + ' segment.CSpeedsFwd.fwdColor: ' + segment.CSpeedsFwd.fwdColor + ' lineFeature: ',lineFeature);
  1855. }
  1856. }
  1857. if (revspeed && WMECSpeeds.visibility) {
  1858. //Color for reverse speed
  1859. var newWidth = '', newColor = '', newDashes = '', newOpacity = '', newDashOffset = '';
  1860.  
  1861. if (WMECSpeeds.MultiplePalette === false && WMECSpeeds.PaletteByCountrie === false){
  1862. if (WMECSpeeds.speedColors[unit].hasOwnProperty(revspeed)) newColor = WMECSpeeds.speedColors[unit][revspeed];
  1863. }else if (WMECSpeeds.PaletteByCountrie === true){
  1864. if (WMECSpeeds.speedColors.Countries[countrie][unit].hasOwnProperty(revspeed)) newColor = WMECSpeeds.speedColors.Countries[countrie][unit][revspeed];
  1865. }else if (WMECSpeeds.MultiplePalette === true && WMECSpeeds.speedColors.US[state] !== undefined){
  1866. if (WMECSpeeds.speedColors.US[state][unit].hasOwnProperty(revspeed)) newColor = WMECSpeeds.speedColors.US[state][unit][revspeed];
  1867. }
  1868. /*
  1869. if (newColor!=""){
  1870. //Dashes
  1871. if (revdir==true && revspeed && !revspeedUnverified) { newWidth = 6; newOpacity = 0.8; newDashes = "5 10"; } // verified speed
  1872. else if (revdir==true && revspeed && revspeedUnverified) { newColor = WMECSpeeds.speedColors.Others; newWidth = 4; newOpacity = 0.8; newDashes = "2 10";} // unverified speed
  1873. }else if (revdir==true && revspeed) { newWidth = 4; newColor = WMECSpeeds.speedColors.Others; newOpacity = 0.9; newDashes = "5 5"; } // other
  1874. */
  1875. if (newColor != ''){
  1876. //Dashes
  1877. if (revdir == true && revspeed && !revspeedUnverified) { newWidth = WMECSpeeds.thicknessValue; newOpacity = WMECSpeeds.opacityValue; newDashes = '5 10'; } // verified speed
  1878. else if (revdir == true && revspeed && revspeedUnverified) { newColor = WMECSpeeds.speedColors.Others; newWidth = WMECSpeeds.thicknessValue; newOpacity = WMECSpeeds.opacityValue; newDashes = '2 10';} // unverified speed
  1879. }else if (revdir == true && revspeed) { newWidth = WMECSpeeds.thicknessValue; newColor = WMECSpeeds.speedColors.Others; newOpacity = WMECSpeeds.opacityValue; newDashes = '5 5'; } // other
  1880.  
  1881. if (newColor != ''){
  1882. var style = {
  1883. strokeColor: newColor,
  1884. strokeOpacity: newOpacity,
  1885. strokeWidth: newWidth,
  1886. strokeDashstyle: newDashes,
  1887. };
  1888.  
  1889. var points = [];
  1890. var segID = attributes.id;
  1891.  
  1892. points = shiftGeometry(shiftValue, segment.getOLGeometry().getVertices(), !CSpeedsModel.getTopCountry().getAttribute('leftHandTraffic'));
  1893.  
  1894. var newline = new CSpeedOpenLayers.Geometry.LineString(points);
  1895.  
  1896. lineFeature.push(new CSpeedOpenLayers.Feature.Vector(newline, null, style));
  1897. }
  1898. }
  1899.  
  1900. }
  1901.  
  1902. // log("lineFeature = ",lineFeature);
  1903. // Display new array of segments
  1904. try {
  1905. mapLayer.addFeatures(lineFeature);
  1906. } catch (err) { log('err addFeatures: ', err); }
  1907. if (debug) log(`Total load time without WW of ${Math.round(performance.now() - scriptStartTime)} ms.`);
  1908. if (debug) log(`Total load time with WW of ${Math.round(performance.now() - loadStartTime)} ms.`);
  1909. }
  1910.  
  1911. /* begin running the code! */
  1912. counterStart();

QingJ © 2025

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