/* eslint-disable max-len */
// ==UserScript==
// @name WME Color Speeds
// @name:fr WME Color Speeds
// @version 2024.04.15.01
// @description Adds colors to road segments to show their speed
// @description:fr Colorisation des segments selon leurs vitesses.
// @include https://www.waze.com/editor*
// @include https://www.waze.com/*/editor*
// @include https://beta.waze.com/editor*
// @include https://beta.waze.com/*/editor*
// @exclude https://www.waze.com/user*
// @exclude https://www.waze.com/*/user*
// @grant GM_xmlhttpRequest
// @connect greasyfork.org
// @namespace https://greasyfork.org/scripts/14044-wme-color-speeds
// @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
// @author Created by French Script Team, Maintained by WazeDev
// @copyright Sebiseba, seb-d59 & DummyD2 - 2015-2019
// ==/UserScript==
/* global W */
/* global WazeWrap */
/* global GM_info */
/* global CSpeedsWaze */
/* global I18n */
/* global $ */
// *********************
// ** DECLARATIONS **
// *********************
// eslint-disable-next-line camelcase
const scriptName = GM_info.script.name;
// eslint-disable-next-line camelcase
const currentVersion = GM_info.script.version;
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>';
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>';
// eslint-disable-next-line camelcase
const greasyForkUrl = GM_info.script.namespace;
const downloadUrl = 'https://greasyfork.org/scripts/14044-wme-color-speeds/code/wme-color-speeds.user.js';
const forumUrl = 'https://www.waze.com/forum/viewtopic.php?t=167387';
// let oldScriptVersion;
const debug = false;
let WMECSpeeds = {};
let loadStartTime;
let scriptStartTime;
const iconUndo = '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';
const iconDelete = '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';
const iconSubmit = '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';
const iconEdit = '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';
const colors = [
'(255,0,128)', '(255,0,160)', '(255,0,192)', '(255,0,224)', '(255,0,255)', '(224,0,255)',
'(192,0,255)', '(160,0,255)', '(128,0,255)', '(96,0,255)', '(64,0,255)', '(32,0,255)',
'(0,0,255)', '(0,32,255)', '(0,64,255)', '(0,96,255)', '(0,128,255)', '(0,160,255)',
'(0,192,255)', '(0,224,255)', '(0,255,255)', '(0,255,224)', '(0,255,192)', '(0,255,160)',
'(0,255,128)', '(0,255,96)', '(0,255,64)', '(0,255,32)', '(0,255,0)', '(32,255,0)',
'(64,255,0)', '(96,255,0)', '(128,255,0)', '(160,255,0)', '(192,255,0)', '(224,255,0)',
'(255,255,0)', '(255,224,0)', '(255,192,0)', '(255,160,0)', '(255,128,0)', '(255,96,0)',
'(255,64,0)', '(255,0,0)', 'Pink', 'LightPink', 'HotPink', 'DeepPink', 'PaleVioletRed',
'MediumVioletRed', 'LightSalmon', 'Salmon', 'DarkSalmon', 'LightCoral', 'IndianRed', 'Crimson',
'FireBrick', 'DarkRed', 'Red', 'OrangeRed', 'Tomato', 'Coral', 'DarkOrange', 'Orange', 'Yellow',
'LightYellow', 'LemonChiffon', 'LightGoldenrodYellow', 'PapayaWhip', 'Moccasin', 'PeachPuff',
'PaleGoldenrod', 'Khaki', 'DarkKhaki', 'Gold', 'Cornsilk', 'BlanchedAlmond', 'Bisque',
'NavajoWhite', 'Wheat', 'BurlyWood', 'Tan', 'RosyBrown', 'SandyBrown', 'Goldenrod',
'DarkGoldenrod', 'Peru', 'Chocolate', 'SaddleBrown', 'Sienna', 'Brown', 'Maroon',
'DarkOliveGreen', 'Olive', 'OliveDrab', 'YellowGreen', 'LimeGreen', 'Lime', 'LawnGreen',
'Chartreuse', 'GreenYellow', 'SpringGreen', 'MediumSpringGreen', 'LightGreen', 'PaleGreen',
'DarkSeaGreen', 'MediumAquamarine', 'MediumSeaGreen', 'SeaGreen', 'ForestGreen', 'Green',
'DarkGreen', 'Aqua', 'Cyan', 'LightCyan', 'PaleTurquoise', 'Aquamarine', 'Turquoise',
'MediumTurquoise', 'DarkTurquoise', 'LightSeaGreen', 'CadetBlue', 'DarkCyan', 'Teal',
'LightSteelBlue', 'PowderBlue', 'LightBlue', 'SkyBlue', 'LightSkyBlue', 'DeepSkyBlue',
'DodgerBlue', 'CornflowerBlue', 'SteelBlue', 'RoyalBlue', 'Blue', 'MediumBlue', 'DarkBlue',
'Navy', 'MidnightBlue', 'Lavender', 'Thistle', 'Plum', 'Violet', 'Orchid', 'Fuchsia',
'Magenta', 'MediumOrchid', 'MediumPurple', 'BlueViolet', 'DarkViolet', 'DarkOrchid',
'DarkMagenta', 'Purple', 'Indigo', 'DarkSlateBlue', 'RebeccaPurple', 'SlateBlue',
'MediumSlateBlue', 'Snow', 'Honeydew', 'MintCream', 'Azure', 'AliceBlue', 'GhostWhite',
'WhiteSmoke', 'Seashell', 'Beige', 'OldLace', 'FloralWhite', 'Ivory', 'AntiqueWhite',
'Linen', 'LavenderBlush', 'MistyRose', 'LightSlateGray', 'SlateGray', 'DarkSlateGray',
'White', '#EEE', 'Gainsboro', '#DDD', 'LightGrey', '#CCC', 'Silver', '#BBB', '#AAA',
'DarkGray', '#999', '#888', 'Gray', '#777', 'DimGray', '#666', '#555', '#444', '#333',
'#222', '#111', 'Black'
];
// speedColors[unit][speed] = color //-----> Default
WMECSpeeds.speedColors = {
kmh: {
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'
},
mph: {
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'
},
Others: '#f00'
};
const colorsUS = {
Alabama: {},
Alaska: {},
Arizona: {},
Arkansas: {},
California: {},
Colorado: {},
Connecticut: {},
Delaware: {},
District_of_Columbia: {},
Florida: {},
Georgia: {},
Hawaii: {},
Idaho: {},
Illinois: {},
Indiana: {},
Iowa: {},
Kansas: {},
Kentucky: {},
Louisiana: {},
Maine: {},
Maryland: {},
Massachusetts: {},
Michigan: {},
Minnesota: {},
Mississippi: {},
Missouri: {},
Montana: {},
Nebraska: {},
Nevada: {},
New_Hampshire: {},
New_Jersey: {},
New_Mexico: {},
New_York: {},
North_Carolina: {},
North_Dakota: {},
Ohio: {},
Oklahoma: {},
Oregon: {},
Pennsylvania: {},
Rhode_Island: {},
South_Carolina: {},
South_Dakota: {},
Tennessee: {},
Texas: {},
Utah: {},
Vermont: {},
Virginia: {},
Washington: {},
West_Virginia: {},
Wisconsin: {},
Wyoming: {},
United_States_Minor_Outlying_Islands: {},
United_States_Virgin_Islands: {}
};
const multiplePalette = false;
const paletteByCountry = false;
let unit;
let selectedState;
let selectedCountry;
let mapLayer = [];
let toggler;
let groupToggler;
let zoom = 0;
const RoadToScan = [3, 6, 7, 4, 2, 1, 22, 20, 17, 8, 999];
// var RoadUpToStreet = [2,3,6,7];
// var highway = [3,6,7];
const typeOfRoad = {
3: { name: 'Freeways', checked: true, zoom: 14 },
6: { name: 'Major Highway', checked: true, zoom: 14 },
7: { name: 'Minor Highway', checked: true, zoom: 14 },
4: { name: 'Ramps', checked: true, zoom: 15 },
2: { name: 'Primary Street', checked: false, zoom: 15 },
1: { name: 'Streets', checked: false, zoom: 16 },
22: { name: 'Narrow Streets', checked: false, zoom: 16 },
20: { name: 'Parking Lot Road', checked: false, zoom: 16 },
17: { name: 'Private Road', checked: false, zoom: 16 },
8: { name: 'Off Road', checked: false, zoom: 16 },
999: { name: 'Roundabout', checked: false, zoom: false }
};
WMECSpeeds.typeOfRoad = typeOfRoad;
const roadTypeZoomInfo = {
3: { en: 'Freeway highlights require zoom of 14+', fr: 'Surligner les autoroutes nécessite un niveau de zoom supérieur ou égal à 14' },
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' },
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' },
4: { en: 'Ramp highlights require zoom of 14+', fr: 'Surligner les bretelles nécessite un niveau de zoom supérieur ou égal à 14' },
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' },
1: { en: 'Street highlights require zoom of 16+', fr: 'Surligner les rues nécessite un niveau de zoom supérieur ou égal à 16' },
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' },
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' },
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' },
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' },
999: { en: 'Roundabouts are highlighted based on their Road Type', fr: 'Les ronds-points sont surlignés en fonction de leur type de route' }
};
// 5: "Walking Trails",
// 10: "Pedestrian Bw",
// 14: "Ferry",
// 16: "Stairway",
// 17: "Private Road",
// 18: "Railroad",
// 19: "Runway/Taxiway"
// 21: "Service Road"
// WMECSpeeds.selectedRoadType = [];
/*
const dashStyles = [
'Solid',
'ShortDash',
'ShortDot',
'ShortDashDot',
'ShortDashDotDot',
'Dot',
'Dash',
'LongDash',
'DashDot',
'LongDashDot',
'LongDashDotDot'
];
*/
let CSI18n = 'en';
const CSlang = {
1: { fr: 'Vitesses :', en: 'Speeds:' },
2: { fr: 'Configuration des couleurs :', en: 'Color Control Panel:' },
3: { fr: 'Couleurs :', en: 'Colors:' },
4: { fr: 'Ajouter une vitesse', en: 'Add new speed' },
5: { fr: 'Supprimer', en: 'Delete' },
6: { fr: 'Annuler', en: 'Cancel' },
7: { fr: 'Autres', en: 'Others' },
8: { fr: 'Modifier', en: 'Edit' },
9: { fr: 'Type de route', en: 'Road type' },
10: { fr: 'Zoom', en: 'Zoom' },
11: { fr: 'Rouge :', en: 'Red:' },
12: { fr: 'Vert :', en: 'Green:' },
13: { fr: 'Bleu :', en: 'Blue:' },
14: { fr: 'Valider', en: 'Validate' },
15: { fr: 'Décalage :', en: 'Offset:' },
16: { fr: 'Opacité :', en: 'Opacity:' },
17: { fr: 'Épaisseur :', en: 'Thickness:' },
18: { fr: 'Rond-point', en: 'Roundabout' },
19: { fr: 'Une palette par pays', en: 'One palette by country' },
20: { fr: 'Une palette par état (USA uniquement)', en: 'One Palette by State (US only)' },
21: { fr: 'pour', en: 'for' },
22: { fr: 'Autoroute', en: 'Freeway' },
23: { fr: 'Route majeure', en: 'Major Highway' },
24: { fr: 'Route mineure', en: 'Minor Highway' },
25: { fr: 'Bretelle', en: 'Ramps' },
26: { fr: 'Rue principale', en: 'Primary Street' },
27: { fr: 'Rue', en: 'Street' },
28: { fr: 'Rue étroite', en: 'Narrow Street' },
29: { fr: 'Voie de parking', en: 'Parking Lot Road' },
30: { fr: 'Voie privée', en: 'Private Road' },
31: { fr: 'Chemin de terre', en: 'Off Road' },
32: { fr: 'Vitesses', en: 'Speeds' },
33: { fr: 'Couleurs', en: 'Colors' },
};
WMECSpeeds.visibility = true;
const offsetValue = 3;
const opacityValue = 0.8;
const thicknessValue = 6;
let newspeedColorDialog;
// **********************
// ** HELPER FUNCTIONS **
// **********************
function log(msg, obj) {
if (obj == null) {
// eslint-disable-next-line camelcase, no-undef
console.log(`${GM_info.script.name} v${currentVersion} - ${msg}`);
} else if (debug) {
// eslint-disable-next-line camelcase, no-undef
console.debug(`${GM_info.script.name} v${currentVersion} - ${msg} `, obj);
}
}
function getId(node) {
return document.getElementById(node);
}
function getElementsByClassName(classname, node) {
node = node || document.body;
return Array.from(node.querySelectorAll(`.${classname}`));
}
function getFunctionWithArgs(func, args) {
return (
function() {
const jsonArgs = JSON.stringify(args);
return function() {
args = JSON.parse(jsonArgs);
func.apply(this, args);
};
}
)();
}
function IsJsonString(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
function cloneObj(obj) {
const copy = JSON.parse(JSON.stringify(obj));
return copy;
}
function Rgb2String(rgb) {
rgb = roundDecimals(rgb);
return `rgb(${rgb.r},${rgb.g},${rgb.b})`;
// return "rgb(" + Math.round(rgb.r) +","+ Math.round(rgb.g) +","+ Math.round(rgb.b) +")";
}
function color2Rgb(c) {
c = c.toLowerCase();
function parseRgb(arr) {
const rgb = {
r: parseInt(arr[0], 10) || 0,
g: parseInt(arr[1], 10) || 0,
b: parseInt(arr[2], 10) || 0,
name: null
};
rgb.r = Math.min(255, rgb.r);
rgb.g = Math.min(255, rgb.g);
rgb.b = Math.min(255, rgb.b);
if (debug) log(`Red: ${rgb.r}, Green: ${rgb.g}, Blue: ${rgb.b}`);
return rgb;
}
if (c.substr(0, 3) === 'rgb') {
const arr = c
.substring(3)
.replace('(', '')
.replace(')', '')
.split(',')
.map(val => val.trim());
if (arr.length === 3 && arr.every(val => !isNaN(val))) {
const colorrgbs = getColorArr('rgbs');
const colornames = getColorArr('names');
const matchIndex = colorrgbs.findIndex(color => JSON.stringify(arr) === JSON.stringify(color));
if (matchIndex !== -1) {
return {
r: arr[0],
g: arr[1],
b: arr[2],
name: colornames[matchIndex]
};
}
return parseRgb(arr);
}
} else {
let colornames = getColorArr('names');
const matchIndex = colornames.findIndex(name => c === name.toLowerCase());
if (matchIndex !== -1) {
const colorrgbs = getColorArr('rgbs');
if (debug) log(`${colornames}`);
return {
r: colorrgbs[matchIndex][0],
g: colorrgbs[matchIndex][1],
b: colorrgbs[matchIndex][2],
name: colornames[matchIndex]
};
}
c = c.replace('#', '');
const colorHex = getColorArr('hexs');
const hexMatchIndex = colorHex.findIndex(hex => c === hex);
if (hexMatchIndex !== -1) {
colornames = getColorArr('names');
return { name: colornames[hexMatchIndex] };
}
if (c.length === 3) {
c = c[0] + c[0] + c[1] + c[1] + c[2] + c[2];
}
const arr = [
parseInt(c.substr(0, 2), 16),
parseInt(c.substr(2, 2), 16),
parseInt(c.substr(4, 2), 16)
];
return parseRgb(arr);
}
return {
r: 0,
g: 0,
b: 0,
name: null
};
}
// eslint-disable-next-line consistent-return
function getColorArr(x) {
if (x === 'names') {
return ['AliceBlue', 'AntiqueWhite', 'Aqua', 'Aquamarine', 'Azure', 'Beige', 'Bisque', 'Black', 'BlanchedAlmond',
'Blue', 'BlueViolet', 'Brown', 'BurlyWood', 'CadetBlue', 'Chartreuse', 'Chocolate', 'Coral', 'CornflowerBlue', 'Cornsilk', 'Crimson',
'Cyan', 'DarkBlue', 'DarkCyan', 'DarkGoldenRod', 'DarkGray', 'DarkGrey', 'DarkGreen', 'DarkKhaki', 'DarkMagenta', 'DarkOliveGreen',
'DarkOrange', 'DarkOrchid', 'DarkRed', 'DarkSalmon', 'DarkSeaGreen', 'DarkSlateBlue', 'DarkSlateGray', 'DarkSlateGrey', 'DarkTurquoise',
'DarkViolet', 'DeepPink', 'DeepSkyBlue', 'DimGray', 'DimGrey', 'DodgerBlue', 'FireBrick', 'FloralWhite', 'ForestGreen', 'Fuchsia',
'Gainsboro', 'GhostWhite', 'Gold', 'GoldenRod', 'Gray', 'Grey', 'Green', 'GreenYellow', 'HoneyDew', 'HotPink', 'IndianRed', 'Indigo',
'Ivory', 'Khaki', 'Lavender', 'LavenderBlush', 'LawnGreen', 'LemonChiffon', 'LightBlue', 'LightCoral', 'LightCyan',
'LightGoldenRodYellow', 'LightGray', 'LightGrey', 'LightGreen', 'LightPink', 'LightSalmon', 'LightSeaGreen', 'LightSkyBlue',
'LightSlateGray', 'LightSlateGrey', 'LightSteelBlue', 'LightYellow', 'Lime', 'LimeGreen', 'Linen', 'Magenta', 'Maroon',
'MediumAquaMarine', 'MediumBlue', 'MediumOrchid', 'MediumPurple', 'MediumSeaGreen', 'MediumSlateBlue', 'MediumSpringGreen',
'MediumTurquoise', 'MediumVioletRed', 'MidnightBlue', 'MintCream', 'MistyRose', 'Moccasin', 'NavajoWhite', 'Navy', 'OldLace',
'Olive', 'OliveDrab', 'Orange', 'OrangeRed', 'Orchid', 'PaleGoldenRod', 'PaleGreen', 'PaleTurquoise', 'PaleVioletRed',
'PapayaWhip', 'PeachPuff', 'Peru', 'Pink', 'Plum', 'PowderBlue', 'Purple', 'RebeccaPurple', 'Red', 'RosyBrown', 'RoyalBlue',
'SaddleBrown', 'Salmon', 'SandyBrown', 'SeaGreen', 'SeaShell', 'Sienna', 'Silver', 'SkyBlue', 'SlateBlue', 'SlateGray', 'SlateGrey',
'Snow', 'SpringGreen', 'SteelBlue', 'Tan', 'Teal', 'Thistle', 'Tomato', 'Turquoise', 'Violet', 'Wheat', 'White', 'WhiteSmoke',
'Yellow', 'YellowGreen'];
}
if (x === 'hexs') {
return ['f0f8ff', 'faebd7', '00ffff', '7fffd4', 'f0ffff', 'f5f5dc', 'ffe4c4', '000000', 'ffebcd', '0000ff', '8a2be2', 'a52a2a', 'deb887',
'5f9ea0', '7fff00', 'd2691e', 'ff7f50', '6495ed', 'fff8dc', 'dc143c', '00ffff', '00008b', '008b8b', 'b8860b', 'a9a9a9', 'a9a9a9', '006400',
'bdb76b', '8b008b', '556b2f', 'ff8c00', '9932cc', '8b0000', 'e9967a', '8fbc8f', '483d8b', '2f4f4f', '2f4f4f', '00ced1', '9400d3', 'ff1493',
'00bfff', '696969', '696969', '1e90ff', 'b22222', 'fffaf0', '228b22', 'ff00ff', 'dcdcdc', 'f8f8ff', 'ffd700', 'daa520', '808080', '808080',
'008000', 'adff2f', 'f0fff0', 'ff69b4', 'cd5c5c', '4b0082', 'fffff0', 'f0e68c', 'e6e6fa', 'fff0f5', '7cfc00', 'fffacd', 'add8e6', 'f08080',
'e0ffff', 'fafad2', 'd3d3d3', 'd3d3d3', '90ee90', 'ffb6c1', 'ffa07a', '20b2aa', '87cefa', '778899', '778899', 'b0c4de', 'ffffe0', '00ff00',
'32cd32', 'faf0e6', 'ff00ff', '800000', '66cdaa', '0000cd', 'ba55d3', '9370db', '3cb371', '7b68ee', '00fa9a', '48d1cc', 'c71585', '191970',
'f5fffa', 'ffe4e1', 'ffe4b5', 'ffdead', '000080', 'fdf5e6', '808000', '6b8e23', 'ffa500', 'ff4500', 'da70d6', 'eee8aa', '98fb98', 'afeeee',
'db7093', 'ffefd5', 'ffdab9', 'cd853f', 'ffc0cb', 'dda0dd', 'b0e0e6', '800080', '663399', 'ff0000', 'bc8f8f', '4169e1', '8b4513', 'fa8072',
'f4a460', '2e8b57', 'fff5ee', 'a0522d', 'c0c0c0', '87ceeb', '6a5acd', '708090', '708090', 'fffafa', '00ff7f', '4682b4', 'd2b48c', '008080',
'd8bfd8', 'ff6347', '40e0d0', 'ee82ee', 'f5deb3', 'ffffff', 'f5f5f5', 'ffff00', '9acd32'];
}
if (x === 'rgbs') {
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],
[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],
[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],
[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],
[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],
[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],
[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],
[240, 230, 140], [230, 230, 250], [255, 240, 245], [124, 252, 0], [255, 250, 205], [173, 216, 230], [240, 128, 128], [224, 255, 255],
[250, 250, 210], [211, 211, 211], [211, 211, 211], [144, 238, 144], [255, 182, 193], [255, 160, 122], [32, 178, 170], [135, 206, 250],
[119, 136, 153], [119, 136, 153], [176, 196, 222], [255, 255, 224], [0, 255, 0], [50, 205, 50], [250, 240, 230], [255, 0, 255],
[128, 0, 0], [102, 205, 170], [0, 0, 205], [186, 85, 211], [147, 112, 219], [60, 179, 113], [123, 104, 238], [0, 250, 154],
[72, 209, 204], [199, 21, 133], [25, 25, 112], [245, 255, 250], [255, 228, 225], [255, 228, 181], [255, 222, 173], [0, 0, 128],
[253, 245, 230], [128, 128, 0], [107, 142, 35], [255, 165, 0], [255, 69, 0], [218, 112, 214], [238, 232, 170], [152, 251, 152],
[175, 238, 238], [219, 112, 147], [255, 239, 213], [255, 218, 185], [205, 133, 63], [255, 192, 203], [221, 160, 221], [176, 224, 230],
[128, 0, 128], [102, 51, 153], [255, 0, 0], [188, 143, 143], [65, 105, 225], [139, 69, 19], [250, 128, 114], [244, 164, 96],
[46, 139, 87], [255, 245, 238], [160, 82, 45], [192, 192, 192], [135, 206, 235], [106, 90, 205], [112, 128, 144], [112, 128, 144],
[255, 250, 250], [0, 255, 127], [70, 130, 180], [210, 180, 140], [0, 128, 128], [216, 191, 216], [255, 99, 71], [64, 224, 208],
[238, 130, 238], [245, 222, 179], [255, 255, 255], [245, 245, 245], [255, 255, 0], [154, 205, 50]];
}
}
// I don't think this is needed anymore
function roundDecimals(c) {
c.r = Math.round(c.r);
c.g = Math.round(c.g);
c.b = Math.round(c.b);
return c;
}
function checkUnit() {
// eslint-disable-next-line no-undef
if (CSpeedsModel.isImperial) {
unit = 'mph';
} else {
unit = 'kmh';
}
log(unit);
if (getId('CStable')) {
getId('CStable').innerHTML = '';
getId('CSroadType').innerHTML = '';
LoadSettings();
getId('unitvalue').innerHTML = `(${unit})`;
}
}
function createToggler() {
// Layers switcher
// test with script toggler----------------
const oldTogglers = document.querySelectorAll('.togglers');
oldTogglers.forEach((elt, idx) => {
if (elt.id !== 'toolboxUl') {
if (oldTogglers[idx].querySelector('.layer-switcher-group_scripts') === null) {
const newScriptsToggler = document.createElement('li');
newScriptsToggler.className = 'group';
newScriptsToggler.innerHTML = '<div class="controls-container main toggler">\
<input class="layer-switcher-group_scripts toggle" id="layer-switcher-group_scripts" type="checkbox">\
<label for="layer-switcher-group_scripts">\
<span class="label-text">Scripts</span>\
</label>\
</div>\
<ul class="children">\
</ul>';
oldTogglers[idx].appendChild(newScriptsToggler);
}
const layerSwitcher = document.createElement('li');
layerSwitcher.innerHTML = '<div class="controls-container toggler">\
<input class="layer-switcher-item_WME_Color_Speeds toggle" id="layer-switcher-item_WME_Color_Speeds" type="checkbox">\
<label for="layer-switcher-item_WME_Color_Speeds">\
<span class="label-text">Color Speeds</span>\
</label>\
</div>';
let groupScripts = document.querySelector('.layer-switcher-group_scripts').parentNode.parentNode;
let newScriptsChildren = getElementsByClassName('children', groupScripts)[0];
newScriptsChildren.appendChild(layerSwitcher);
toggler = getId('layer-switcher-item_WME_Color_Speeds');
groupToggler = getId('layer-switcher-group_scripts');
groupToggler.checked = (typeof (localStorage.groupScriptsToggler) !== 'undefined'
? JSON.parse(localStorage.groupScriptsToggler) : true);
toggler.checked = WMECSpeeds.togglerChecked;
toggler.disabled = !groupToggler.checked;
toggler.addEventListener('click', e => {
mapLayer.setVisibility(e.target.checked);
saveOption();
});
groupToggler.addEventListener('click', e => {
toggler.disabled = !e.target.checked;
mapLayer.setVisibility(toggler.checked ? e.target.checked : toggler.checked);
localStorage.setItem('groupScriptsToggler', e.target.checked);
});
}
});
}
function changelogLocalizer() {
let changelog;
// eslint-disable-next-line no-undef
CSpeedI18n = I18n.locale;
// eslint-disable-next-line no-undef
if (CSpeedI18n === 'fr') {
changelog = changelogFrench;
} else {
changelog = changelogEnglish;
}
return changelog;
}
function getTopCountry() {
// eslint-disable-next-line no-undef
return CSpeedsModel.getTopCountry();
}
function getTopState() {
// eslint-disable-next-line no-undef
return CSpeedsModel.getTopState();
}
function saveOption() {
WMECSpeeds.togglerChecked = getId('layer-switcher-item_WME_Color_Speeds').checked;
localStorage.setItem('WMEColorSpeeds', JSON.stringify(WMECSpeeds));
}
function destroyTab() {
W.userscripts.removeSidebarTab('ColorSpeeds');
if (debug) log('Sidebar tab removed');
}
// *************
// ** INIT **
// *************
function counterStart() {
loadStartTime = performance.now();
bootstrap();
}
function bootstrap() {
scriptStartTime = performance.now();
// eslint-disable-next-line no-undef
if (WazeWrap?.Ready && W?.userscripts?.state.isReady) {
log('Starting');
init();
} else {
if (debug) log('WME and WW not ready');
setTimeout(bootstrap, 500);
}
}
function showScriptInfoAlert() {
WazeWrap.Interface.ShowScriptUpdate(
// eslint-disable-next-line camelcase
GM_info.script.name,
// eslint-disable-next-line camelcase
GM_info.script.version,
changelogLocalizer(),
greasyForkUrl,
forumUrl
);
}
function loadScriptUpdateMonitor() {
try {
const updateMonitor = new WazeWrap.Alerts.ScriptUpdateMonitor(scriptName, currentVersion, downloadUrl, GM_xmlhttpRequest);
if (debug) log('Checked for update');
updateMonitor.start();
} catch (ex) {
// Report the error, but not a critical failure.
console.error(scriptName, ex);
}
}
function init() {
loadScriptUpdateMonitor();
showScriptInfoAlert();
// Waze object needed
// eslint-disable-next-line no-undef
CSpeedsWaze = unsafeWindow.W;
if (typeof (CSpeedsWaze) === 'undefined') {
if (debug) { console.error('WME ColorSpeeds - CSpeedsWaze : NOK'); }
window.setTimeout(init, 500);
return;
}
// eslint-disable-next-line no-undef
CSpeedsMap = CSpeedsWaze.map;
if (typeof (CSpeedsMap) === 'undefined') {
if (debug) { console.error('WME ColorSpeeds - CSpeedsmap : NOK'); }
window.setTimeout(init, 500);
return;
}
// eslint-disable-next-line no-undef
CSpeedsModel = CSpeedsWaze.model;
if (typeof (CSpeedsModel) === 'undefined') {
if (debug) { console.error('WME ColorSpeeds - CSpeedsModel DOM : NOK'); }
window.setTimeout(init, 500);
return;
}
// eslint-disable-next-line no-undef
CSpeedsCountries = CSpeedsModel.countries;
if (typeof (CSpeedsCountries) === 'undefined') {
if (debug) { console.error('WME ColorSpeeds - CSpeedsCountries DOM : NOK'); }
window.setTimeout(init, 500);
return;
}
CSpeedsTopCountries = getTopCountry();
if (typeof (CSpeedsTopCountries) === 'undefined' || getTopCountry() === null) {
if (debug) { console.error('WME ColorSpeeds - CSpeedsCountries.top DOM : NOK'); }
window.setTimeout(init, 500);
return;
}
if (typeof (getTopCountry().attributes.name) === 'undefined') {
if (debug) { console.error('WME ColorSpeeds - CSpeedsCountries.top.name DOM : NOK'); }
window.setTimeout(init, 500);
return;
}
// OpenLayers
CSpeedOpenLayers = unsafeWindow.OpenLayers;
if (typeof (CSpeedOpenLayers) === 'undefined') {
if (debug) { console.error('WME ColorSpeeds - OpenLayers : NOK'); }
window.setTimeout(init, 500);
return;
}
// Traductions
CSpeedI18n = I18n.locale;
if (typeof(CSpeedI18n) === 'undefined') {
if (debug) { console.error('WME ColorSpeeds - CSpeedI18n : NOK'); }
setTimeout(init, 500);
return;
}
// Verify localStorage. Init if empty or not correct
if (typeof (localStorage.WMEColorSpeeds) !== 'undefined' && IsJsonString(localStorage.getItem('WMEColorSpeeds'))) {
WMECSpeeds = JSON.parse(localStorage.WMEColorSpeeds);
if (WMECSpeeds.speedColors.Others === undefined) WMECSpeeds.speedColors.Others = '#f00';
if (WMECSpeeds.speedColors.US === undefined) WMECSpeeds.speedColors.US = cloneObj(colorsUS);
if (WMECSpeeds.speedColors.Countries === undefined) WMECSpeeds.speedColors.Countries = {};
if (WMECSpeeds.multiplePalette === undefined) WMECSpeeds.multiplePalette = multiplePalette;
if (WMECSpeeds.PaletteByCountrie === undefined) WMECSpeeds.PaletteByCountrie = paletteByCountry;
if (WMECSpeeds.offsetValue === undefined) WMECSpeeds.offsetValue = offsetValue;
if (WMECSpeeds.opacityValue === undefined) WMECSpeeds.opacityValue = opacityValue;
if (WMECSpeeds.thicknessValue === undefined) WMECSpeeds.thicknessValue = thicknessValue;
for (const key in typeOfRoad) {
if (WMECSpeeds.typeOfRoad.hasOwnProperty(key) === false ) {
WMECSpeeds.typeOfRoad[key] = cloneObj(typeOfRoad[key]);
}
}
if (WMECSpeeds.togglerChecked === undefined) WMECSpeeds.togglerChecked = WMECSpeeds.visibility;
/* this if statement is no longer needed with WW
if (WMECSpeeds.version === undefined) {
oldScriptVersion = 0;
} else if (WMECSpeeds.version !== undefined) {
oldScriptVersion = WMECSpeeds.version;
}
*/
WMECSpeeds.MultiplePalette = (getTopCountry().attributes.name === 'United States') ? WMECSpeeds.MultiplePalette : false;
// WMECSpeeds.MultiplePalette = (CSpeedsCountries.top.name == "United States")? WMECSpeeds.MultiplePalette : false;
log('Init ok');
log('WMECSpeeds = ', WMECSpeeds);
} else {
localStorage.setItem('WMEColorSpeeds', JSON.stringify(WMECSpeeds));
setTimeout(init, 500);
return;
}
// ======================================================
// Translation
if (CSpeedI18n === 'fr') {
CSI18n = CSpeedI18n;
} else CSI18n = 'en';
// ======================================================
checkUnit();
// WME Layers check
let layers = CSpeedsMap.getLayersBy('uniqueName', 'WME_Color_Speeds');
if (layers.length === 0) {
I18n.translations[CSpeedI18n].layers.name['WME_Color_Speeds'] = 'Color Speeds';
const colorspeedsStyle = new CSpeedOpenLayers.Style({
pointRadius: 2,
fontWeight: 'normal',
label: '${labelText}',
fontFamily: 'Tahoma, Courier New',
labelOutlineColor: '#FFFFFF',
labelOutlineWidth: 2,
fontColor: '#000000',
fontSize: '10px'
});
mapLayer = new CSpeedOpenLayers.Layer.Vector(I18n.t('layers.name.WME_Color_Speeds'), {
displayInLayerSwitcher: true,
uniqueName: 'WME_Color_Speeds',
styleMap: new CSpeedOpenLayers.StyleMap(colorspeedsStyle)
});
CSpeedsMap.addUniqueLayer(mapLayer);
mapLayer.setVisibility(WMECSpeeds.visibility);
}
createToggler();
// MTE mode event
/*
W.app.modeController.model.bind('change:mode', function(){
if (W.app.modeController.getState() !== undefined){
eventUnRegister();
try { colorspeeds_mapLayer.destroyFeatures();
}catch(err){log('err destroyFeatures: ',err);}
}
if (W.app.modeController.getState() === undefined){
eventUnRegister();
createToggler();
CSpeeds_css();
}
});
*/
// reload after changing WME units
W.prefs.on('change:isImperial', () => {
destroyTab();
eventUnRegister();
checkUnit();
createToggler();
createCSS();
});
// log('colorspeeds_mapLayer ',colorspeeds_mapLayer);
// Then running
createCSS();
}
function createCSS() {
let CSpeedsCSS = getId('CSpeedsCSS');
if (CSpeedsCSS === null) {
CSpeedsCSS = document.createElement('style');
CSpeedsCSS.type = 'text/css';
CSpeedsCSS.id = 'CSpeedsCSS';
}
let css = '.CScontent {width:255px; margin-left:10px; box-shadow: 0 4px 10px #aaa;}';
css += '.divStateChoise {width:250px; margin-left:10px; color:#59899e; font-weight:bold; vertical-align: middle;}';
css += '.divHeadline {height:26px; font-weight:bold; padding-top:2px; border:2px solid #3d3d3d; background-color:#BEDCE5;}';
css += '.divContent {clear:both;height:26px; border:2px solid #3d3d3d; border-top:0;}';
css += '.divContentZoom { clear:both; height:26px; border:2px solid #3d3d3d; border-top:0;}';
css += '.divc {float:center; text-align:center;}';
css += '.divl {float:left; text-align:center;}';
css += '.divll {float:left; text-align:left;}';
css += '.divr {float:right; text-align:center;}';
css += '.speed {margin-top:2px; width:65px; height:20px; color:#59899e; font-weight:bold; vertical-align: middle;}';
css += '.divcolor { width:80px; height:17px; margin:4px 0 0 0; vertical-align: middle;}';
css += '.CStype {margin-top:2px; margin-left:10px; height:20px; color:#59899e; font-weight:bold; text-align:left; vertical-align: middle;}';
css += '.CScheckLabel {margin-top:5px; margin-left:10px; height:22px; color:#59899e; font-weight:bold; text-align:left; vertical-align: middle;}';
css += '.CScheck { float:left; width:22px; height:22px;}';
css += '.CSzoom {margin-top:2px; height:20px; color:#59899e; font-weight:bold; vertical-align: middle}';
css += '#newspeed {width:65px; height:26px; font-weight:bold;text-align:center;}';
css += '#editzoom { display:none;}';
css += '#newvalzoom {width:45px; height:24px; font-weight:bold;text-align:center;}';
css += '.CScontentConf {width:280px; margin-left:5px;}';
css += '.divContentConf {clear:both; line-height:24px; height:28px;}';
css += '.valColor {color:#59899e; font-weight:bold;}';
css += '#valRed {width:80px; height:28px; font-weight:bold; color:red;text-align:center;}';
css += '#valGreen {width:80px; height:28px; font-weight:bold; color:green;text-align:center;}';
css += '#valBlue {width:80px; height:28px; font-weight:bold; color:blue;text-align:center;}';
css += '#valOffset {width:80px; height:28px; font-weight:bold;text-align:center;}';
css += '#valOpacity {width:80px; height:28px; font-weight:bold;text-align:center;}';
css += '#valThickness {width:80px; height:28px; font-weight:bold;text-align:center;}';
css += '#ConfColor.dropdown-menu li:hover, #ConfColor+.dropdown-menu li:active, #ConfColor+.dropdown-menu li:focus { cursor: pointer; outline: #3B99FC dotted 1px; }';
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; }';
css += '#nameColor {width:120px; height:22px;}';
// css +="#ConfDash.dropdown-menu li:hover, #ConfDash+.dropdown-menu li:active, #ConfDash+.dropdown-menu li:focus { cursor: pointer; outline: #3B99FC dotted 1px; }";
// 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; }";
CSpeedsCSS.innerHTML = css;
document.body.appendChild(CSpeedsCSS);
createTab();
}
function createNewSpeedColorDialog() {
newspeedColorDialog = getId('newspeedColorDialog');
if (newspeedColorDialog === null) {
newspeedColorDialog = document.createElement('div');
newspeedColorDialog.id = 'newspeedColorDialog';
}
// newspeedColorDialog.style.fontSize = '90%';
newspeedColorDialog.style.display = 'none';
newspeedColorDialog.style.top = '10px';
// newspeedColorDialog.style.left = '15px';
newspeedColorDialog.style.width = '300px';
newspeedColorDialog.style.height = '500px';
newspeedColorDialog.style.margin = '10px 10px 10px 0px';
newspeedColorDialog.style.borderRadius = '10px';
newspeedColorDialog.style.border = '1px solid #BEDCE5';
newspeedColorDialog.style.position = 'relative';
newspeedColorDialog.style.padding = '5px';
newspeedColorDialog.style.overflow = 'auto';
newspeedColorDialog.style.background = 'rgba(255, 255, 255, 1)';
let content = "<div style='clear:both;'></div>";
content += `<div class='divc' style='width:200px; font-weight:bold;'>${CSlang[2][CSI18n]}</div>`;
content += "<div style='clear:both; padding-top:10px;'></div>";
// header table
content += "<div class='CScontentConf'>";
// Edit other color
content += "<div class='divContentConf' id='Conf_Others' style='display:none;'>";
content += `<div class='divll' style='width:70px;font-weight:bold;'>${CSlang[1][CSI18n]} </div>`;
content += `<div class='divll' style='width:60px;font-weight:bold;'>${CSlang[7][CSI18n]}</div>`;
content += "<div class='divl' style='width:45px;'> </div>";
content += "<div style='clear:both; padding-top:10px;'></div>";
content += `<div class='divll' style='width:70px;font-weight:bold;'>${CSlang[3][CSI18n]}: </div>`;
content += '</div>';
// Edit speed color
content += "<div class='divContentConf' id='Conf_Color' style='display:none;'>";
content += `<div class='divll' style='width:75px;font-weight:bold;'>${CSlang[1][CSI18n]} </div>`;
content += "<div class='divll speed' style='width:60px;'><input type='text' value='' id='newspeed'/></div>";
content += `<div class='divl' id='unitvalue' style='width:45px;font-size:11px;font-weight:bold;line-height:20px;'>(${unit})</div>`;
content += "<div style='clear:both; padding-top:10px;'></div>";
content += `<div class='divll' style='width:75px;font-weight:bold;'>${CSlang[3][CSI18n]} </div>`;
content += '</div>';
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;'>`;
for (let i = 0; colors[i]; ++i) {
let test = (colors[i].match(/\(/)) ? true : false;
switch (test) {
case true:
content += "<li style='background-color:rgb" + colors[i] + "'> </li>";
break;
case false:
content += "<li style='background-color:" + colors[i] + "'> </li>";
break;
}
}
content += '</ul></div>';
content += "<span class='divl valColor' id=nameColor></span>";
content += '</div>';
content += "<div style='clear:both; padding-top:10px;'></div>";
// Red Value
content += "<div class='CScontentConf'>";
content += "<div class='divContentConf'>";
content += `<div class='divll' style='width:60px;font-weight:bold; color:red;'>${CSlang[11][CSI18n]}</div>`;
content += "<div style='clear:both; padding-top:2px;'></div>";
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>";
content += "<div class='divr'><input id='sliderRed' type='range' max='255' min='0' style='width:180px;height:24px;'></div>";
content += '</div>';
// Green Value
content += "<div style='clear:both; padding-top:10px;'></div>";
content += "<div class='divContentConf'>";
content += `<div class='divll' style='width:60px;font-weight:bold; color:green;'>${CSlang[12][CSI18n]}</div>`;
content += "<div style='clear:both; padding-top:2px;'></div>";
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>";
content += "<div class='divr'><input id='sliderGreen' type='range' max='255' min='0' style='width:180px;height:24px;'></div>";
content += '</div>';
content += "<div style='clear:both; padding-top:10px;'></div>";
// Bleu Value
content += "<div class='divContentConf'>";
content += `<div class='divll' style='width:60px;font-weight:bold; color:blue;'>${CSlang[13][CSI18n]}</div>`;
content += "<div style='clear:both; padding-top:2px;'></div>";
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>";
content += "<div class='divr'><input id='sliderBlue' type='range' max='255' min='0' style='width:180px;height:24px;'></div>";
content += '</div>';
content += "<div style='clear:both; padding-top:10px;'></div>";
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>`;
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>`;
// content += "<div class='divc' style='width:270px; font-weight:bold;'><button id='OkButton'>Ok</button></div>";
content += '</div>';
newspeedColorDialog.innerHTML = content;
// document.body.appendChild(newspeedColorDialog);
// CSpeedshandleClass2.appendChild(newspeedColorDialog);
getId('tab-colorspeeds').appendChild(newspeedColorDialog);
}
// *************
// ** HTML **
// *************
async function createTab() {
const { tabLabel, tabPane } = W.userscripts.registerSidebarTab('ColorSpeeds');
if (debug) log('Starting tab creation');
const labelText = $('<div>').append(
$('<span>', {
id: 'cspeedstablabel',
class: 'fa fa-dashboard',
title: `${CSlang[32][CSI18n]}`
})
).html();
tabLabel.innerHTML = labelText;
// colorspeeds header
let content = `<div style='float:left; margin-left:5px;'><b><a href='https://greasyfork.org/scripts/14044-wme-color-speeds' target='_blank'><u>WME Color Speeds</u></a></b> v${currentVersion}</div>`;
content += "<div id='colorspeedsDiv'>";
// Countries pallete
content += "<div style='clear:both; padding-top:10px;'></div>";
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>`;
content += "<div style='clear:both; padding-top:10px;'></div>"; // Couleurs pour </div>";
content += "<select id='selectCountrie' style='height:22px; width:250px; active:none;'>";
Object.keys(WMECSpeeds.speedColors.Countries).forEach(countrie => {
content += `<option value='${countrie}'>${countrie.replace(/_/g, ' ')}</option>`;
});
content += '</select></div>';
// Mutiple pallete
content += "<div style='clear:both; padding-top:10px;'></div>";
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>`;
content += "<div style='clear:both; padding-top:20px;'></div>"; // Couleurs pour </div>";
content += "<select id='selectState' style='height:22px; active:none;'>";
Object.keys(WMECSpeeds.speedColors.US).forEach(state => {
content += `<option value='${state}'>${state.replace(/_/g, ' ')}</option>`;
});
content += '</select></div>';
// Speed table header
content += "<div style='clear: both; padding-top:10px;'></div><div class='CScontent'>";
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>`;
// Speed table
content += `<div class='divContent'><div class='divl speed' style='width:60px;'>${CSlang[7][CSI18n]}</div>`;
content += "<div class='divr' style='width:20px;'> </div>";
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>`;
content += `<div class='divr' style='width:120px;'><div id='color_others' class='divcolor' style='background-color:${WMECSpeeds.speedColors.Others};'> </div></div></div>`;
content += "<div id='CStable'></div></div><div id='divadd'></div>";
// Road type header
content += "<br><div style='clear:both; padding-top:10px;'></div><div class='CScontent'>";
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>`;
// edit zoom
content += "<div class='divContent' id='editzoom'><div class='divl speed' style='width:110px;'><span id='texttype'></span></div>";
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>`;
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>`;
content += "<div class='divr speed' style='width:60px;'><input type='text' value='' id='newvalzoom'/></div>";
content += '</div>';
content += "<div id='CSroadType'></div></div>";
// Offset Value
content += "<br><div style='clear:both; padding-top:10px;'></div>";
content += "<div class='divContentConf'>";
content += `<div class='divll' style='width:65px;font-weight:bold;color:#59899e;'>${CSlang[15][CSI18n]}</div>`;
content += "<div style='clear:both; padding-top:2px;'></div>";
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>";
content += "<div class='divr'><input id='sliderOffset' type='range' max='10' min='1' step='1' style='width:180px;height:24px;margin-right:20px;'></div>";
content += '</div>';
// Opacity Value
content += "<div style='clear:both; padding-top:10px;'></div>";
content += "<div class='divContentConf'>";
content += `<div class='divll' style='width:65px;font-weight:bold;color:#59899e;'>${CSlang[16][CSI18n]}</div>`;
content += "<div style='clear:both; padding-top:2px;'></div>";
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>";
content += "<div class='divr'><input id='sliderOpacity' type='range' max='100' min='20' step='1' style='width:180px;height:24px;margin-right:20px;'></div>";
content += '</div>';
// Thickness Value
content += "<div style='clear:both; padding-top:10px;'></div>";
content += "<div class='divContentConf'>";
content += `<div class='divll' style='width:65px;font-weight:bold;color:#59899e;'>${CSlang[17][CSI18n]}</div>`;
content += "<div style='clear:both; padding-top:2px;'></div>";
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>";
content += "<div class='divr'><input id='sliderThickness' type='range' max='10' min='2' step='1' style='width:180px;height:24px;margin-right:20px;'></div>";
content += '</div>';
/*
// 2023-09-26 SS28 I haven't taken the time to see what is wrong here. Maybe we can resurrect it
// Dash Style
content += "<div class='divContentConf'>";
content += "<div style='clear:both; padding-top:10px;'></div>";
content += "<div class='divll' style='width:140px;font-weight:bold;color:#59899e;'>Dash Style:</div>";
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;'>";
for (let i = 0; i <= dashStyles.length; ++i) {
content += `<li> ${dashStyles[i]} </li>`;
}
content += '</ul></div>';
content += '</div>';
*/
tabPane.innerHTML = content;
tabPane.id = 'tab-colorspeeds';
// Fix tab content div spacing.
// $(tabPane).parent().css({ width: 'auto', padding: '4px' });
await W.userscripts.waitForElementConnected(tabPane);
if (debug) log('Tab loaded');
createNewSpeedColorDialog();
getId('divadd').innerHTML += (`<br/><center><input type='button' id='addbutton' name='add' value='${CSlang[4][CSI18n]}' /></center>`);
getId('addbutton').onclick = (() => {
getId('Conf_Others').style.display = 'none';
getId('Conf_Color').style.display = 'block';
getId('colorspeedsDiv').style.display = 'none';
getId('newspeed').value = '';
getId('ConfColor').style.backgroundColor = '#fff';
newspeedColorDialog.style.display = 'block';
let c = getId('ConfColor').style.backgroundColor;
c = color2Rgb(c);
actualiseColorRGB(c);
});
if (debug) log(`Country = ${getTopCountry().attributes.name}`);
getId('cbPaletteByCountrie').checked = WMECSpeeds.PaletteByCountrie;
getId('selectCountrie').style.display = (WMECSpeeds.PaletteByCountrie) ? 'block' : 'none';
getId('stateChoise').style.display = (getTopCountry().attributes.name === 'United States') ? 'block' : 'none';
if (WMECSpeeds.MultiplePalette === true) {
let index = 0;
const stateToSelect = getTopState().attributes.name.replace(/ /g, '_');
for (index; getId('selectState').options[index].value !== stateToSelect; index++) { /* empty */ }
getId('selectState').options[index].selected = true;
}
getId('valOffset').value = WMECSpeeds.offsetValue;
getId('sliderOffset').value = WMECSpeeds.offsetValue;
getId('valOpacity').value = Number(WMECSpeeds.opacityValue * 100).toFixed(0);
getId('sliderOpacity').value = Number(WMECSpeeds.opacityValue * 100).toFixed(0);
getId('valThickness').value = WMECSpeeds.thicknessValue;
getId('sliderThickness').value = WMECSpeeds.thicknessValue;
LoadSettings();
eventRegister();
SCColor();
}
function eventRegister() {
CSpeedsWaze.selectionManager.events.register('selectionchanged', null, SCColor);
CSpeedsModel.actionManager.events.register('afterclearactions', null, SCColor);
CSpeedsModel.actionManager.events.register('afterundoaction', null, SCColor);
CSpeedsMap.olMap.events.register('zoomend', null, SCColor);
CSpeedsMap.olMap.events.register('moveend', null, SCColor);
CSpeedsModel.events.register('mergeend', null, SCColor);
window.addEventListener('beforeunload', saveOption, false);
}
function eventUnRegister() {
CSpeedsWaze.selectionManager.events.unregister('selectionchanged', null, SCColor);
CSpeedsModel.actionManager.events.unregister('afterclearactions', null, SCColor);
CSpeedsModel.actionManager.events.unregister('afterundoaction', null, SCColor);
CSpeedsMap.olMap.events.unregister('zoomend', null, SCColor);
CSpeedsMap.olMap.events.unregister('moveend', null, SCColor);
CSpeedsModel.events.unregister('mergeend', null, SCColor);
window.removeEventListener('beforeunload', saveOption, false);
}
function LoadSettings() {
getId('cbPaletteByCountrie').checked = WMECSpeeds.PaletteByCountrie;
getId('selectCountrie').style.display = (WMECSpeeds.PaletteByCountrie) ? 'block' : 'none';
getId('cbMultiplePalette').checked = WMECSpeeds.MultiplePalette;
getId('selectState').style.display = (WMECSpeeds.MultiplePalette) ? 'block' : 'none';
if (WMECSpeeds.MultiplePalette === false && WMECSpeeds.PaletteByCountrie === false) {
Object.keys(WMECSpeeds.speedColors[unit]).forEach(valSpeed => {
const color = WMECSpeeds.speedColors[unit][valSpeed];
const div = document.createElement('div');
div.className = 'divContent';
const divspeed = document.createElement('div');
divspeed.className = 'divl speed';
divspeed.style.width = '60px';
divspeed.innerHTML = valSpeed;
div.appendChild(divspeed);
const divsuppr = document.createElement('div');
divsuppr.className = 'divr';
divsuppr.style.width = '20px';
const divsuppra = document.createElement('a');
divsuppra.innerHTML = `<img style='width:20px;' title='${CSlang[5][CSI18n]}' src='data:image/png;base64,${iconDelete}' />`;
divsuppra.href = '#';
divsuppra.className = 'delSpeed';
divsuppra.id = `delSpeed_${valSpeed}`;
divsuppr.appendChild(divsuppra);
div.appendChild(divsuppr);
const divedit = document.createElement('div');
divedit.className = 'divr';
divedit.style.width = '20px';
const divedita = document.createElement('a');
divedita.innerHTML = `<img style='width:16px;' title='${CSlang[8][CSI18n]}' src='data:image/png;base64,${iconEdit}' />`;
divedita.href = '#';
divedita.onclick = getFunctionWithArgs(CSModifCouleur, [unit, valSpeed, color, null]);
divedit.appendChild(divedita);
div.appendChild(divedit);
const divcolor = document.createElement('div');
divcolor.className = 'divr';
divcolor.style.width = '120px';
divcolor.innerHTML = `<div class='divcolor' style='background-color:${color};'> </div>`;
div.appendChild(divcolor);
getId('CStable').appendChild(div);
});
// log("LoadSettings WMECSpeeds.speedColors."+unit+" = ",WMECSpeeds.speedColors[unit]);
}
if (WMECSpeeds.MultiplePalette === true && WMECSpeeds.PaletteByCountrie === false) {
selectedState = getId('selectState').options[getId('selectState').selectedIndex].value;
if (debug) log('selectedState = ', selectedState);
if (WMECSpeeds.speedColors.US[selectedState][unit] === undefined) {
WMECSpeeds.speedColors.US[selectedState][unit] = cloneObj(WMECSpeeds.speedColors[unit]);
}
Object.keys(WMECSpeeds.speedColors.US[selectedState][unit]).forEach(valSpeed => {
const color = WMECSpeeds.speedColors.US[selectedState][unit][valSpeed];
const div = document.createElement('div'); div.className = 'divContent';
const divspeed = document.createElement('div'); divspeed.className = 'divl speed'; divspeed.style.width = '60px'; divspeed.innerHTML = valSpeed;
div.appendChild(divspeed);
const divsuppr = document.createElement('div'); divsuppr.className = 'divr'; divsuppr.style.width = '20px';
const divsuppra = document.createElement('a');
divsuppra.innerHTML = `<img style='width:20px;' title='${CSlang[5][CSI18n]}' src='data:image/png;base64,${iconDelete}' />`;
divsuppra.href = '#'; divsuppra.className = 'delSpeed'; divsuppra.id = `delSpeed_${valSpeed}`;
divsuppr.appendChild(divsuppra);
div.appendChild(divsuppr);
const divedit = document.createElement('div'); divedit.className = 'divr'; divedit.style.width = '20px';
const divedita = document.createElement('a');
divedita.innerHTML = `<img style='width:16px;' title='${CSlang[8][CSI18n]}' src='data:image/png;base64,${iconEdit}' />`;
divedita.href = '#';
divedita.onclick = getFunctionWithArgs(CSModifCouleur, [unit, valSpeed, color, selectedState]);
divedit.appendChild(divedita);
div.appendChild(divedit);
const divcolor = document.createElement('div'); divcolor.className = 'divr'; divcolor.style.width = '120px';
divcolor.innerHTML = `<div class='divcolor' style='background-color:${color};'> </div>`;
div.appendChild(divcolor);
getId('CStable').appendChild(div);
});
if (debug) log(`LoadSettings WMECSpeeds.speedColors.US.${selectedState}.${unit} = `, WMECSpeeds.speedColors.US[selectedState][unit]);
}
if (WMECSpeeds.PaletteByCountrie === true && WMECSpeeds.MultiplePalette === false) {
if (getId('selectCountrie').options[getId('selectCountrie').selectedIndex] !== undefined) {
selectedCountry = getId('selectCountrie').options[getId('selectCountrie').selectedIndex].value;
} else selectedCountry = getTopCountry().attributes.name.replace(/ /g, '_');
log('selectCountrie = ', selectedCountry);
if (WMECSpeeds.speedColors.Countries[selectedCountry] === undefined || WMECSpeeds.speedColors.Countries[selectedCountry][unit] === undefined) {
WMECSpeeds.speedColors.Countries[selectedCountry] = {};
WMECSpeeds.speedColors.Countries[selectedCountry][unit] = cloneObj(WMECSpeeds.speedColors[unit]);
updateCountrieList();
// log("LoadSettings création WMECSpeeds.speedColors.Countries."+selectedCountrie+"."+unit+" = ",WMECSpeeds.speedColors.Countries[selectedCountrie][unit]);
}
Object.keys(WMECSpeeds.speedColors.Countries[selectedCountry][unit]).forEach(valSpeed => {
const color = WMECSpeeds.speedColors.Countries[selectedCountry][unit][valSpeed];
const div = document.createElement('div'); div.className = 'divContent';
const divspeed = document.createElement('div'); divspeed.className = 'divl speed'; divspeed.style.width = '60px'; divspeed.innerHTML = valSpeed;
div.appendChild(divspeed);
const divsuppr = document.createElement('div'); divsuppr.className = 'divr'; divsuppr.style.width = '20px';
const divsuppra = document.createElement('a');
divsuppra.innerHTML = `<img style='width:20px;' title='${CSlang[5][CSI18n]}' src='data:image/png;base64,${iconDelete}' />`;
divsuppra.href = '#'; divsuppra.className = 'delSpeed'; divsuppra.id = `delSpeed_${valSpeed}`;
divsuppr.appendChild(divsuppra);
div.appendChild(divsuppr);
const divedit = document.createElement('div'); divedit.className = 'divr'; divedit.style.width = '20px';
const divedita = document.createElement('a');
divedita.innerHTML = `<img style='width:16px;' title='${CSlang[8][CSI18n]}' src='data:image/png;base64,${iconEdit}' />`;
divedita.href = '#';
divedita.onclick = getFunctionWithArgs(CSModifCouleur, [unit, valSpeed, color, selectedCountry]);
divedit.appendChild(divedita);
div.appendChild(divedit);
const divcolor = document.createElement('div'); divcolor.className = 'divr'; divcolor.style.width = '120px';
divcolor.innerHTML = `<div class='divcolor' style='background-color:${color};'> </div>`;
div.appendChild(divcolor);
getId('CStable').appendChild(div);
});
// log("LoadSettings WMECSpeeds.speedColors.Countries."+selectedCountrie+"."+unit+" = ",WMECSpeeds.speedColors.Countries[selectedCountrie][unit]);
}
for (let i = 0; i < RoadToScan.length; ++i) {
const type = RoadToScan[i];
const div = document.createElement('div'); div.className = 'divContentZoom';
const divcheck = document.createElement('div'); divcheck.className = 'divl';
divcheck.innerHTML = `<input type="checkbox" style="margin:1px 1px;" class="CScheck" id="cbRoad${type}">`;
div.appendChild(divcheck);
const divtype = document.createElement('div');
divtype.className = 'divl CStype';
divtype.style.width = '130px';
const divedit = document.createElement('div');
divedit.className = 'divr';
divedit.style.width = '20px';
const divedita = document.createElement('a');
divedita.innerHTML = `<img style='width:16px;' title='${CSlang[8][CSI18n]}' src='data:image/png;base64,${iconEdit}' />`;
divedita.href = '#';
divedita.className = 'modifyZoom';
divedita.id = `zoom_${type}`;
divedit.appendChild(divedita);
const divzoom = document.createElement('div');
divzoom.className = 'divr CSzoom';
divzoom.style.width = '60px';
divzoom.innerHTML = WMECSpeeds.typeOfRoad[type].zoom;
divzoom.title = `${roadTypeZoomInfo[type][CSI18n]}`;
if (type === 3) {
divtype.innerHTML = CSlang[22][CSI18n];
div.appendChild(divtype);
div.appendChild(divedit);
div.appendChild(divzoom);
} else if (type === 6) {
divtype.innerHTML = CSlang[23][CSI18n];
div.appendChild(divtype);
div.appendChild(divedit);
div.appendChild(divzoom);
} else if (type === 7) {
divtype.innerHTML = CSlang[24][CSI18n];
div.appendChild(divtype);
div.appendChild(divedit);
div.appendChild(divzoom);
} else if (type === 4) {
divtype.innerHTML = CSlang[25][CSI18n];
div.appendChild(divtype);
div.appendChild(divedit);
div.appendChild(divzoom);
} else if (type === 2) {
divtype.innerHTML = CSlang[26][CSI18n];
div.appendChild(divtype);
div.appendChild(divedit);
div.appendChild(divzoom);
} else if (type === 1) {
divtype.innerHTML = CSlang[27][CSI18n];
div.appendChild(divtype);
div.appendChild(divedit);
div.appendChild(divzoom);
} else if (type === 22) {
divtype.innerHTML = CSlang[28][CSI18n];
div.appendChild(divtype);
div.appendChild(divedit);
div.appendChild(divzoom);
} else if (type === 20) {
divtype.innerHTML = CSlang[29][CSI18n];
div.appendChild(divtype);
div.appendChild(divedit);
div.appendChild(divzoom);
} else if (type === 17) {
divtype.innerHTML = CSlang[30][CSI18n];
div.appendChild(divtype);
div.appendChild(divedit);
div.appendChild(divzoom);
} else if (type === 8) {
divtype.innerHTML = CSlang[31][CSI18n];
div.appendChild(divtype);
div.appendChild(divedit);
div.appendChild(divzoom);
} else if (type === 999) {
divtype.innerHTML = CSlang[18][CSI18n];
div.appendChild(divtype);
}
getId('CSroadType').appendChild(div);
getId(`cbRoad${type}`).checked = WMECSpeeds.typeOfRoad[type].checked;
// getId(`cbRoad${type}`).style.marginLeft = '2px';
// getId(`cbRoad${type}`).style.marginTop = '2px';
// getId(`cbRoad${type}`).style.width = '15px';
// getId(`cbRoad${type}`).style.height = '15px';
getId(`cbRoad${type}`).onclick = (() => {
SCColor();
});
}
if (debug) log('Settings Loaded');
setupHandler();
}
function setupHandler() {
let rgb = {
r: 0, g: 0, b: 0, name: null
};
const listeDelSpeed = getId('CStable');
const btnDelSpeed = getElementsByClassName('delSpeed', listeDelSpeed);
for (let i = 0; i < btnDelSpeed.length; i++) {
const target = btnDelSpeed[i];
const index = target.id.split('_')[1];
target.onclick = getFunctionWithArgs(SCSpeeds, [unit, index, selectedState, selectedCountry]);
}
const listeEditZoom = getId('CSroadType');
const btnEditZoom = getElementsByClassName('modifyZoom', listeEditZoom);
for (let i = 0; i < btnEditZoom.length; i++) {
const target = btnEditZoom[i];
const index = target.id.split('_')[1];
const val = WMECSpeeds.typeOfRoad[parseInt(index, 10)].zoom;
target.onclick = getFunctionWithArgs(SCEditZoom, [index, val]);
}
getId('cbPaletteByCountrie').onclick = (() => {
getId('selectCountrie').style.display = (getId('cbPaletteByCountrie').checked) ? 'block' : 'none';
WMECSpeeds.PaletteByCountrie = getId('cbPaletteByCountrie').checked;
WMECSpeeds.MultiplePalette = false;
updateCountrieList();
getId('CStable').innerHTML = '';
getId('CSroadType').innerHTML = '';
LoadSettings();
SCColor();
});
getId('selectCountrie').onclick = (() => {
updateCountrieList();
getId('CStable').innerHTML = '';
getId('CSroadType').innerHTML = '';
LoadSettings();
});
getId('cbMultiplePalette').onclick = (() => {
getId('selectState').style.display = (getId('cbMultiplePalette').checked) ? 'block' : 'none';
WMECSpeeds.MultiplePalette = getId('cbMultiplePalette').checked;
WMECSpeeds.PaletteByCountrie = false;
if (WMECSpeeds.MultiplePalette === true) {
const stateToSelect = getTopState().attributes.name.replace(/ /g, '_');
let index;
for (index = 0; getId('selectState').options[index].value !== stateToSelect; index++) { /* empty */ }
getId('selectState').options[index].selected = true;
}
getId('CStable').innerHTML = '';
getId('CSroadType').innerHTML = '';
LoadSettings();
SCColor();
});
getId('selectState').onclick = (() => {
getId('CStable').innerHTML = '';
getId('CSroadType').innerHTML = '';
LoadSettings();
});
getId('edit_others').onclick = (() => {
getId('Conf_Others').style.display = 'block';
getId('Conf_Color').style.display = 'none';
getId('colorspeedsDiv').style.display = 'none';
getId('newspeed').value = null;
getId('ConfColor').style.backgroundColor = WMECSpeeds.speedColors.Others;
getId('newspeedColorDialog').style.display = 'block';
rgb = color2Rgb(WMECSpeeds.speedColors.Others);
actualiseColorRGB(rgb);
});
getId('cancel').onclick = (() => {
getId('Conf_Others').style.display = 'none';
getId('Conf_Color').style.display = 'none';
getId('newspeedColorDialog').style.display = 'none';
getId('colorspeedsDiv').style.display = 'block';
getId('newspeed').value = '';
});
getId('submit').onclick = (() => {
let newSpeed = getId('newspeed').value;
let newColor = getId('ConfColor').style.backgroundColor;
// log("newSpeed = ", newSpeed);log("newColor = ", newColor);
if (getId('Conf_Color').style.display === 'block' && newSpeed && newColor) {
if (WMECSpeeds.MultiplePalette === true) {
WMECSpeeds.speedColors.US[selectedState][unit][newSpeed] = newColor;
} else if (WMECSpeeds.PaletteByCountrie === true) {
WMECSpeeds.speedColors.Countries[selectedCountry][unit][newSpeed] = newColor;
} else if (WMECSpeeds.MultiplePalette === false && WMECSpeeds.PaletteByCountrie === false) {
WMECSpeeds.speedColors[unit][newSpeed] = newColor;
}
}
if (getId('Conf_Others').style.display === 'block' && newColor) {
WMECSpeeds.speedColors.Others = newColor;
getId('color_others').style.backgroundColor = WMECSpeeds.speedColors.Others;
}
getId('newspeed').value = '';
newSpeed = null;
newColor = null;
getId('CStable').innerHTML = '';
getId('CSroadType').innerHTML = '';
getId('Conf_Others').style.display = 'none';
getId('Conf_Color').style.display = 'none';
getId('newspeedColorDialog').style.display = 'none';
getId('colorspeedsDiv').style.display = 'block';
LoadSettings();
SCColor();
});
$('#ConfColor.dropdown-toggle').dropdown();
$('#ConfColor+.dropdown-menu li').click(function() {
getId('ConfColor').style.backgroundColor = this.style.backgroundColor;
rgb = color2Rgb(this.style.backgroundColor);
actualiseColorRGB(rgb);
});
/*
$("#ConfDash.dropdown-toggle").dropdown();
$('#ConfDash+.dropdown-menu li').click(function(){
getId('ConfDash').text=this.text;
});
*/
getId('sliderRed').onmousemove = () => {
getId('valRed').value = getId('sliderRed').value;
rgb.r = getId('valRed').value;
rgb.g = getId('valGreen').value;
rgb.b = getId('valBlue').value;
rgb = color2Rgb(Rgb2String(rgb));
actualiseColorRGB(rgb);
};
getId('sliderGreen').onmousemove = () => {
getId('valGreen').value = getId('sliderGreen').value;
rgb.r = getId('valRed').value;
rgb.g = getId('valGreen').value;
rgb.b = getId('valBlue').value;
rgb = color2Rgb(Rgb2String(rgb));
actualiseColorRGB(rgb);
};
getId('sliderBlue').onmousemove = () => {
getId('valBlue').value = getId('sliderBlue').value;
rgb.r = getId('valRed').value;
rgb.g = getId('valGreen').value;
rgb.b = getId('valBlue').value;
rgb = color2Rgb(Rgb2String(rgb));
actualiseColorRGB(rgb);
};
getId('sliderOffset').onmousemove = () => {
WMECSpeeds.offsetValue = getId('sliderOffset').value;
getId('valOffset').value = getId('sliderOffset').value;
SCColor();
};
getId('sliderOpacity').onmousemove = () => {
WMECSpeeds.opacityValue = Number(getId('sliderOpacity').value / 100).toFixed(2);
getId('valOpacity').value = getId('sliderOpacity').value;
SCColor();
};
getId('sliderThickness').onmousemove = () => {
WMECSpeeds.thicknessValue = getId('sliderThickness').value;
getId('valThickness').value = getId('sliderThickness').value;
SCColor();
};
getId('valRed').onchange = () => {
const R = parseInt(getId('valRed').value, 10);
if ((R >= 0) && (R <= 255)) {
getId('sliderRed').value = getId('valRed').value;
rgb.r = getId('valRed').value;
rgb.g = getId('valGreen').value;
rgb.b = getId('valBlue').value;
rgb = color2Rgb(Rgb2String(rgb));
actualiseColorRGB(rgb);
} else {
getId('valRed').value = getId('sliderRed').value;
}
};
getId('valGreen').onchange = () => {
const G = parseInt(getId('valGreen').value, 10);
if ((G >= 0) && (G <= 255)) {
getId('sliderGreen').value = getId('valGreen').value;
rgb.r = getId('valRed').value;
rgb.g = getId('valGreen').value;
rgb.b = getId('valBlue').value;
rgb = color2Rgb(Rgb2String(rgb));
actualiseColorRGB(rgb);
} else {
getId('valGreen').value = getId('sliderGreen').value;
}
};
getId('valBlue').onchange = () => {
const B = parseInt(getId('valBlue').value, 10);
if ((B >= 0) && (B <= 255)) {
getId('sliderBlue').value = getId('valBlue').value;
rgb.r = getId('valRed').value;
rgb.g = getId('valGreen').value;
rgb.b = getId('valBlue').value;
rgb = color2Rgb(Rgb2String(rgb));
actualiseColorRGB(rgb);
} else {
getId('valBlue').value = getId('sliderBlue').value;
}
};
getId('valOffset').onchange = () => {
const R = parseInt(getId('valOffset').value, 10);
if ((R >= 1) && (R <= 10)) {
getId('sliderOffset').value = getId('valOffset').value;
WMECSpeeds.offsetValue = getId('valOffset').value;
SCColor();
} else {
getId('valOffset').value = getId('sliderOffset').value;
}
};
getId('valOpacity').onchange = () => {
const R = parseInt(getId('valOpacity').value, 10);
if ((R >= 0) && (R <= 100)) {
getId('sliderOpacity').value = getId('valOpacity').value;
WMECSpeeds.opacityValue = Number(getId('valOpacity').value / 100).toFixed(2);
SCColor();
} else {
getId('valOpacity').value = getId('sliderOpacity').value;
}
};
getId('valThickness').onchange = () => {
const R = parseInt(getId('valThickness').value, 10);
if ((R >= 2) && (R <= 10)) {
getId('sliderThickness').value = getId('valThickness').value;
WMECSpeeds.thicknessValue = getId('valThickness').value;
SCColor();
} else {
getId('valThickness').value = getId('sliderThickness').value;
}
};
}
function updateCountrieList() {
const selectCountrie = getId('selectCountrie');
let current = null;
if (selectCountrie.selectedIndex >= 0) current = selectCountrie.options[selectCountrie.selectedIndex].value;
if (current === null) current = getTopCountry().attributes.name.replace(/ /g, '_');
selectCountrie.options.length = 0;
for (var countrie in WMECSpeeds.speedColors.Countries) {
// create option in select menu
if (countrie === undefined) countrie = getTopCountry().attributes.name.replace(/ /g, '_');
var countrieOption = document.createElement('option');
var countrieText = document.createTextNode(countrie.replace(/_/g, ' '));
if (current !== null && countrie == current)
countrieOption.setAttribute('selected', true);
countrieOption.setAttribute('value', countrie);
countrieOption.appendChild(countrieText);
selectCountrie.appendChild(countrieOption);
}
}
function CSModifCouleur(unit, id, color, state) {
getId('Conf_Others').style.display = 'none';
getId('Conf_Color').style.display = 'block';
getId('colorspeedsDiv').style.display = 'none';
getId('newspeed').value = id;
getId('ConfColor').style.backgroundColor = color;
newspeedColorDialog.style.display = 'block';
const c = color2Rgb(color);
actualiseColorRGB(c);
}
function actualiseColorRGB(c) {
log('color: ', c);
getId('valRed').value = c.r;
getId('valGreen').value = c.g;
getId('valBlue').value = c.b;
getId('sliderRed').value = c.r;
getId('sliderGreen').value = c.g;
getId('sliderBlue').value = c.b;
getId('ConfColor').style.backgroundColor = Rgb2String(c);
getId('nameColor').innerHTML = c.name;
}
function SCSpeeds(unit, idx, state, contrie){
if (WMECSpeeds.MultiplePalette === true){
var answer = window.confirm(CSlang[5][CSI18n] + ' ' + idx + ' ' + unit + ' ' + CSlang[21][CSI18n] + ' ' + state + ' ?');
}else if (WMECSpeeds.PaletteByCountrie === true){
var answer = window.confirm(CSlang[5][CSI18n] + ' ' + idx + ' ' + unit + ' ' + CSlang[21][CSI18n] + ' ' + contrie + ' ?');
}else{var answer = window.confirm(CSlang[5][CSI18n] + ' ' + idx + ' ' + unit + ' ?');}
if (answer){
if (WMECSpeeds.MultiplePalette === true){
delete WMECSpeeds.speedColors.US[state][unit][idx];
}else if (WMECSpeeds.PaletteByCountrie === true){
delete WMECSpeeds.speedColors.Countries[contrie][unit][idx];
}else {delete WMECSpeeds.speedColors[unit][idx];}
getId('CStable').innerHTML = '';
getId('CSroadType').innerHTML = '';
LoadSettings();
}
}
function SCEditZoom(idx, val){
getId('editzoom').style.display = 'block';
getId('newvalzoom').value = val;
getId('texttype').textContent = WMECSpeeds.typeOfRoad[idx].name;
getId('submitZoom').onclick = (function(){
var newValZoom = getId('newvalzoom').value;
if (newValZoom) {
WMECSpeeds.typeOfRoad[idx].zoom = newValZoom;
}
getId('editzoom').style.display = 'none';
getId('newvalzoom').value = '';
getId('CStable').innerHTML = '';
getId('CSroadType').innerHTML = '';
LoadSettings();
});
getId('cancelZoom').onclick = (function(){
getId('editzoom').style.display = 'none';
getId('newvalzoom').value = '';
getId('CStable').innerHTML = '';
getId('CSroadType').innerHTML = '';
LoadSettings();
});
}
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
{
if (!trigo)
d = -d;
function getOrthoVector(p1, p2)
{
return [p1.y - p2.y, p2.x - p1.x];
}
function normalizeVector(v)
{
if (v[0] * v[0] + v[1] * v[1] == 0)
return v;
var l = Math.sqrt(v[0] * v[0] + v[1] * v[1]);
return [v[0] / l, v[1] / l];
}
var points = [];
for (var i = 0; i < line.length; i++)
{
var vcount = 0;
// compute orthogonal vectors:
var prevVector = [0, 0];
var nextVector = [0, 0];
if (i > 0) // can compute prev
{
var p1 = line[i - 1];
var p2 = line[i];
prevVector = getOrthoVector(p1, p2);
prevVector = normalizeVector(prevVector);
vcount++;
}
if (i < line.length - 1) // can compute next
{
var p1 = line[i];
var p2 = line[i + 1];
nextVector = getOrthoVector(p1, p2);
nextVector = normalizeVector(nextVector);
vcount++;
}
// sum vectors and normalize
var v = [0, 0];
if (vcount != 0)
v = [(prevVector[0] + nextVector[0]) / vcount, (prevVector[1] + nextVector[1]) / vcount];
//v=normalizeVector(v);
points.push(new CSpeedOpenLayers.Geometry.Point(line[i].x + v[0] * d, line[i].y + v[1] * d));
}
return points;
}
function SCColor() {
function getByID(obj, id){
if (typeof(obj.getObjectById) == 'function'){
return obj.getObjectById(id);
}else if (typeof(obj.getObjectById) == 'undefined'){
return obj.get(id);
}
}
//log('SCColor');
try { mapLayer.destroyFeatures();
}catch(err){log('err destroyFeatures: ', err);}
if (getTopCountry() === null) return;
if ( CSpeedsCountries !== undefined && /*CSpeedsCountries.top*/getTopCountry() !== undefined){
getId('stateChoise').style.display = (/*CSpeedsCountries.top*/getTopCountry().attributes.name == 'United States') ? 'block' : 'none';
}
var lineFeature = [];
for (var i = 0; i < RoadToScan.length; ++i){
var type = RoadToScan[i];
WMECSpeeds.typeOfRoad[type].checked = getId('cbRoad' + type).checked;
}
for (var seg in CSpeedsModel.segments.objects) {
var segment = getByID(CSpeedsModel.segments, seg);
var attributes = segment.attributes;
var roadType = attributes.roadType;
var roundabout = (attributes.junctionID === null) ? false : true;
var line = getId(segment.getOLGeometry().id);
var fwdspeed = attributes.fwdMaxSpeed;
var revspeed = attributes.revMaxSpeed;
var fwdspeedUnverified = attributes.fwdMaxSpeedUnverified;
var revspeedUnverified = attributes.revMaxSpeedUnverified;
var fwddir = attributes.fwdDirection;
var revdir = attributes.revDirection;
//var fwdID = "",revID="";
var isSelected = (segment.selected == true) ? true : false;
var isModified = (segment.state == 'Update') ? true : false;
if (attributes.primaryStreetID === null || attributes.primaryStreetID === undefined) continue;
if (getByID(CSpeedsModel.streets, attributes.primaryStreetID) === null || getByID(CSpeedsModel.streets, attributes.primaryStreetID) === undefined){
if (debug) log('CSpeedsModel.streets.get(' + attributes.primaryStreetID + ') =', getByID(CSpeedsModel.streets, attributes.primaryStreetID));
continue;
}
var cid = getByID(CSpeedsModel.streets, attributes.primaryStreetID).attributes.cityID;
var stateID = null;
var countryID = null;
if (getByID(CSpeedsModel.cities, cid) === null || getByID(CSpeedsModel.cities, cid) === undefined){
if (debug) log('CSpeedsModel.cities.get(' + cid + ') =', getByID(CSpeedsModel.cities, cid));
continue;
}
stateID = getByID(CSpeedsModel.cities, cid).attributes.stateID;
countryID = getByID(CSpeedsModel.cities, cid).attributes.countryID;
var state = getByID(CSpeedsModel.states, stateID).attributes.name.replace(/ /g, '_');
var countrie = getByID(CSpeedsModel.countries, countryID).attributes.name.replace(/ /g, '_');
if (WMECSpeeds.PaletteByCountrie == true && WMECSpeeds.speedColors.Countries[countrie] === undefined){
WMECSpeeds.speedColors.Countries[countrie] = {};
WMECSpeeds.speedColors.Countries[countrie][unit] = cloneObj(WMECSpeeds.speedColors[unit]);
updateCountrieList();
LoadSettings();
log('SCColor WMECSpeeds.speedColors.Countries.' + countrie + '.' + unit + ' = ', WMECSpeeds.speedColors.Countries[countrie][unit]);
}
if (WMECSpeeds.MultiplePalette == true && WMECSpeeds.speedColors.US[state] !== undefined && WMECSpeeds.speedColors.US[state][unit] === undefined){
WMECSpeeds.speedColors.US[state][unit] = cloneObj(WMECSpeeds.speedColors[unit]);
//log("SCColor WMECSpeeds.speedColors.US."+state+"."+unit+" = ",WMECSpeeds.speedColors.US[state][unit]);
}
// check that WME hasn't highlighted this segment
if (isSelected || isModified) continue;
if (zoom != CSpeedsMap.olMap.zoom) {
zoom = CSpeedsMap.olMap.zoom;
//log('zoom = ' + zoom + 'W.map.getResolution() = '+W.map.getResolution());
}
var shiftValue = WMECSpeeds.offsetValue * W.map.getResolution();
if (RoadToScan.indexOf(roadType) == -1 ) continue;
if ((roundabout != false) && (WMECSpeeds.typeOfRoad['999'].checked == false)) continue;
if (unit == 'mph'){
fwdspeed = (fwdspeed != null) ? (Math.trunc(fwdspeed * 0.625)) : null;
revspeed = (revspeed != null) ? (Math.trunc(revspeed * 0.625)) : null;
}
//log("fwdspeed= "+ fwdspeed + " " + unit + " ; revspeed= " + revspeed + " " + unit);
// turn off highlights when roads are no longer visible
if ((zoom < WMECSpeeds.typeOfRoad[roadType].zoom) || !WMECSpeeds.typeOfRoad[roadType].checked) {
continue;
}
WMECSpeeds.visibility = mapLayer.visibility;
if (fwdspeed && WMECSpeeds.visibility) {
//Color for forward speed
var newWidth = '', newColor = '', newDashes = '', newOpacity = '';
if (WMECSpeeds.MultiplePalette === false && WMECSpeeds.PaletteByCountrie === false){
if (WMECSpeeds.speedColors[unit].hasOwnProperty(fwdspeed)) newColor = WMECSpeeds.speedColors[unit][fwdspeed];
}else if (WMECSpeeds.PaletteByCountrie === true){
if (WMECSpeeds.speedColors.Countries[countrie][unit].hasOwnProperty(fwdspeed)) newColor = WMECSpeeds.speedColors.Countries[countrie][unit][fwdspeed];
}else if (WMECSpeeds.MultiplePalette === true && WMECSpeeds.speedColors.US[state] !== undefined){
if (WMECSpeeds.speedColors.US[state][unit].hasOwnProperty(fwdspeed)) newColor = WMECSpeeds.speedColors.US[state][unit][fwdspeed];
}
/*
if (newColor!=""){
//Dashes
if (fwddir==true && fwdspeed && !fwdspeedUnverified) { newWidth = 6; newOpacity = 0.8; newDashes = "5 10"; } // verified speed
else if (fwddir==true && fwdspeed && fwdspeedUnverified) { newColor = WMECSpeeds.speedColors.Others; newWidth = 4; newOpacity = 0.8; newDashes = "2 10";} // unverified speed
}else if (fwddir==true && fwdspeed) { newWidth = 4; newColor = WMECSpeeds.speedColors.Others; newOpacity = 0.9; newDashes = "5 5"; } // other
*/
if (newColor != ''){
//Dashes
if (fwddir == true && fwdspeed && !fwdspeedUnverified) { newWidth = WMECSpeeds.thicknessValue; newOpacity = WMECSpeeds.opacityValue; newDashes = '5 10'; } // verified speed
else if (fwddir == true && fwdspeed && fwdspeedUnverified) { newColor = WMECSpeeds.speedColors.Others; newWidth = WMECSpeeds.thicknessValue; newOpacity = 0.8; newDashes = '2 10';} // unverified speed
}else if (fwddir == true && fwdspeed) { newWidth = WMECSpeeds.thicknessValue; newColor = WMECSpeeds.speedColors.Others; newOpacity = WMECSpeeds.opacityValue; newDashes = '5 5'; } // other
if (newColor != ''){
var style = {
strokeColor: newColor,
strokeOpacity: newOpacity,
strokeWidth: newWidth,
strokeDashstyle: newDashes
};
var points = [];
var segID = attributes.id;
points = shiftGeometry(shiftValue, segment.getOLGeometry().getVertices(), CSpeedsModel.getTopCountry().getAttribute('leftHandTraffic'));
var newline = new CSpeedOpenLayers.Geometry.LineString(points);
lineFeature.push(new CSpeedOpenLayers.Feature.Vector(newline, null, style));
//log("segment id: " + attributes.id + ' newColor: '+ newColor + ' segment.CSpeedsFwd.fwdColor: ' + segment.CSpeedsFwd.fwdColor + ' lineFeature: ',lineFeature);
}
}
if (revspeed && WMECSpeeds.visibility) {
//Color for reverse speed
var newWidth = '', newColor = '', newDashes = '', newOpacity = '', newDashOffset = '';
if (WMECSpeeds.MultiplePalette === false && WMECSpeeds.PaletteByCountrie === false){
if (WMECSpeeds.speedColors[unit].hasOwnProperty(revspeed)) newColor = WMECSpeeds.speedColors[unit][revspeed];
}else if (WMECSpeeds.PaletteByCountrie === true){
if (WMECSpeeds.speedColors.Countries[countrie][unit].hasOwnProperty(revspeed)) newColor = WMECSpeeds.speedColors.Countries[countrie][unit][revspeed];
}else if (WMECSpeeds.MultiplePalette === true && WMECSpeeds.speedColors.US[state] !== undefined){
if (WMECSpeeds.speedColors.US[state][unit].hasOwnProperty(revspeed)) newColor = WMECSpeeds.speedColors.US[state][unit][revspeed];
}
/*
if (newColor!=""){
//Dashes
if (revdir==true && revspeed && !revspeedUnverified) { newWidth = 6; newOpacity = 0.8; newDashes = "5 10"; } // verified speed
else if (revdir==true && revspeed && revspeedUnverified) { newColor = WMECSpeeds.speedColors.Others; newWidth = 4; newOpacity = 0.8; newDashes = "2 10";} // unverified speed
}else if (revdir==true && revspeed) { newWidth = 4; newColor = WMECSpeeds.speedColors.Others; newOpacity = 0.9; newDashes = "5 5"; } // other
*/
if (newColor != ''){
//Dashes
if (revdir == true && revspeed && !revspeedUnverified) { newWidth = WMECSpeeds.thicknessValue; newOpacity = WMECSpeeds.opacityValue; newDashes = '5 10'; } // verified speed
else if (revdir == true && revspeed && revspeedUnverified) { newColor = WMECSpeeds.speedColors.Others; newWidth = WMECSpeeds.thicknessValue; newOpacity = WMECSpeeds.opacityValue; newDashes = '2 10';} // unverified speed
}else if (revdir == true && revspeed) { newWidth = WMECSpeeds.thicknessValue; newColor = WMECSpeeds.speedColors.Others; newOpacity = WMECSpeeds.opacityValue; newDashes = '5 5'; } // other
if (newColor != ''){
var style = {
strokeColor: newColor,
strokeOpacity: newOpacity,
strokeWidth: newWidth,
strokeDashstyle: newDashes,
};
var points = [];
var segID = attributes.id;
points = shiftGeometry(shiftValue, segment.getOLGeometry().getVertices(), !CSpeedsModel.getTopCountry().getAttribute('leftHandTraffic'));
var newline = new CSpeedOpenLayers.Geometry.LineString(points);
lineFeature.push(new CSpeedOpenLayers.Feature.Vector(newline, null, style));
}
}
}
// log("lineFeature = ",lineFeature);
// Display new array of segments
try {
mapLayer.addFeatures(lineFeature);
} catch (err) { log('err addFeatures: ', err); }
if (debug) log(`Total load time without WW of ${Math.round(performance.now() - scriptStartTime)} ms.`);
if (debug) log(`Total load time with WW of ${Math.round(performance.now() - loadStartTime)} ms.`);
}
/* begin running the code! */
counterStart();