您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds shield information display to WME
"use strict"; // ==UserScript== // @name WME Road Shield Assistant // @namespace https://greasyfork.org/en/users/286957-skidooguy // @version 2025.06.19.001 // @description Adds shield information display to WME // @author SkiDooGuy, jm6087, Karlsosha // @match https://www.waze.com/editor* // @match https://www.waze.com/*/editor* // @match https://beta.waze.com/editor* // @match https://beta.waze.com/*/editor* // @exclude https://www.waze.com/user/editor* // @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js // @require https://cdn.jsdelivr.net/npm/@turf/[email protected]/turf.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/proj4.min.js // @grant GM_xmlhttpRequest // @grant unsafeWindow // @connect greasyfork.org // @contributionURL https://github.com/WazeDev/Thank-The-Authors // ==/UserScript== /* global W */ /* global WazeWrap */ // import type { Node, Segment, SegmentAddress, Street, Turn, WmeSDK } from "wme-sdk-typings"; // import type { Point, LineString, Position, Feature } from "geojson"; // import * as turf from "@turf/turf"; // import _ from "underscore"; // import proj4 from "proj4"; // import WazeWrap from "https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js"; let sdk; unsafeWindow.SDK_INITIALIZED.then(() => { if (!unsafeWindow.getWmeSdk) { throw new Error("SDK is not installed"); } sdk = unsafeWindow.getWmeSdk({ scriptId: "wme-road-shield-assistant", scriptName: "WME Road Shield Assistant" }); console.log(`SDK v ${sdk.getSDKVersion()} on ${sdk.getWMEVersion()} initialized`); sdk.Events.once({ eventName: "wme-ready" }).then(rsaInit); }); function rsaInit() { if (!WazeWrap.Ready) { setTimeout(() => { rsaInit(); }, 100); return; } const GF_LINK = "https://greasyfork.org/en/scripts/425050-wme-road-shield-assisstant"; const FORUM_LINK = "https://www.waze.com/discuss/t/script-road-shield-assistant-rsa/227100"; const RSA_UPDATE_NOTES = `<b>NEW:</b><br> - Converted to WME SDK<br> - <b>Make Sure to Enable RSA Layers to See the Shields</b><br> - Added Rules for Shield Checking Logic for Mexico<br> - Updated Shield Highlight Rules for All States in US<br> - Updated Some Highlight Rules for Canada<br><br> <b>BUGFIXES:</b><br> - Fix error with undefined point Radius for Circle Tag<br><br> <b>KNOWN ISSUES:</b><br> - Missing Exit Sign Shields on Node<br> - Some of the highlighting may be incorrect showing issues when there are none<br><br>`; let CountryID; (function (CountryID) { CountryID[CountryID["AFGANISTAN"] = 1] = "AFGANISTAN"; CountryID[CountryID["ALBANIA"] = 2] = "ALBANIA"; CountryID[CountryID["ALGERIA"] = 3] = "ALGERIA"; CountryID[CountryID["AMERICAN_SAMOA"] = 4] = "AMERICAN_SAMOA"; CountryID[CountryID["ANDORRA"] = 5] = "ANDORRA"; CountryID[CountryID["ANGOLA"] = 6] = "ANGOLA"; CountryID[CountryID["ANGUILLA"] = 7] = "ANGUILLA"; CountryID[CountryID["ANTARCTICA"] = 8] = "ANTARCTICA"; CountryID[CountryID["ANTIGUA_AND_BARBUDA"] = 9] = "ANTIGUA_AND_BARBUDA"; CountryID[CountryID["ARGENTINA"] = 10] = "ARGENTINA"; CountryID[CountryID["ARMENIA"] = 11] = "ARMENIA"; CountryID[CountryID["ARUBA"] = 12] = "ARUBA"; CountryID[CountryID["AUSTRALIA"] = 13] = "AUSTRALIA"; CountryID[CountryID["AUSTRIA"] = 14] = "AUSTRIA"; CountryID[CountryID["AZERBAIJAN"] = 15] = "AZERBAIJAN"; CountryID[CountryID["BAHAMAS"] = 16] = "BAHAMAS"; CountryID[CountryID["BAHRAIN"] = 17] = "BAHRAIN"; CountryID[CountryID["BAKER_ISLAND"] = 18] = "BAKER_ISLAND"; CountryID[CountryID["BANGLADESH"] = 19] = "BANGLADESH"; CountryID[CountryID["BARBADOS"] = 20] = "BARBADOS"; CountryID[CountryID["BELGUIM"] = 21] = "BELGUIM"; CountryID[CountryID["BELIZE"] = 22] = "BELIZE"; CountryID[CountryID["BENIN"] = 23] = "BENIN"; CountryID[CountryID["BERMUDA"] = 24] = "BERMUDA"; CountryID[CountryID["BHUTAN"] = 25] = "BHUTAN"; CountryID[CountryID["BOLIVIA"] = 26] = "BOLIVIA"; CountryID[CountryID["BOSNIA_AND_HERZEGOWINA"] = 27] = "BOSNIA_AND_HERZEGOWINA"; CountryID[CountryID["BOTSWANA"] = 28] = "BOTSWANA"; CountryID[CountryID["BOUVET_ISLAND"] = 29] = "BOUVET_ISLAND"; CountryID[CountryID["BRAZIL"] = 30] = "BRAZIL"; CountryID[CountryID["BRITISH_INDIAN_OCEAN_TERRITORY"] = 31] = "BRITISH_INDIAN_OCEAN_TERRITORY"; CountryID[CountryID["BRITISH_VIRGIN_ISLANDS"] = 32] = "BRITISH_VIRGIN_ISLANDS"; CountryID[CountryID["BRUNEI"] = 33] = "BRUNEI"; CountryID[CountryID["BULGARIA"] = 34] = "BULGARIA"; CountryID[CountryID["BURKINA_FASO"] = 35] = "BURKINA_FASO"; CountryID[CountryID["BURUNDI"] = 36] = "BURUNDI"; CountryID[CountryID["BELARUS"] = 37] = "BELARUS"; CountryID[CountryID["CAMBODIA"] = 38] = "CAMBODIA"; CountryID[CountryID["CAMEROON"] = 39] = "CAMEROON"; CountryID[CountryID["CANADA"] = 40] = "CANADA"; CountryID[CountryID["CAPE_VERDE"] = 41] = "CAPE_VERDE"; CountryID[CountryID["CAYMAN_ISLANDS"] = 42] = "CAYMAN_ISLANDS"; CountryID[CountryID["CENTRAL_AFRICAN_REPUBLIC"] = 43] = "CENTRAL_AFRICAN_REPUBLIC"; CountryID[CountryID["CHAD"] = 44] = "CHAD"; CountryID[CountryID["CHILE"] = 45] = "CHILE"; CountryID[CountryID["CHINA"] = 46] = "CHINA"; CountryID[CountryID["CHRISTMAS_ISLAND"] = 47] = "CHRISTMAS_ISLAND"; CountryID[CountryID["COCOS_ISLANDS"] = 48] = "COCOS_ISLANDS"; CountryID[CountryID["KEELING_ISLANDS"] = 48] = "KEELING_ISLANDS"; CountryID[CountryID["COLOMBIA"] = 49] = "COLOMBIA"; CountryID[CountryID["COMOROS"] = 50] = "COMOROS"; CountryID[CountryID["CONGO"] = 51] = "CONGO"; CountryID[CountryID["COOK_ISLANDS"] = 52] = "COOK_ISLANDS"; CountryID[CountryID["COSTA_RICA"] = 53] = "COSTA_RICA"; CountryID[CountryID["CROATIA"] = 54] = "CROATIA"; CountryID[CountryID["CUBA"] = 55] = "CUBA"; CountryID[CountryID["CYPRUS"] = 56] = "CYPRUS"; CountryID[CountryID["CZECH_REPUBLIC"] = 57] = "CZECH_REPUBLIC"; CountryID[CountryID["DENMARK"] = 58] = "DENMARK"; CountryID[CountryID["DJIBOUTI"] = 59] = "DJIBOUTI"; CountryID[CountryID["DOMINICA"] = 60] = "DOMINICA"; CountryID[CountryID["DOMINICAN_REPUBLIC"] = 61] = "DOMINICAN_REPUBLIC"; CountryID[CountryID["ECUADOR"] = 62] = "ECUADOR"; CountryID[CountryID["EGYPT"] = 63] = "EGYPT"; CountryID[CountryID["EL_SALVADOR"] = 64] = "EL_SALVADOR"; CountryID[CountryID["EQUATORIAL_GUINEA"] = 65] = "EQUATORIAL_GUINEA"; CountryID[CountryID["ERITREA"] = 66] = "ERITREA"; CountryID[CountryID["ESTONIA"] = 67] = "ESTONIA"; CountryID[CountryID["ETHIOPIA"] = 68] = "ETHIOPIA"; CountryID[CountryID["FALKLAND_ISLANDS"] = 69] = "FALKLAND_ISLANDS"; CountryID[CountryID["ISLAS_MALVINAS"] = 69] = "ISLAS_MALVINAS"; CountryID[CountryID["FAROE_ISLANDS"] = 70] = "FAROE_ISLANDS"; CountryID[CountryID["MICRONEISA"] = 71] = "MICRONEISA"; CountryID[CountryID["FIJI"] = 72] = "FIJI"; CountryID[CountryID["FRNACE"] = 73] = "FRNACE"; CountryID[CountryID["FRENCH_GUIANA"] = 74] = "FRENCH_GUIANA"; CountryID[CountryID["FRENCH_POLYNESIA"] = 75] = "FRENCH_POLYNESIA"; CountryID[CountryID["FRENCH_SOUTHERN_TERRITORIES"] = 76] = "FRENCH_SOUTHERN_TERRITORIES"; CountryID[CountryID["GABON"] = 77] = "GABON"; CountryID[CountryID["GAMBIA"] = 78] = "GAMBIA"; CountryID[CountryID["GEORGIA"] = 80] = "GEORGIA"; CountryID[CountryID["GERMANY"] = 81] = "GERMANY"; CountryID[CountryID["GHANA"] = 82] = "GHANA"; CountryID[CountryID["GIBRALTAR"] = 83] = "GIBRALTAR"; CountryID[CountryID["GLORIOSO_ISLANDS"] = 84] = "GLORIOSO_ISLANDS"; CountryID[CountryID["GREECE"] = 85] = "GREECE"; CountryID[CountryID["GREENLAND"] = 86] = "GREENLAND"; CountryID[CountryID["GRENADA"] = 87] = "GRENADA"; CountryID[CountryID["GUADELOUPE"] = 88] = "GUADELOUPE"; CountryID[CountryID["GUAM"] = 89] = "GUAM"; CountryID[CountryID["GUATEMALA"] = 90] = "GUATEMALA"; CountryID[CountryID["GUERNSEY"] = 91] = "GUERNSEY"; CountryID[CountryID["GUINEA"] = 92] = "GUINEA"; CountryID[CountryID["GUINEA_BISSAU"] = 93] = "GUINEA_BISSAU"; CountryID[CountryID["GUYANA"] = 94] = "GUYANA"; CountryID[CountryID["HAITI"] = 95] = "HAITI"; CountryID[CountryID["HEARD_AND_MCDONAL_ISLANDS"] = 96] = "HEARD_AND_MCDONAL_ISLANDS"; CountryID[CountryID["HONDURAS"] = 97] = "HONDURAS"; CountryID[CountryID["HOWLAND_ISLAND"] = 98] = "HOWLAND_ISLAND"; CountryID[CountryID["HUNGARY"] = 99] = "HUNGARY"; CountryID[CountryID["ICELAND"] = 100] = "ICELAND"; CountryID[CountryID["INDIA"] = 101] = "INDIA"; CountryID[CountryID["INDONESIA"] = 102] = "INDONESIA"; CountryID[CountryID["IRAN"] = 103] = "IRAN"; CountryID[CountryID["IRAQ"] = 104] = "IRAQ"; CountryID[CountryID["IRELAND"] = 105] = "IRELAND"; CountryID[CountryID["ITALY"] = 107] = "ITALY"; CountryID[CountryID["COTE_DIVORE"] = 108] = "COTE_DIVORE"; CountryID[CountryID["JAMAICA"] = 109] = "JAMAICA"; CountryID[CountryID["JAN_MAYEN"] = 110] = "JAN_MAYEN"; CountryID[CountryID["JAPAN"] = 111] = "JAPAN"; CountryID[CountryID["JARVIS_ISLAND"] = 112] = "JARVIS_ISLAND"; CountryID[CountryID["JERSEY"] = 113] = "JERSEY"; CountryID[CountryID["JOHNSTON_ATOLL"] = 114] = "JOHNSTON_ATOLL"; CountryID[CountryID["JORDAN"] = 115] = "JORDAN"; CountryID[CountryID["JUAN_DE_NOVA_ISLAND"] = 116] = "JUAN_DE_NOVA_ISLAND"; CountryID[CountryID["KAZAKHSTAN"] = 117] = "KAZAKHSTAN"; CountryID[CountryID["KENYA"] = 118] = "KENYA"; CountryID[CountryID["KIRIBATI"] = 119] = "KIRIBATI"; CountryID[CountryID["KUWAIT"] = 120] = "KUWAIT"; CountryID[CountryID["KYRGYZSTAN"] = 121] = "KYRGYZSTAN"; CountryID[CountryID["LAOS"] = 122] = "LAOS"; CountryID[CountryID["LATVIA"] = 123] = "LATVIA"; CountryID[CountryID["LEBANON"] = 124] = "LEBANON"; CountryID[CountryID["LESOTHO"] = 125] = "LESOTHO"; CountryID[CountryID["LIBERIA"] = 126] = "LIBERIA"; CountryID[CountryID["LIBYA"] = 127] = "LIBYA"; CountryID[CountryID["LIECHTENSTEIN"] = 128] = "LIECHTENSTEIN"; CountryID[CountryID["LITHUANIA"] = 129] = "LITHUANIA"; CountryID[CountryID["LUXEMBOURG"] = 130] = "LUXEMBOURG"; CountryID[CountryID["MACAU"] = 131] = "MACAU"; CountryID[CountryID["MACEDONIA"] = 132] = "MACEDONIA"; CountryID[CountryID["MADAGASCAR"] = 133] = "MADAGASCAR"; CountryID[CountryID["MALAWI"] = 134] = "MALAWI"; CountryID[CountryID["MALAYSIA"] = 135] = "MALAYSIA"; CountryID[CountryID["MALDIVES"] = 136] = "MALDIVES"; CountryID[CountryID["MALI"] = 137] = "MALI"; CountryID[CountryID["MALTA"] = 138] = "MALTA"; CountryID[CountryID["ISLE_OF_MAN"] = 139] = "ISLE_OF_MAN"; CountryID[CountryID["MARSHALL_ISLANDS"] = 140] = "MARSHALL_ISLANDS"; CountryID[CountryID["MARTINIQUE"] = 141] = "MARTINIQUE"; CountryID[CountryID["MAURITANIA"] = 142] = "MAURITANIA"; CountryID[CountryID["MAURITIUS"] = 143] = "MAURITIUS"; CountryID[CountryID["MAYOTTE"] = 144] = "MAYOTTE"; CountryID[CountryID["MEXICO"] = 145] = "MEXICO"; CountryID[CountryID["MIDWAY_ISLAND"] = 146] = "MIDWAY_ISLAND"; CountryID[CountryID["MOLDOVA"] = 147] = "MOLDOVA"; CountryID[CountryID["MONACO"] = 148] = "MONACO"; CountryID[CountryID["MONGOLIA"] = 149] = "MONGOLIA"; CountryID[CountryID["MONTENEGRO"] = 150] = "MONTENEGRO"; CountryID[CountryID["MONTSERRAT"] = 151] = "MONTSERRAT"; CountryID[CountryID["MOROCCO"] = 152] = "MOROCCO"; CountryID[CountryID["MOZAMBIQUE"] = 153] = "MOZAMBIQUE"; CountryID[CountryID["MYANMAR"] = 154] = "MYANMAR"; CountryID[CountryID["NAMIBIA"] = 155] = "NAMIBIA"; CountryID[CountryID["NAURU"] = 156] = "NAURU"; CountryID[CountryID["NEPAL"] = 157] = "NEPAL"; CountryID[CountryID["NETHERLANDS"] = 158] = "NETHERLANDS"; CountryID[CountryID["NEW_CALEDONIA"] = 159] = "NEW_CALEDONIA"; CountryID[CountryID["NEW_ZEALAND"] = 161] = "NEW_ZEALAND"; CountryID[CountryID["NICARAGUA"] = 162] = "NICARAGUA"; CountryID[CountryID["NIGER"] = 163] = "NIGER"; CountryID[CountryID["NIGERIA"] = 164] = "NIGERIA"; CountryID[CountryID["NIUE"] = 165] = "NIUE"; CountryID[CountryID["NORFOLK_ISLAND"] = 166] = "NORFOLK_ISLAND"; CountryID[CountryID["NORTHERN_MARIANA_ISLANDS"] = 167] = "NORTHERN_MARIANA_ISLANDS"; CountryID[CountryID["NORTH_KOREA"] = 168] = "NORTH_KOREA"; CountryID[CountryID["KOREA_NORTH"] = 168] = "KOREA_NORTH"; CountryID[CountryID["NORWAY"] = 169] = "NORWAY"; CountryID[CountryID["OMAN"] = 170] = "OMAN"; CountryID[CountryID["PASIFIC_ISLANDS"] = 171] = "PASIFIC_ISLANDS"; CountryID[CountryID["PALAU"] = 171] = "PALAU"; CountryID[CountryID["PAKISTAN"] = 172] = "PAKISTAN"; CountryID[CountryID["PANAMA"] = 173] = "PANAMA"; CountryID[CountryID["PAPUA_NEW_GUINEA"] = 174] = "PAPUA_NEW_GUINEA"; CountryID[CountryID["PARACEL_ISLANDS"] = 175] = "PARACEL_ISLANDS"; CountryID[CountryID["PARAGUAY"] = 176] = "PARAGUAY"; CountryID[CountryID["PERU"] = 177] = "PERU"; CountryID[CountryID["PHILIPPINES"] = 178] = "PHILIPPINES"; CountryID[CountryID["PITCAIRN_ISLANDS"] = 179] = "PITCAIRN_ISLANDS"; CountryID[CountryID["POLAND"] = 180] = "POLAND"; CountryID[CountryID["PORTUGAL"] = 181] = "PORTUGAL"; CountryID[CountryID["PUERTO_RICO"] = 182] = "PUERTO_RICO"; CountryID[CountryID["QATAR"] = 183] = "QATAR"; CountryID[CountryID["REUNION"] = 184] = "REUNION"; CountryID[CountryID["ROMANIA"] = 185] = "ROMANIA"; CountryID[CountryID["RUSSIA"] = 186] = "RUSSIA"; CountryID[CountryID["RWANDA"] = 187] = "RWANDA"; CountryID[CountryID["SAN_MARINO"] = 188] = "SAN_MARINO"; CountryID[CountryID["SAO_TOME_AND_PRINCIPE"] = 189] = "SAO_TOME_AND_PRINCIPE"; CountryID[CountryID["SAUDI_ARABIA"] = 190] = "SAUDI_ARABIA"; CountryID[CountryID["SENEGAL"] = 191] = "SENEGAL"; CountryID[CountryID["SERBIA"] = 192] = "SERBIA"; CountryID[CountryID["SEYCHELLES"] = 193] = "SEYCHELLES"; CountryID[CountryID["SIERRA_LEONE"] = 194] = "SIERRA_LEONE"; CountryID[CountryID["SINGAPORE"] = 195] = "SINGAPORE"; CountryID[CountryID["SLOVAKIA"] = 196] = "SLOVAKIA"; CountryID[CountryID["SLOVENIA"] = 197] = "SLOVENIA"; CountryID[CountryID["SOLOMON_ISLANDS"] = 198] = "SOLOMON_ISLANDS"; CountryID[CountryID["SOMALIA"] = 199] = "SOMALIA"; CountryID[CountryID["SOUTH_AFRICA"] = 200] = "SOUTH_AFRICA"; CountryID[CountryID["SOUTH_GEORGIA_AND_THE_SOUTH_SANDWICH_ISLANDS"] = 201] = "SOUTH_GEORGIA_AND_THE_SOUTH_SANDWICH_ISLANDS"; CountryID[CountryID["SOUTH_GEORGIA"] = 201] = "SOUTH_GEORGIA"; CountryID[CountryID["SOUTH_SANDWICH_ISLANDS"] = 201] = "SOUTH_SANDWICH_ISLANDS"; CountryID[CountryID["SOUTH_KOREA"] = 202] = "SOUTH_KOREA"; CountryID[CountryID["KOREA_SOUTH"] = 202] = "KOREA_SOUTH"; CountryID[CountryID["SPAIN"] = 203] = "SPAIN"; CountryID[CountryID["SPRATLY_ISLANDS"] = 204] = "SPRATLY_ISLANDS"; CountryID[CountryID["SRI_LANKA"] = 205] = "SRI_LANKA"; CountryID[CountryID["ST_MARTIN"] = 254] = "ST_MARTIN"; CountryID[CountryID["SAINT_MARTIN"] = 254] = "SAINT_MARTIN"; CountryID[CountryID["ST_HELENA"] = 206] = "ST_HELENA"; CountryID[CountryID["ST_KITTS_AND_NEVIS"] = 207] = "ST_KITTS_AND_NEVIS"; CountryID[CountryID["ST_LUCIA"] = 208] = "ST_LUCIA"; CountryID[CountryID["ST_PIERRE_AND_MIQUELON"] = 209] = "ST_PIERRE_AND_MIQUELON"; CountryID[CountryID["ST_VINCENT_AND_THE_GRENADINES"] = 210] = "ST_VINCENT_AND_THE_GRENADINES"; CountryID[CountryID["SUDAN"] = 211] = "SUDAN"; CountryID[CountryID["SURINAME"] = 212] = "SURINAME"; CountryID[CountryID["SVALBARD"] = 213] = "SVALBARD"; CountryID[CountryID["SWAZILAND"] = 214] = "SWAZILAND"; CountryID[CountryID["SWEDEN"] = 215] = "SWEDEN"; CountryID[CountryID["SWITZERLAND"] = 216] = "SWITZERLAND"; CountryID[CountryID["SYRIA"] = 217] = "SYRIA"; CountryID[CountryID["TAIWAN"] = 218] = "TAIWAN"; CountryID[CountryID["TAJIKISTAN"] = 219] = "TAJIKISTAN"; CountryID[CountryID["TANZANIA"] = 220] = "TANZANIA"; CountryID[CountryID["THAILAND"] = 221] = "THAILAND"; CountryID[CountryID["TOGO"] = 222] = "TOGO"; CountryID[CountryID["TOKELAU"] = 223] = "TOKELAU"; CountryID[CountryID["TONGA"] = 224] = "TONGA"; CountryID[CountryID["TRINIDAD_AND_TOBAGO"] = 225] = "TRINIDAD_AND_TOBAGO"; CountryID[CountryID["TUNISIA"] = 226] = "TUNISIA"; CountryID[CountryID["TURKEY"] = 227] = "TURKEY"; CountryID[CountryID["TURKMENISTAN"] = 228] = "TURKMENISTAN"; CountryID[CountryID["TURKS_AND_CAICOS_ISLANDS"] = 229] = "TURKS_AND_CAICOS_ISLANDS"; CountryID[CountryID["TUVALU"] = 230] = "TUVALU"; CountryID[CountryID["UGANDA"] = 231] = "UGANDA"; CountryID[CountryID["UKRAINE"] = 232] = "UKRAINE"; CountryID[CountryID["UNITED_ARAB_EMIRATES"] = 233] = "UNITED_ARAB_EMIRATES"; CountryID[CountryID["UNITED_KINGDOM"] = 234] = "UNITED_KINGDOM"; CountryID[CountryID["UK"] = 234] = "UK"; CountryID[CountryID["GREAT_BRITAIN"] = 234] = "GREAT_BRITAIN"; CountryID[CountryID["UNITED_STATES"] = 235] = "UNITED_STATES"; CountryID[CountryID["USA"] = 235] = "USA"; CountryID[CountryID["UNITED_STATES_OF_AMERICA"] = 235] = "UNITED_STATES_OF_AMERICA"; CountryID[CountryID["URUGUAY"] = 236] = "URUGUAY"; CountryID[CountryID["UZBEKISTAN"] = 237] = "UZBEKISTAN"; CountryID[CountryID["VANUATU"] = 238] = "VANUATU"; CountryID[CountryID["VENEZUELA"] = 239] = "VENEZUELA"; CountryID[CountryID["VIETNAM"] = 240] = "VIETNAM"; CountryID[CountryID["US_VIRGIN_ISLANDS"] = 241] = "US_VIRGIN_ISLANDS"; CountryID[CountryID["WAKE_ISLAND"] = 242] = "WAKE_ISLAND"; CountryID[CountryID["WALLIS_AND_FUTUNA"] = 243] = "WALLIS_AND_FUTUNA"; CountryID[CountryID["WESTERN_SAHARA"] = 245] = "WESTERN_SAHARA"; CountryID[CountryID["SAMOA"] = 246] = "SAMOA"; CountryID[CountryID["YEMEN"] = 247] = "YEMEN"; CountryID[CountryID["DEMOCRATIC_REPUBLIC_OF_THE_CONGO"] = 248] = "DEMOCRATIC_REPUBLIC_OF_THE_CONGO"; CountryID[CountryID["DRC"] = 248] = "DRC"; CountryID[CountryID["ZAMBIA"] = 249] = "ZAMBIA"; CountryID[CountryID["ZIMBABWE"] = 250] = "ZIMBABWE"; CountryID[CountryID["FINLAND"] = 251] = "FINLAND"; CountryID[CountryID["CURACAO"] = 252] = "CURACAO"; CountryID[CountryID["BONAIRE_SINT_EUSTATIUS_SABA_ISLAND"] = 253] = "BONAIRE_SINT_EUSTATIUS_SABA_ISLAND"; CountryID[CountryID["BONAIRE"] = 253] = "BONAIRE"; CountryID[CountryID["SINT_EUSTATIUS"] = 253] = "SINT_EUSTATIUS"; CountryID[CountryID["SABA_ISLAND"] = 253] = "SABA_ISLAND"; CountryID[CountryID["SAINT_BARTHELEMY"] = 255] = "SAINT_BARTHELEMY"; CountryID[CountryID["SAINT_BARTHS"] = 255] = "SAINT_BARTHS"; CountryID[CountryID["SAINT_BARTS"] = 255] = "SAINT_BARTS"; CountryID[CountryID["HONG_KONG"] = 256] = "HONG_KONG"; CountryID[CountryID["SINT_MAARTEN"] = 257] = "SINT_MAARTEN"; CountryID[CountryID["TIMOR_LESTE"] = 258] = "TIMOR_LESTE"; CountryID[CountryID["SOUTH_SUDAN"] = 259] = "SOUTH_SUDAN"; })(CountryID || (CountryID = {})); const MIN_ZOOM_LEVEL = 14; let ZoomLevel; (function (ZoomLevel) { ZoomLevel[ZoomLevel["ZM0"] = 12] = "ZM0"; ZoomLevel[ZoomLevel["ZM1"] = 13] = "ZM1"; ZoomLevel[ZoomLevel["ZM2"] = 14] = "ZM2"; ZoomLevel[ZoomLevel["ZM3"] = 15] = "ZM3"; ZoomLevel[ZoomLevel["ZM4"] = 16] = "ZM4"; ZoomLevel[ZoomLevel["ZM5"] = 17] = "ZM5"; ZoomLevel[ZoomLevel["ZM6"] = 18] = "ZM6"; ZoomLevel[ZoomLevel["ZM7"] = 19] = "ZM7"; ZoomLevel[ZoomLevel["ZM8"] = 20] = "ZM8"; ZoomLevel[ZoomLevel["ZM9"] = 21] = "ZM9"; ZoomLevel[ZoomLevel["ZM10"] = 22] = "ZM10"; })(ZoomLevel || (ZoomLevel = {})); const minShieldDisplayLengths = { 15: 150, 16: 90, 17: 80, 18: 70, 19: 60, 20: 50, 21: 40, 22: 30, }; const RoadAbbr = { //Canada 40: { Alberta: { "^Hwy 1$": 5000, // 5000: National-Trans-Canada Highway "^Hwy 1A\\b": 5011, // 5011: Alberta - Provincial Hwy "^Hwy 2\\b": 5011, // 5011: Alberta - Provincial Hwy "^Hwy 3$": 5015, // 5015: Alberta - Crowsnext Hwy "^Hwy 3A\\b": 5011, // 5011: Alberta - Provincial Hwy "^Hwy 16$": 5000, // 5000: National-Trans-Canada Highway "^Hwy 16A\\b": 5011, // 5011: Alberta - Provincial Hwy "^Hwy ([4-9]|1[0-57-9]|[2-9]\\d{1}|2\\d{2})\\b": 5011, "^Hwy ([3-9]\\d{2})\\b": 5012, }, "British Columbia": { "^Hwy 1\\b": 5000, // 5000: National-Trans-Canada Highway "^Hwy 2\\b": 5001, // 5001: BC - Provincial Hwy "^Hwy 3\\b": 5002, // 5002: BC - Crowsnest Hwy "^Hwy 16\\b": 5000, // 5000: National-Trans-Canada Highway "^Hwy 113\\b": 5004, // 5004: BC - Nisga'a Hwy "^Hwy\\s+([4-9]|[1-9][0-57-9]|10\\d|11[0-24-9]|1[2-9]\\d|[2-9]\\d{1,2})[a-zA-Z]*\\b": 5001, // 5001: BC - Provincial Hwy }, Saskatchewan: { "^Hwy 1\\b": 5000, // 5000: National - Trans-Canada Hwy "^Hwy 16\\b": 5000, // 5000: National - Trans-Canada Hwy "^Hwy ([2-9]|1[0-57-9]|[2-9]\\d|[1-3]\\d{2})\\b": 5030, // 5030: Saskatchewan - Provincial Hwy "^Hwy (9\\d{2})\\b": 5031, // 5031: Saskatchewan - Northern Secondary Hwy "^Hwy ([6-7]\\d{2})\\b": 5032, // 5032: Saskatchewan - Municipal Road }, Manitoba: { "^Hwy 1\\b": 5000, // 5000: National - Trans-Canada Hwy "^Hwy 16\\b": 5000, // 5000: National - Trans-Canada Hwy "^Hwy ([2-9]|1[0-57-9]|[2-9]\\d|1\\d{2})\\b": 5038, // 5038: Manitoba - Provincial Trunk Highway "^Hwy ([2-9]\\d{2})\\b": 5039, // 5039: Manitoba - Provincial Rd }, Ontario: { "^QEW\\b": 5058, // 5058: Ontario QEW "(^Hwy 17\\b|Hwy 17$)": new Set([5000, 5057]), // 5000: National - Trans-Canada Hwy "^Hwy 407\\b": new Set([5207, 5206]), // 5060: Ontario ETR "^Hwy 412\\b": 5059, // 5059: Ontario Toll Hwy "^Hwy 418\\b": new Set([5059, 5057]), // 5059: Ontario Toll Hwy // "Hwy [1-9]\\d{0,2}\\b": 5057, // 5057: Ontario King's Hwy 1-16 // "Hwy (1[89]|[2-9]d|[1-3]d{2}|40[0-6])\\b": 5057, // 5057: Ontario King's Hwy 18-406 // "Hwy (40[89]|41[01])\\b": 5057, // 5057: Ontario King's Hwy 408-411 // "Hwy (41[3-7])\\b": 5057, // 5057: Ontario King's Hwy 413-417 "^CR-[1-9]\\d{0,2}\\b": 5063, "^Hwy\\s+([1-9]|[1-68-9]\\d|[1-3]\\d{2}|40[0-68-9]|41[0-13-79]|4[2-9]\\d|[7-9]\\d{2})[A-Z]*\\b": 5057, "^Hwy\\s+[5-6]\\d{2}\\b": 5061, // 5061: Ontario Secondary Hwy 500-699 // "Hwy (80d|8[1-9]d)\\b": 5057, // 5057: Ontario Tertiary Hwy "^(Muskoka|Wellington|Winchester|Regional) (Road|Rd) [1-9]\\d{0,2}\\b": new Set([ 5065, 5063, 5077, ]), // Ontario Regional }, Quebec: { "Rte Transcanadienne": 5093, // 5093: Quebec: Route Transcanadienne "^Aut [1-9]\\d{1,2}\\b": 5090, // 5090: Quebec Autoroute 1-999 "^Rte [1-9]\\d{0,2}\\b": 5091, // 5091: Quebec Route 100-399 "R (10d|1[1-9]d|[2-9]d{2}|1[0-4]d{2}|15[0-5]d)\b": 5092, // 5092: Quebec Route 100-1559 }, "New Brunswick": { "^Rte 2\\b": 5000, // 5000: Trans-Canada Hwy "^Rte 16\\b": 5000, // 5000: Trans-Canada Hwy "^Rte 1\\b": 5112, // 5112: NB Arterial Highway 1 "^Rte ([3-9]|1[0-57-9]|[2-9]\\d)\\b": 5112, // 5112: NB Arterial Highway 17-99 "^Rte (10\\d|11[02-9]|1[2-9]\\d)\\b": 5113, // 5113: NB Collector Highway 100-199 "^Rte (111|[2-9]\\d{2})\\b": 5114, // 5114: NB Local Highway 200-999 }, "Nova Scotia": { "^Hwy ([1-9]\\d{0,1})\\b": 5116, // 5116: NS Trunk Hwy 1-99 "^Hwy 104\\b": new Set([5115, 5000]), // In NS 104 has 2 different shields "^Hwy (10[5-6])\\b": 5000, // 5000: National Trans Canada Highway 105-106 "^Hwy (10[0-37-9]|1[1-9]\\d)\\b": 5115, // 5115: NS Aterial Hwy 107-199 "^Hwy ([2-3]\\d{2})\\b": 5117, // 5117: NS Collector Hwy 200-399 }, "Newfoundland and Labrador": { "^Hwy 1": 5000, // 5000: National - Trans-Canada Hwy 1 "^Rte ([2-9]|[1-9]\\d|[1-5]\\d{2})\\b": 5129, // NLR: Newfoundland Labrador Route 2-599 }, "Prince Edward Island": { "^Rte 1$": 5000, // 5000: National Trans-Canada Hwy "^Rte ([2-9]|[1-9]\\d{1,2})\\b": 5144, // 5144: PEI - Provincial Highway }, "Yukon Territory": { "^Hwy 1\\b": 5146, // 5145: Yukon - Territorial Hwy - Orange "Hwy 2": 5146, // 5146: Yukon - Territorial Hwy - Amber "Hwy 3": 5147, // 5147: Yukon - Territorial Hwy - Maroon "Hwy 4": 5148, // 5148: Yukon - Territorial Hwy - Brown "Hwy 5": 5149, // 5149: Yukon - Territorial Hwy - Blue "Hwy 6": 5150, // 5150: Yukon - Territorial Hwy - Teal "Hwy 7": 5147, // 5147: Yukon - Territorial Hwy - Maroon "Hwy 8": 5148, // 5148: Yukon - Territorial Hwy - Brown "Hwy 9": 5151, // 5151: Yukon - Territorial Hwy - Black "Hwy 10": 5151, // 5151: Yukon - Territorial Hwy - Black "Hwy 11": 5149, // 5149: Yukon - Territorial Hwy - Blue "Hwy 37": 5147, // 5147: Yukon - Territorial Hwy - Maroon }, "Northwest Territories": { "Hwy ([1-9]|10)\b": 5152, // 5152: NWT - Territorial Hwy 1-10 }, }, // France 73: { "": { "D\\d+[^:]*": 1092, "N\\d+[^:]*": 1072, "A\\d+[^:]*": 1072, "M\\d+[^:]*": 1067, "C\\d+[^:]*": 3333, "T\\d+[^:]*": 3037, }, }, // Germany 81: { "": { "(A\\d{1,3})": 1012, "(B\\d{1,3})": 1094 } }, // Mexico 145: { "*": { "^MEX-[1-9]\\d{0,2}[A-Z]*\\b": new Set([1107, 1106]) }, "Quintana Roo": { "Q.ROO-[1-9]\\d{0,2}\\b": 1000 }, Yucatán: { "YUC-[1-9]\\d{0,2}\\b": 1000 }, Campeche: { "CAM-[1-9]\\d{0,2}\\b": 1000 }, }, // Ukraine 232: { "": { "(E\\d{2,3})": 1048, "(М-\\d{2})": 1071, "(Н-\\d{2})": 1071, "(Р-\\d{2})": 1008, "(Т-\\d{2}-\\d{2,3})": 1008, "(О\\d{6,7})": 1085, "(С\\d{6,7})": 1085, }, }, // US 235: { "*": { "^I-[1-9]\\d{0,2}(?!\s+(?:W|E|East|West))\\b": 5, "^I-[1-9]\\d{0,2}\\s{1,}\\b(?:Bus|BUS|Business|BUSINESS)\\b": 2003, "^US-[1-9]\\d{0,2}[A-Z]*\\b": 6, }, Alabama: { "^CR-[1-9]\\d{0,2}\\b": 2002, "^SR-[1-9]\\d{0,2}\\b": 2019 }, Alaska: { "CR-[1-9]\\d{0,2}": 2002, "SR-[1-9]\\d{0,2}": 2017, "AK-[1-9]\\d{0,2}": 2017, "A-[1-9]\\d{0,2}": 2017, }, Arizona: { "CR-[1-9]\\d{0,2}": 2002, "SR-[1-9]\\d{0,2}": 2022 }, Arkansas: { "^CR-[1-9]\\d{0,2}\\b": 2002, "^AR-[1-9]\\d{0,2}\\b": 2020, "^AR-$1 SPUR\\b": 2020 }, California: { "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 1082, "^SR-[1-9]\\d{0,2}\\b": 1082 }, Colorado: { "^CR-[1-9]\\d{0,2}[a-zA-Z]*\\b": 2002, "^SH-[1-9]\\d{0,2}[a-zA-Z]*\\b": 2025, "^SR-[1-9]\\d{0,2}\\b": 2025, }, Connecticut: { "^CR-[1-9]\\d{0,2}": 2002, "^SH-[1-9]\\d{0,2}": 2027, "^SR-[1-9]\\d{0,2}": 2027, "\\b(?:Wilbur Cross(?: Parkway| Pkwy))\\b": 2027, }, Delaware: { "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 7, "^SR-[1-9]\\d{0,2}\\b": 7 }, "District of Columbia": { "DC-[1-9]\\d{0,2}": 7 }, Florida: { "^CR-[1-9]\\d{0,2}": 2002, "^SH-[1-9]\\d{0,2}": 2030, "^SR-[1-9]\\d{0,2}": 2030, "^Florida.* (Turnpike|Tpk|Tpke)\\b": 2033, }, Georgia: { "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2036, "^SR-[1-9]\\d{0,2}\\b": 2036 }, Hawaii: { "H-[1-9]\\d{0,2}": 5, "CR-[1-9]\\d{0,2}": 2002, "SH-[1-9]\\d{0,2}": 2041, "SR-[1-9]\\d{0,2}": 2041, }, Idaho: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2043, "^SR-[1-9]\\d{0,2}\\b": 2043, "^ID-[1-9]\\d{0,2}\\b": 2043, }, Illinois: { "^CH-[1-9]\\d{0,2}": 2002, "^CR-[1-9]\\d{0,3}": 2002, "^SH-[1-9]\\d{0,2}": 2044, "^SR-[1-9]\\d{0,2}": 2044, }, Indiana: { "^CH-[1-9]\\d{0,2}": 2002, "^CR-[1-9]\\d{0,2}": 2002, "^SH-[1-9]\\d{0,2}": 2045, "^SR-[1-9]\\d{0,2}": 2045, "^IN-[1-9]\\d{0,2}": 2045, }, Iowa: { "CH-[1-9]\\d{0,2}": 2002, "CR-[1-9]\\d{0,2}": 2002, "SH-[1-9]\\d{0,2}": 7, "SR-[1-9]\\d{0,2}": 7, "IA-[1-9]\\d{0,2}": 7, }, Kansas: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2046, "^SR-[1-9]\\d{0,2}\\b": 2046, "^K-[1-9]\\d{0,2}\\b": 2046, }, Kentucky: { "^US-[1-9]\\d{0,2}\\s+(?:BUS|Bus|Business)\\b": 2005, "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 7, "^SR-[1-9]\\d{0,2}\\b": 7, "^KY-[1-9]\\d{0,3}\\b": 7, "^AA (Highway|Hwy)\\b": 2050, }, Louisiana: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 1117, "^SR-[1-9]\\d{0,3}\\b": 1117, "^LA-[1-9]\\d{0,3}\\b": new Set([1117, 1115]), }, Maine: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2051, "^SR-[1-9]\\d{0,2}(?!\\s*(?:BUS|Bus|Business))\\b": 2051, "^SR-[1-9]\\d{0,2}\\s+(?:BUS|Bus|Business)\\b": 2052, }, Maryland: { "^CH-[1-9]\\d{0,2}": 2002, "^CR-[1-9]\\d{0,2}": 2002, "^SH-[1-9]\\d{0,2}": 2053, "^SR-[1-9]\\d{0,2}": 2053, "^MD-[1-9]\\d{0,2}": 2053, }, Massachusetts: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2055, "^SR-[1-9]\\d{0,2}[a-zA-Z]*\\b": 2055, }, Michigan: { "^CR-[1-9]\\d{0,2}\\b": 2056, "^M-[1-9]\\d{0,2}\\b": 2056, "^SR-[1-9]\\d{0,2}\\b": 2056 }, Minnesota: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2180, "^SH-[1-9]\\d{0,2}\\b": 2060, "^SR-[1-9]\\d{0,2}\\b": 2060, "^MN-[1-9]\\d{0,2}\\b": 2060, }, Mississippi: { "^SH-[1-9]\\d{0,2}\\b": 7, "^SR-[1-9]\\d{0,2}\\b": 7, "^MS-[1-9]\\d{0,2}\\b": 7 }, Missouri: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2061, "^SH-[A-Z]\\w{0,2}\\b": 2062, "^SR-[1-9]\\d{0,2}\\b": 2061, "^MO-[1-9]\\d{0,2}\\b": 2061, }, Montana: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2063, "^SR-[1-9]\\d{0,2}\\b": 2063, "^MT-[1-9]\\d{0,2}\\b": 2063, }, Nebraska: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 7, "^SR-[1-9]\\d{0,2}\\b": 7, "^L-[1-9]\\d{0,2}\\b": 7, "^N-[1-9]\\d{0,2}\\b": 2072, "^S-[1-9]\\d{0,2}\\b": 7, }, Nevada: { "^US-[1-9]\\d{0,2}\\s+(?:ALT|Alt)\\b": 2004, "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2086, "^SR-[1-9]\\d{0,2}\\b": 2086, "^NV-[1-9]\\d{0,2}\\b": 2086, }, "New Hampshire": { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2076, "^SR-[1-9]\\d{0,2}[a-zA-Z]*\\b": 2076, }, "New Jersey": { "^CH-[1-9]\\d{0,2}": 2002, "^CR-[1-9]\\d{0,2}": 2083, "^SH-[1-9]\\d{0,2}": 7, "^SR-[1-9]\\d{0,2}": 7, "^NJ-[1-9]\\d{0,2}": 7, "^Garden State (Parkway|Pkwy)": 2079, "^Palisades Interstate (Parkway|Pkwy)": 2082, "^Atlantic City (Expressway|Expy|Expwy)": 2000, }, "New Mexico": { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2085, "^SR-[1-9]\\d{0,2}\\b": 2085, }, "New York": { "^CH-[1-9]\\d{0,2}": 2002, "^CR-[1-9]\\d{0,2}[A-Z]*\\b": 2002, "^SH-[1-9]\\d{0,2}": 2087, "^SR-[1-9]\\d{0,2}": 2087, "^NY-[1-9]\\d{0,2}": 2087, "\\bPalisades Interstate (Parkway|Pkwy)\\b": 2082, "\\b(?:Saw Mill River(?: Parkway| Pkwy)|SMP)\\b": 2092, "\\b(?:Taconic State(?: Parkway| Pkwy)|TSP)\\b": 2092, "\\b(?:Bear Mountain State(?: Parkway| Pkwy)|BMP)\\b": 2092, "\\b(?:Cross County(?: Parkway| Pkwy)|CCP)\\b": 2092, "\\b(?:Hutchinson River(?: Parkway| Pkwy)|HRP)\\b": 2092, "\\b(?:Korean War Veterans(?: Parkway| Pkwy)|KWVP)\\b": 2092, "\\b(?:Pelham(?: Parkway| Pkwy)|PP)\\b": 2092, "\\b(?:Sprain Brook(?: Parkway| Pkwy)|SBP)\\b": 2092, "\\b(?:Belt(?: Parkway| Pkwy))\\b": 2090, "\\b(?:Cross Island(?: Parkway| Pkwy))\\b": 2090, "\\b(?:Grand Central(?: Parkway| Pkwy))\\b": 2090, "\\b(?:Jackie Robinson(?: Parkway| Pkwy))\\b": 2090, "\\b(?:Bronx River(?: Parkway| Pkwy))\\b": 2090, "\\b(?:Hutchison River(?: Parkway| Pkwy))\\b": 2090, "\\b(?:Mosholu(?: Parkway| Pkwy))\\b": 2090, "\\b(?:Northern State(?: Parkway| Pkwy))\\b": 2090, "\\b(?:Harlem River(?: Drive| Dr))\\b": 2090, "\\b(?:Robert Moses(?: Causeway| Cswy))\\b": 2090, "\\b(?:Sagtikos State(?: Parkway| Pkwy))\\b": 2090, "\\b(?:Southern State(?: Parkway| Pkwy))\\b": 2090, "\\b(?:Sunken Meadow State(?: Parkway| Pkwy))\\b": 2090, "\\b(?:Wantagh State(?: Parkway| Pkwy))\\b": 2090, "\\b(?:Loop(?: Parkway| Dr))\\b": 2091, "\\b(?:Bethpage State(?: Parkway| Pkwy))\\b": 2091, "\\b(?:Meadowbrook State(?: Parkway| Pkwy))\\b": 2091, "\\b(?:Lake Ontario State(?: Parkway| Pkwy))\\b": 2093, "\\b(?:Niagara Scenic(?: Parkway| Pkwy))\\b": 2094, }, "North Carolina": { "^US-[1-9]\\d{0,2}\\s+(?:BUS|Bus|Business)\\b": 2005, "^US-[1-9]\\d{0,2}\\s+(?:BYP|Byp|Bypass)\\b": 2006, "^US-[1-9]\\d{0,2}\\s+(?:CONN|Conn|Connector)\\b": 2007, "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2065, "^SR-[1-9]\\d{0,2}\\b": 2065, "^NC-[1-9]\\d{0,2}\\b": 2065, }, "North Dakota": { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2070, "^SR-[1-9]\\d{0,2}\\b": 2070, "^ND-[1-9]\\d{0,3}\\b": 2070, }, Ohio: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,3}\\b": 2181, "^SH-[1-9]\\d{0,2}\\b": 2095, "^SR-[1-9]\\d{0,2}\\b": 2095, }, Oklahoma: { "^SH-[1-9]\\d{0,2}\\b": 2097, "^SR-[1-9]\\d{0,2}\\b": 2097 }, Oregon: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2099, "^SR-[1-9]\\d{0,2}\\b": 2099, "^OR-[1-9]\\d{0,2}\\b": 2099, }, Pennsylvania: { "^US-[1-9]\\d{0,2}\\s+(?:BUS|Bus|Business)\\b": 2005, "^CH-[1-9]\\d{0,2}": 2002, "^CR-[1-9]\\d{0,2}": 2002, "^SH-[1-9]\\d{0,2}": 2101, "^PA-[1-9]\\d{0,2}\\b": 2101, "^Hwy\\s[1-9]\\d{0,2}\\b": 2101, "^SR-[1-9]\\d{0,2}\\s+(?:BUS|Bus|Business)\\b": 2104, "^SR-[1-9]\\d{0,2}(?!\\s*(?:BUS|Bus|Business))\\b": 2101, }, "Rhode Island": { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2108, "^SR-[1-9]\\d{0,2}\\b": 2108, "^RI-[1-9]\\d{0,2}\\b": 2108, }, "South Carolina": { "^CH-[1-9]\\d{0,2}": 2002, "^CR-[1-9]\\d{0,2}": 2002, "^SH-[1-9]\\d{0,2}": 2109, "^SR-[1-9]\\d{0,2}": 2109, "^SC-[1-9]\\d{0,2}": 2109, }, "South Dakota": { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9A-Z]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2114, "^SR-[1-9]\\d{0,2}\\b": 2114, "^SD-[1-9]\\d{0,3}\\b": 2114, }, Tennessee: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2115, "^TN-[1-9]\\d{0,2}\\b": 2115, "^SR-[1-9]\\d{0,2}\\b": 2116, }, Texas: { "^I-[1-9]\\d{0,2}[A-Z]+\\s": new Set([5, 2206]), "^SH-[1-9]\\d{0,3}": new Set([2117, 2123]), "^[Ss][Pp][Uu][Rr] [1-9]\\d{0,3}\\b": 2126, "\\b[Ll][Oo][Oo][Pp] [1-9]\\d{0,3}\\b": 2122, "^SR-[1-9]\\d{0,3}": 2117, "^FM-[1-9]\\d{0,3}": 2121, "^Beltway [1-9]\\d{0,3}\\b": 2119, "^Sam Houston (Tollway|Tlwy|Parkway|Pkwy)\\b": 2198, "^President George Bush (Turnpike|Tpke|Tpk)\\b": 2123, "^Park (Road|Rd)\\b": 2144, "^Westpark (Tollway|Tlwy)\\b": 2199, "^Fort Bend (Tollway|Tlwy|Parkway|Pkwy)\\b": 2196, }, Utah: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2127, "^SR-[1-9]\\d{0,2}\\b": 2127, }, Vermont: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2131, "^SR-[1-9]\\d{0,2}\\b": 2131, "^VT-[1-9]\\d{0,2}\\b": 2131, }, Virginia: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}]\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2128, "^SR-[1-9]\\d{0,2}\\b": 2128, "^Blue Ridge Pkwy\\b": 2069, }, Washington: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2133, "^SR-[1-9]\\d{0,2}(?!\\s*(?:Spur|SPUR|BUS|Bus|Business))\\b": 2133, "^SR-[1-9]\\d{0,2}\\s+(?:Spur|SPUR|BUS|Bus|Business)": 2134, "^FS-[1-9]\\d{0,3}\\b": 2011, }, "West Virginia": { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2138, "^SR-[1-9]\\d{0,2}\\b": 2138, "^WV-[1-9]\\d{0,2}\\b": 2138, }, Wisconsin: { "^CH-[A-Z]+\\b": 2137, "^CR-[1-9]\\d{0,2}": 2137, "^SH-[1-9]\\d{0,2}": 2135, "^SR-[1-9]\\d{0,2}": 2135, "^WIS-[1-9]\\d{0,2}\\b": 2135, "^WIS SPUR": 2135, }, Wyoming: { "^CH-[1-9]\\d{0,2}\\b": 2002, "^CR-[1-9]\\d{0,2}\\b": 2002, "^SH-[1-9]\\d{0,2}\\b": 2143, "^SR-[1-9]\\d{0,2}\\b": 2143, "^WY-[1-9]\\d{0,2}\\b": 2143, }, }, // Uruguay 236: { "": { Ruta: 1111 } }, // Réunion 262: { "": { "D\\d+[^:]*": 1092, "N\\d+[^:]*": 1072 } }, // Guadeloupe 590: { "": { "D\\d+[^:]*": 1092, "N\\d+[^:]*": 1072 } }, // French Guyana 594: { "": { "D\\d+[^:]*": 1092, "N\\d+[^:]*": 1072 } }, // Martinique 596: { "": { "D\\d+[^:]*": 1092, "N\\d+[^:]*": 1072 } }, // Wallis and Futuna 681: { "": { "D\\d+[^:]*": 1092, "N\\d+[^:]*": 1072 } }, // French Polynesia 689: { "": { "D\\d+[^:]*": 1092, "N\\d+[^:]*": 1072 } }, }; const iconsAllowingNoText = new Set([ 2000, // Atlantic City Expy 2079, // Garden State Parkway 2033, // Florida's Turnpike 2082, // Palisades Pkwy 2093, // Ontario State Pkwy 2094, // Niagara Scenic Pkwy 2199, // Westpark Tollway, 2198, // Sam Houston Parkway, 2196, // Fort Bend 2050, // AA Hwy, 2069, // Blue Ridge Pkwy 5058, // QEW ]); const Strings = { en: { enableScript: "Script enabled", HighSegShields: "Segments with Shields", HighSegShieldsClr: "Segments with Shields", ShowSegShields: "Show Segment Shields on Map", SegShieldMissing: "Segments that might be missing shields", SegShieldMissingClr: "Segments that might be missing shields", SegShieldError: "Segments that have shields but maybe shouldn't", SegShieldErrorClr: "Segments that have shields but maybe shouldn't", HighNodeShields: "Nodes with Shields (TG)", HighNodeShieldsClr: "Nodes with Shields (TG)", ShowNodeShields: "Show Node Shield Info", ShowExitShields: "Has Exit Signs", ShowTurnTTS: "Has TIO", AlertTurnTTS: "Alert if TTS is different from default", NodeShieldMissing: "Nodes that might be missing shields", NodeShieldMissingClr: "Nodes that might be missing shields", resetSettings: "Reset Settings", disabledFeat: "(Feature not configured for this country)", ShowTowards: "Has Towards", ShowVisualInst: "Has Visual Instruction", SegHasDir: "Segment Shields with direction", SegHasDirClr: "Segment Shields with direction", SegInvDir: "Segment Shields without direction", SegInvDirClr: "Segment Shields without direction", IconHead: "Map Icons", HighlightHead: "Highlights", HighlightColors: "Highlight Colors", ShowRamps: "Include Ramps", Experimental: "Experimental Features (Use at Your own Risk)", AlternativeShields: "Alternative Name Shields", AlternativePrimaryCity: "Alternative Street with Primary City", AlternativeNoCity: "Alternative Street with No City", mHPlus: "Only show on minor highways or greater", titleCase: "Segments/nodes with direction not in large-and-small-caps format", TitleCaseClr: "Segments/nodes with direction not in large-and-small-caps format", TitleCaseSftClr: "Direction in free text might not be in large-and-small-caps format", checkTWD: "Include Towards field", checkTTS: "Include TTS field", checkVI: "Include Visual Instruction field", }, "en-us": { enableScript: "Script enabled", HighSegShields: "Segments with Shields", HighSegShieldsClr: "Segments with Shields", ShowSegShields: "Show Segment Shields on Map", SegShieldMissing: "Segments that might be missing shields", SegShieldMissingClr: "Segments that might be missing shields", SegShieldError: "Segments that have shields but maybe shouldn't", SegShieldErrorClr: "Segments that have shields but maybe shouldn't", HighNodeShields: "Nodes with Shields (TG)", HighNodeShieldsClr: "Nodes with Shields (TG)", ShowNodeShields: "Show Node Shield Info", ShowExitShields: "Has Exit Signs", ShowTurnTTS: "Has TIO", AlertTurnTTS: "Alert if TTS is different from default", NodeShieldMissing: "Nodes that might be missing shields", NodeShieldMissingClr: "Nodes that might be missing shields", resetSettings: "Reset Settings", disabledFeat: "(Feature not configured for this country)", ShowTowards: "Has Towards", ShowVisualInst: "Has Visual Instruction", SegHasDir: "Segment Shields with direction", SegHasDirClr: "Segment Shields with direction", SegInvDir: "Segment Shields without direction", SegInvDirClr: "Segment Shields without direction", IconHead: "Map Icons", HighlightHead: "Highlights", HighlightColors: "Highlight Colors", ShowRamps: "Include Ramps", Experimental: "Experimental Features (Unstable use at Your own Risk)", AlternativeShields: "Alternative Name Shields", AlternativePrimaryCity: "Alternative Street with Primary City", AlternativeNoCity: "Alternative Street with No City", mHPlus: "Only show on minor highways or greater", titleCase: "Segments/nodes with direction not in large-and-small-caps format", TitleCaseClr: "Segments/nodes with direction not in large-and-small-caps format", TitleCaseSftClr: "Direction in free text might not be in large-and-small-caps format", checkTWD: "Include Towards field", checkTTS: "Include TTS field", checkVI: "Include Visual Instruction field", }, "es-419": { enableScript: "Script habilitado", HighSegShields: "Segmentos con escudos", HighSegShieldsClr: "Segmentos con escudos", ShowSegShields: "Mostrar escudos de segmentos en el mapa", SegShieldMissing: "Segmentos a los que les pueden faltar escudos", SegShieldMissingClr: "Segmentos a los que les pueden faltar escudos", SegShieldError: "Segmentos que tienen escudos y quizá no deberían", SegShieldErrorClr: "Segmentos que tienen escudos y quizá no deberían", HighNodeShields: "Nodos con escudos (TG)", HighNodeShieldsClr: "Nodos con escudos (TG)", ShowNodeShields: "Mostrar Info de Escudo en Nodo", ShowExitShields: "Incluir iconos de giro (si existen)", ShowTurnTTS: "Incuir TTS", AlertTurnTTS: "Alertar si TTS fue modificado", NodeShieldMissing: "Nodos a los que les pueden faltar escudos", NodeShieldMissingClr: "Nodos a los que les pueden faltar escudos", resetSettings: "Reiniciar ajustes", disabledFeat: "(Funcionalidad no configurada para ese país)", ShowTowards: "Incluir dirección (si existe)", ShowVisualInst: "Incluir instrucción visual", SegHasDir: "Escudos con dirección", SegHasDirClr: "Escudos con dirección", SegInvDir: "Escudos sin dirección", SegInvDirClr: "Escudos sin dirección", IconHead: "Iconos en mapa", HighlightHead: "Destacar", HighlightColors: "Reseña de Colores", ShowRamps: "Incluir Rampas", Experimental: "Experimental Features", AlternativeShields: "Alternative Name Shields", AlternativePrimaryCity: "Alternative Street with Primary City", AlternativeNoCity: "Alternative Street with No City", mHPlus: "Only show on minor highways or greater", titleCase: "Segments/nodes with direction not in large-and-small-caps format", TitleCaseClr: "Segments/nodes with direction not in large-and-small-caps format", TitleCaseSftClr: "Direction in free text might not be in large-and-small-caps format", checkTWD: "Include Towards field", checkTTS: "Include TTS field", checkVI: "Include Visual Instruction field", }, uk: { enableScript: "Скріпт вимкнено", HighSegShields: "Сегменти з шильдами", HighSegShieldsClr: "Сегменти з шильдами", ShowSegShields: "Показувати шильди на мапі", SegShieldMissing: "Сегменти, яким можливо потрібні шильди", SegShieldMissingClr: "Сегменти, яким можливо потрібні шильди", SegShieldError: "Сегменти, які мають шильди, але можливо вони непотрібні", SegShieldErrorClr: "Сегменти, які мають шильди, але можливо вони непотрібні", HighNodeShields: "Вузли з шильдами (TG)", HighNodeShieldsClr: "Вузли з шильдами (TG)", ShowNodeShields: "Показувати деталі шильда на вузлі ", ShowExitShields: "Включити іконку повороту (якщо вони є)", ShowTurnTTS: "Вимкнути TTS", AlertTurnTTS: "Сповіщати, якщо TTS відрізняється від типового", NodeShieldMissing: "Вузли, на яких можуть бути відсутні щити", NodeShieldMissingClr: "Вузли, на яких можуть бути відсутні щити", resetSettings: "Скинути налаштування", disabledFeat: "Відсутні налаштування для цієї страни", ShowTowards: "Включаючи Towards (якщо існує)", ShowVisualInst: "Включаючи візуальні інструкції", SegHasDir: "Шильди з напрямками", SegHasDirClr: "Шильди з напрямками", SegInvDir: "Шильди без напрямків", SegInvDirClr: "Шильди без напрямків", IconHead: "Іконки на мапі", HighlightHead: "Підсвічувати", HighlightColors: "Кольори підсвічування", ShowRamps: "Включаючи рампи", Experimental: "Экспериментальні засобливості", AlternativeShields: "Шильди альтернатівних назв", AlternativePrimaryCity: "Альтернативна назва с основним містом", AlternativeNoCity: "Альтернативна назва без міста", mHPlus: "Only show on minor highways or greater", titleCase: "Segments/nodes with direction not in large-and-small-caps format", TitleCaseClr: "Segments/nodes with direction not in large-and-small-caps format", TitleCaseSftClr: "Direction in free text might not be in large-and-small-caps format", checkTWD: "Include Towards field", checkTTS: "Include TTS field", checkVI: "Include Visual Instruction field", }, fr: { enableScript: "Script activé", HighSegShields: "Segments avec cartouche", HighSegShieldsClr: "Segments avec cartouche", ShowSegShields: "Afficher les cartouches sur la carte", SegShieldMissing: "Segments dont le cartouche pourrait manquer", SegShieldMissingClr: "Segments dont le cartouche pourrait manquer", SegShieldError: "Segments ayant un cartouche mais ne devraient peut-être pas", SegShieldErrorClr: "Segments ayant un cartouche mais ne devraient peut-être pas", HighNodeShields: "Noeuds avec cartouche (TG)", HighNodeShieldsClr: "Noeuds avec cartouche (TG)", ShowNodeShields: "Afficher les infos des cartouches de noeuds", ShowExitShields: "As des panneaux de sortie", ShowTurnTTS: "Has TIO", AlertTurnTTS: "Alert if TTS is different from default", NodeShieldMissing: "Noeud dont le cartouche pourrait manquer", NodeShieldMissingClr: "Noeud dont le cartouche pourrait manquer", resetSettings: "Réinitialiser les paramètres", disabledFeat: "Feature not configured for this country", ShowTowards: 'As "En direction de"', ShowVisualInst: "As des instructions visuelles", SegHasDir: "Cartouche de segment avec direction", SegHasDirClr: "Cartouche de segment avec direction", SegInvDir: "Cartouche de segment sans direction", SegInvDirClr: "Cartouche de segment sans direction", IconHead: "Icônes de carte", HighlightHead: "Surlignages", HighlightColors: "Couleurs de surlignage", ShowRamps: "Inclure les bretelles", mHPlus: "Only show on minor highways or greater", Experimental: "Experimental Features", AlternativeShields: "Alternative Name Shields", AlternativePrimaryCity: "Alternative Street with Primary City", AlternativeNoCity: "Alternative Street with No City", titleCase: "Segments/nodes with direction not in large-and-small-caps format", TitleCaseClr: "Segments/nodes with direction not in large-and-small-caps format", TitleCaseSftClr: "Direction in free text might not be in large-and-small-caps format", checkTWD: 'Inclure le champ "en direction de"', checkTTS: "Inclure le champ TTS", checkVI: "Inclure le champ d'instruction visuel", }, }; const CheckAltName = new Set([ // France 73, ]); let BadNames = []; let rsaSettings = { lastSaveAction: 0, enableScript: true, HighSegShields: false, ShowSegShields: true, SegShieldMissing: false, SegShieldError: false, SegHasDir: false, SegInvDir: false, HighNodeShields: true, ShowNodeShields: false, ShowExitShields: false, ShowTurnTTS: false, AlertTurnTTS: false, ShowTowards: false, ShowVisualInst: false, NodeShieldMissing: false, HighSegClr: "#0066ff", MissSegClr: "#00ff00", ErrSegClr: "#cc00ff", HighNodeClr: "#ff00bf", MissNodeClr: "#ff0000", SegHasDirClr: "#ffff00", SegInvDirClr: "#66ffff", TitleCaseClr: "#ff9933", TitleCaseSftClr: "#ffff66", ShowRamps: true, AlternativeShields: false, mHPlus: false, titleCase: false, checkTWD: false, checkTTS: false, checkVI: false, mapLayerVisible: false, iconLayerVisible: false, }; let UpdateObj; let SetTurn; const rsaMapLayer = { layerName: "RSA Map Layer", zIndexing: false }; const rsaIconLayer = { layerName: "RSA Icon Layer", zIndexing: false }; let LANG; let alternativeType; const styleConfig = { styleContext: { highNodeColor: (context) => { return context?.feature?.properties?.style?.strokeColor; }, labelExternalGraphic: (context) => { const style = context?.feature?.properties?.style; if (!style || !style?.sign || !style?.txt) return ""; return `https://renderer-am.waze.com/renderer/v1/signs/${style.sign}?text=${style.txt}`; }, labelGraphicHeight: (context) => { return context?.feature?.properties?.style?.height; }, labelGraphicWidth: (context) => { return context?.feature?.properties?.style?.width; }, shieldExternalGraphic: (context) => { return context?.feature?.properties?.style?.externalGraphic; }, shieldGraphicWidth: (context) => { return context?.feature?.properties?.style?.graphicWidth; }, shieldGraphicHeight: (context) => { return context?.feature?.properties?.style?.graphicHeight; }, shieldLabel: (context) => { return context?.feature?.properties?.style?.label; }, nodeStyleStrokeColor: (context) => { return context?.feature?.properties?.style?.strokeColor; }, nodeStyleStrokeOpacity: (context) => { return context?.feature?.properties?.style?.strokeOpacity; }, nodeStyleStrokeWidth: (context) => { return context?.feature?.properties?.style?.strokeWidth; }, nodeStyleFillOpacity: (context) => { return context?.feature?.properties?.style?.fillOpacity; }, nodeStylePointRadius: (context) => { return context?.feature?.properties?.style?.pointRadius; }, segHighlightStrokeOpacity: (context) => { return context?.feature?.properties?.style?.strokeOpacity; }, segHighlightStrokeColor: (context) => { return context?.feature?.properties?.style?.strokeColor; }, segHighlightStrokeWidth: (context) => { return context?.feature?.properties?.style?.strokeWidth; }, segHighlightFillColor: (context) => { return context?.feature?.properties?.style?.fillColor; }, segHighlightFillOpacity: (context) => { return context?.feature?.properties?.style?.fillOpacity; }, shieldLabelYOffset: (context) => { return context?.feature?.properties?.style?.labelYOffset; }, }, styleRules: [ { predicate: applyPointLabel, style: { strokeColor: "${highNodeColor}", strokeOpacity: 0.75, strokeWidth: 4, fillColor: "${highNodeColor}", fillOpacity: 0.75, pointRadius: 3, }, }, { predicate: applyShield, style: { externalGraphic: "${shieldExternalGraphic}", graphicWidth: "${shieldGraphicWidth}", graphicHeight: "${shieldGraphicHeight}", graphicXOffset: -20, graphicYOffset: -20, style: "opacity: 1", fillOpacity: 1, fill: "black", stroke: "black", fontColor: "green", labelOutlineColor: "white", labelOutlineWidth: 1, fontSize: 12, display: "grid", label: "${shieldLabel}", labelYOffset: "${shieldLabelYOffset}", }, }, { predicate: applySegHighlight, style: { strokeColor: "${segHighlightStrokeColor}", strokeOpacity: "${segHighlightStrokeOpacity}", strokeWidth: "${segHighlightStrokeWidth}", fillColor: "${segHighlightFillColor}", fillOpacity: "${segHighlightFillOpacity}", }, }, { predicate: applyStyleNode, style: { strokeColor: "${nodeStyleStrokeColor}", strokeOpacity: "${nodeStyleStrokeOpacity}", strokeWidth: "${nodeStyleStrokeWidth}", fillColor: "${nodeStyleFillColor}", fillOpacity: "${nodeStyleFillOpacity}", pointRadius: "${nodeStylePointRadius}", }, }, { predicate: applyStyleLabel, style: { externalGraphic: "${labelExternalGraphic}", graphicHeight: "${labelGraphicHeight}", graphicWidth: "${labelGraphicWidth}", fillOpacity: "${nodeStyleFillOpacity}", fontSize: 12, graphicZIndex: 2432, }, }, ], }; console.debug(`SDK v. ${sdk.getSDKVersion()} on ${sdk.getWMEVersion()} initialized`); // function rsaBootstrap() { // // if (!document.getElementById('edit-panel') || !sdk.DataModel.Countries.getTopCountry() || !WazeWrap.Ready) { // // setTimeout(rsaBootstrap, 200); // // } // if (sdk.State.isReady()) { // initRSA(); // } else { // sdk.Events.once({eventName: "wme-ready"}).then(initRSA); // } // } function initRSA() { const locale = sdk.Settings.getLocale(); LANG = locale.localeCode.toLowerCase(); console.log("RSA: Initializing..."); // let UpdateObj = sdk.DataModel. require('Waze/Action/UpdateObject'); // let SetTurn = require('Waze/Model/Graph/Actions/SetTurn'); const rsaCss = [ '.rsa-wrapper {position:relative;width:100%;font-size:12px;font-family:"Rubik", "Boing-light", sans-serif;user-select:none;}', ".rsa-section-wrapper {display:block;width:100%;padding:4px;}", ".rsa-section-wrapper.border {border-bottom:1px solid grey;margin-bottom:5px;}", ".rsa-header {font-weight:bold;}", ".rsa-option-container {padding:3px;}", ".rsa-option-container.no-display {display:none;}", ".rsa-option-container.sub {margin-left:20px;}", 'input[type="checkbox"].rsa-checkbox {display:inline-block;position:relative;top:3px;vertical-align:top;margin:0;}', 'input[type="color"].rsa-color-input {display:inline-block;position:relative;width:20px;padding:0px 1px;border:0px;vertical-align:top;cursor:pointer;}', 'input[type="color"].rsa-color-input:focus {outline-width:0;}', "label.rsa-label {display:inline-block;position:relative;max-width:80%;vertical-align:top;font-weight:normal;padding-left:5px;word-wrap:break-word;}", ".group-title.toolbar-top-level-item-title.rsa:hover {cursor:pointer;}", ].join(" "); const $rsaTab = $("<div>"); $rsaTab.html = [ `<div class='rsa-wrapper' id='rsa-tab-wrapper'> <div style='margin-bottom:5px;border-bottom:1px solid black;'> <span style='font-weight:bold;'> <a href='https://www.waze.com/forum/viewtopic.php?f=1851&t=315748' target='_blank' style='text-decoration:none;'>Road Shield Assistant</a> </span> - v${GM_info.script.version} </div> <div class='rsa-option-container'> <input type=checkbox class='rsa-checkbox' id='rsa-enableScript' /> <label class='rsa-label' for='rsa-enableScript'><span id='rsa-text-enableScript'></span></label> </div> <div class='rsa-option-container'> <input type=checkbox class='rsa-checkbox' id='rsa-ShowRamps' /> <label class='rsa-label' for='rsa-ShowRamps'><span id='rsa-text-ShowRamps'></span></label> </div> <div class='rsa-option-container'> <input type=checkbox class='rsa-checkbox' id='rsa-mHPlus' /> <label class='rsa-label' for='rsa-mHPlus'><span id='rsa-text-mHPlus'></span></label> </div> <span id='rsa-text-IconHead' class='rsa-header'></span> <div style='border-top:2px solid black;'> <div class='rsa-option-container'> <input type=checkbox class='rsa-checkbox' id='rsa-ShowSegShields' /> <label class='rsa-label' for='rsa-ShowSegShields'><span id='rsa-text-ShowSegShields'></span></label> </div> <div class='rsa-option-container no-display'> <input type=checkbox class='rsa-checkbox' id='rsa-NodeShieldMissing' /> <label class='rsa-label' for='rsa-NodeShieldMissing'><span id='rsa-text-NodeShieldMissing'></span></label> </div> <div class='rsa-option-container'> <input type=checkbox class='rsa-checkbox' id='rsa-ShowNodeShields' /> <label class='rsa-label' for='rsa-ShowNodeShields'><span id='rsa-text-ShowNodeShields'></span></label> </div> <div class='rsa-option-container sub'> <input type=checkbox class='rsa-checkbox' id='rsa-ShowExitShields' /> <label class='rsa-label' for='rsa-ShowExitShields'><span id='rsa-text-ShowExitShields'></span></label> </div> <div class='rsa-option-container sub'> <input type=checkbox class='rsa-checkbox' id='rsa-ShowTurnTTS' /> <label class='rsa-label' for='rsa-ShowTurnTTS'><span id='rsa-text-ShowTurnTTS'></span></label> </div> <div class='rsa-option-container sub'> <input type=checkbox class='rsa-checkbox' id='rsa-ShowTowards' /> <label class='rsa-label' for='rsa-ShowTowards'><span id='rsa-text-ShowTowards'></span></label> </div> <div class='rsa-option-container sub'> <input type=checkbox class='rsa-checkbox' id='rsa-ShowVisualInst' /> <label class='rsa-label' for='rsa-ShowVisualInst'><span id='rsa-text-ShowVisualInst'></span></label> </div> <div class='rsa-option-container sub' style='display:none;'> <input type=checkbox class='rsa-checkbox' id='rsa-AlertTurnTTS' /> <label class='rsa-label' for='rsa-AlertTurnTTS'><span id='rsa-text-AlertTurnTTS'></span></label> </div> </div> <span id='rsa-text-HighlightHead' class='rsa-header'></span> <div style='border-top:2px solid black;'> <div class='rsa-option-container' style='display:none;'> <input type=checkbox class='rsa-checkbox' id='rsa-HighNodeShields' /> <label class='rsa-label' for='rsa-HighNodeShields'><span id='rsa-text-HighNodeShields'></span></label> </div> <div class='rsa-option-container'> <input type=checkbox class='rsa-checkbox' id='rsa-HighSegShields' /> <label class='rsa-label' for='rsa-HighSegShields'><span id='rsa-text-HighSegShields'></span></label> </div> <div class='rsa-option-container'> <input type=checkbox class='rsa-checkbox' id='rsa-SegHasDir' /> <label class='rsa-label' for='rsa-SegHasDir'><span id='rsa-text-SegHasDir'></span></label> </div> <div class='rsa-option-container'> <input type=checkbox class='rsa-checkbox' id='rsa-SegInvDir' /> <label class='rsa-label' for='rsa-SegInvDir'><span id='rsa-text-SegInvDir'></span></label> </div> <div class='rsa-option-container' id='rsa-container-titleCase'> <input type=checkbox class='rsa-checkbox' id='rsa-titleCase' /> <label class='rsa-label' for='rsa-titleCase'><span id='rsa-text-titleCase'></span></label> </div> <div class='rsa-option-container sub' id='rsa-container-checkTWD'> <input type=checkbox class='rsa-checkbox' id='rsa-checkTWD' /> <label class='rsa-label' for='rsa-checkTWD'><span id='rsa-text-checkTWD'></span></label> </div> <div class='rsa-option-container sub' id='rsa-container-checkTTS'> <input type=checkbox class='rsa-checkbox' id='rsa-checkTTS' /> <label class='rsa-label' for='rsa-checkTTS'><span id='rsa-text-checkTTS'></span></label> </div> <div class='rsa-option-container sub' id='rsa-container-checkVI'> <input type=checkbox class='rsa-checkbox' id='rsa-checkVI' /> <label class='rsa-label' for='rsa-checkVI'><span id='rsa-text-checkVI'></span></label> </div> <div class='rsa-option-container'> <input type=checkbox class='rsa-checkbox' id='rsa-SegShieldMissing' /> <label class='rsa-label' for='rsa-SegShieldMissing'><span id='rsa-text-SegShieldMissing'></span></label> </div> <div class='rsa-option-container'> <input type=checkbox class='rsa-checkbox' id='rsa-SegShieldError' /> <label class='rsa-label' for='rsa-SegShieldError'><span id='rsa-text-SegShieldError'></span></label> </div> </div> <span id='rsa-text-HighlightColors' class='rsa-header'></span> <div style='border-top:2px solid black;'> <div class='rsa-option-container'> <input type=color class='rsa-color-input' id='rsa-HighSegClr' /> <label class='rsa-label' for='rsa-HighSegClr'><span id='rsa-text-HighSegShieldsClr'></span></label> </div> <div class='rsa-option-container'> <input type=color class='rsa-color-input' id='rsa-SegHasDirClr' /> <label class='rsa-label' for='rsa-SegHasDirClr'><span id='rsa-text-SegHasDirClr'></span></label> </div> <div class='rsa-option-container'> <input type=color class='rsa-color-input' id='rsa-SegInvDirClr' /> <label class='rsa-label' for='rsa-SegInvDirClr'><span id='rsa-text-SegInvDirClr'></span></label> </div> <div class='rsa-option-container'> <input type=color class='rsa-color-input' id='rsa-MissSegClr' /> <label class='rsa-label' for='rsa-MissSegClr'><span id='rsa-text-SegShieldMissingClr'></span></label> </div> <div class='rsa-option-container'> <input type=color class='rsa-color-input' id='rsa-ErrSegClr' /> <label class='rsa-label' for='rsa-ErrSegClr'><span id='rsa-text-SegShieldErrorClr'></span></label> </div> <div class='rsa-option-container'> <input type=color class='rsa-color-input' id='rsa-HighNodeClr' /> <label class='rsa-label' for='rsa-HighNodeClr'><span id='rsa-text-HighNodeShieldsClr'></span></label> </div> <div class='rsa-option-container no-display'> <input type=color class='rsa-color-input' id='rsa-MissNodeClr' /> <label class='rsa-label' for='rsa-MissNodeClr'><span id='rsa-text-NodeShieldMissingClr'></span></label> </div> <div class='rsa-option-container' id='rsa-container-TitleCaseClr'> <input type=color class='rsa-color-input' id='rsa-TitleCaseClr' /> <label class='rsa-label' for='rsa-TitleCaseClr'><span id='rsa-text-TitleCaseClr'></span></label> </div> <div class='rsa-option-container' id='rsa-container-TitleCaseSftClr'> <input type=color class='rsa-color-input' id='rsa-TitleCaseSftClr' /> <label class='rsa-label' for='rsa-TitleCaseSftClr'><span id='rsa-text-TitleCaseSftClr'></span></label> </div> </div> <span id='rsa-text-Experimental' class='rsa-header'></span> <div style='border-top:2px solid black;'> <div class='rsa-option-container'> <input type=checkbox class='rsa-checkbox' id='rsa-AlternativeShields' /> <label class='rsa-label' for='rsa-AlternativeShields'><span id='rsa-text-AlternativeShields'></span></label> </div> <div class='rsa-option-container sub'> <input type=radio class='rsa-checkbox' value='AlternativePrimaryCity' name='AlternativeShields' id='rsa-AlternativePrimaryCity' checked/> <label class='rsa-label' for='rsa-AlternativePrimaryCity'><span id='rsa-text-AlternativePrimaryCity'></span></label> </div> <div class='rsa-option-container sub'> <input type=radio class='rsa-checkbox' value='AlternativeNoCity' name='AlternativeShields' id='rsa-AlternativeNoCity' /> <label class='rsa-label' for='rsa-AlternativeNoCity'><span id='rsa-text-AlternativeNoCity'></span></label> </div> </div> <div style='border-top:2px solid black;'> <div class='rsa-option-container'> <input type=button id='rsa-resetSettings' /> </div> </div> </div>`, ].join(" "); const $rsaFixWrapper = $('<div id="rsa-autoWrapper" class="toolbar-button ItemInactive" style="display:none;margin-right:5px;">'); const $rsaFixInner = $('<div class="group-title toolbar-top-level-item-title rsa" style="margin:5px 0 0 15px;font-size:12px;">RSA Fix</div>'); // WazeWrap.Interface.Tab('RSA', $rsaTab.html, setupOptions, 'RSA'); sdk.Sidebar.registerScriptTab().then((r) => { r.tabLabel.innerHTML = "RSA"; r.tabPane.innerHTML = $rsaTab.html; setupOptions(); }); $(`<style type="text/css">${rsaCss}</style>`).appendTo("head"); // $($rsaFixInner).appendTo($rsaFixWrapper); // $($rsaFixWrapper).appendTo($('#primary-toolbar > div')); WazeWrap.Interface.ShowScriptUpdate(GM_info.script.name, GM_info.script.version, RSA_UPDATE_NOTES, GF_LINK, FORUM_LINK); console.log("RSA: loaded"); } function processAlternativeSettings() { if (rsaSettings.AlternativeShields) { const alt_primary = $("#rsa-AlternativePrimaryCity"); alt_primary.prop("disabled", false); const alt_nocity = $("#rsa-AlternativeNoCity"); alt_nocity.prop("disabled", false); const primaryCityButton = alt_primary[0]; const noCityButton = alt_primary[0]; if (primaryCityButton.checked) { alternativeType = primaryCityButton.value; } if (noCityButton.checked) { alternativeType = noCityButton.value; } } toggleAlternativeShields(); } function getId(ele) { return document.getElementById(ele); } function setChecked(ele, status) { $(`#${ele}`).prop("checked", status); } function setValue(ele, value) { const inputElem = $(`#${ele}`); inputElem.attr("value", value); // inputElem.css('border', `1px solid ${value}`); } function toggleAlternativeShields() { if (!rsaSettings.AlternativeShields) { $("#rsa-AlternativePrimaryCity").prop("disabled", true); $("#rsa-AlternativeNoCity").prop("disabled", true); } } function applyPointLabel(properties) { return properties.styleName === "pointLabelStyle"; } function applyShield(properties) { return properties.styleName === "shield"; } function applySegHighlight(properties) { return properties.styleName === "segHighlight"; } function applyStyleNode(properties) { return properties.styleName === "styleNode"; } function applyStyleLabel(properties) { return properties.styleName === "styleLabel"; } function updateMap() { removeAutoFixButton(); tryScan(); checkOptions(); } async function setupOptions() { await loadSettings(); // Create OL layer for display sdk.Map.addLayer({ layerName: rsaMapLayer.layerName, styleRules: styleConfig.styleRules, styleContext: styleConfig.styleContext, }); sdk.LayerSwitcher.addLayerCheckbox({ name: rsaMapLayer.layerName }); sdk.LayerSwitcher.setLayerCheckboxChecked({ name: rsaMapLayer.layerName, isChecked: rsaSettings.mapLayerVisible, }); sdk.Map.setLayerVisibility({ layerName: rsaMapLayer.layerName, visibility: rsaSettings.mapLayerVisible }); sdk.Map.addLayer({ layerName: rsaIconLayer.layerName, styleRules: styleConfig.styleRules, styleContext: styleConfig.styleContext, }); sdk.LayerSwitcher.addLayerCheckbox({ name: rsaIconLayer.layerName }); sdk.Map.setLayerVisibility({ layerName: rsaIconLayer.layerName, visibility: rsaSettings.iconLayerVisible }); sdk.LayerSwitcher.setLayerCheckboxChecked({ name: rsaIconLayer.layerName, isChecked: rsaSettings.iconLayerVisible, }); sdk.Events.on({ eventName: "wme-layer-checkbox-toggled", eventHandler: (payload) => { sdk.Map.setLayerVisibility({ layerName: payload.name, visibility: payload.checked }); if (payload.name === rsaMapLayer.layerName) { rsaSettings.mapLayerVisible = payload.checked; } else if (payload.name === rsaIconLayer.layerName) { rsaSettings.iconLayerVisible = payload.checked; } if (payload.checked) tryScan(); saveSettings(); }, }); // Set user options function setEleStatus() { setChecked("rsa-enableScript", rsaSettings.enableScript); setChecked("rsa-HighSegShields", rsaSettings.HighSegShields); setChecked("rsa-ShowSegShields", rsaSettings.ShowSegShields); setChecked("rsa-SegShieldMissing", rsaSettings.SegShieldMissing); setChecked("rsa-SegShieldError", rsaSettings.SegShieldError); setChecked("rsa-HighNodeShields", rsaSettings.HighNodeShields); setChecked("rsa-ShowNodeShields", rsaSettings.ShowNodeShields); setChecked("rsa-ShowExitShields", rsaSettings.ShowExitShields); setChecked("rsa-ShowTurnTTS", rsaSettings.ShowTurnTTS); setChecked("rsa-AlertTurnTTS", rsaSettings.AlertTurnTTS); setChecked("rsa-ShowTowards", rsaSettings.ShowTowards); setChecked("rsa-ShowVisualInst", rsaSettings.ShowVisualInst); setChecked("rsa-NodeShieldMissing", rsaSettings.NodeShieldMissing); setChecked("rsa-SegHasDir", rsaSettings.SegHasDir); setChecked("rsa-SegInvDir", rsaSettings.SegInvDir); setChecked("rsa-ShowRamps", rsaSettings.ShowRamps); setChecked("rsa-mHPlus", rsaSettings.mHPlus); setChecked("rsa-titleCase", rsaSettings.titleCase); setChecked("rsa-checkTWD", rsaSettings.checkTWD); setChecked("rsa-checkTTS", rsaSettings.checkTTS); setChecked("rsa-checkVI", rsaSettings.checkVI); setChecked("rsa-AlternativeShields", rsaSettings.AlternativeShields); setValue("rsa-HighSegClr", rsaSettings.HighSegClr); setValue("rsa-MissSegClr", rsaSettings.MissSegClr); setValue("rsa-ErrSegClr", rsaSettings.ErrSegClr); setValue("rsa-HighNodeClr", rsaSettings.HighNodeClr); setValue("rsa-MissNodeClr", rsaSettings.MissNodeClr); setValue("rsa-SegHasDirClr", rsaSettings.SegHasDirClr); setValue("rsa-SegInvDirClr", rsaSettings.SegInvDirClr); setValue("rsa-TitleCaseClr", rsaSettings.TitleCaseClr); setValue("rsa-TitleCaseSftClr", rsaSettings.TitleCaseSftClr); $("#rsa-AlternativeShields").on("change", (e) => { processAlternativeSettings(); }); if (rsaSettings.titleCase && sdk.DataModel.Countries.getTopCountry()?.id === 235) { $("#rsa-container-checkTWD").css("display", "block"); $("#rsa-container-checkTTS").css("display", "block"); $("#rsa-container-checkVI").css("display", "block"); } else { $("#rsa-container-checkTWD").css("display", "none"); $("#rsa-container-checkTTS").css("display", "none"); $("#rsa-container-checkVI").css("display", "none"); } toggleAlternativeShields(); } // Register event listeners // WazeWrap.Events.register('selectionchanged', null, removeAutoFixButton); sdk.Events.on({ eventName: "wme-selection-changed", eventHandler: removeAutoFixButton }); // WazeWrap.Events.register('selectionchanged', null, tryScan); sdk.Events.on({ eventName: "wme-map-move-end", eventHandler: updateMap }); sdk.Events.on({ eventName: "wme-map-zoom-changed", eventHandler: updateMap }); sdk.Shortcuts.createShortcut({ callback: addShieldClick, description: "Activates the Add Shield Button", shortcutId: "addShield", shortcutKeys: "A+83", }); // new WazeWrap.Interface.Shortcut('addShield', // 'Activates the Add Shield Button', // 'wmersa', // 'Road Shield Assistant', // rsaSettings.addShield, // addShieldClick, null).add(); setEleStatus(); $("input[type=radio][name=AlternativeShields]").on("change", () => { processAlternativeSettings(); saveSettings(); removeHighlights(); tryScan(); }); $(".rsa-checkbox").on("change", function () { const settingName = $(this)[0].id.substring(4); rsaSettings[settingName] = this.checked; // Check to ensure highlight nodes and show node shields don't overlap each other // if (settingName = 'ShowNodeShields') { // if (this.checked) { // $('rsa-HighNodeShields').prop('checked', false); // rsaSettings.HighNodeShields = false; // } // } else if (settingName = 'HighNodeShields') { // if (this.checked) { // $('rsa-ShowNodeShields').prop('checked', false); // rsaSettings.ShowNodeShields = false; // } // } if (settingName === "AlternativeShields") processAlternativeSettings(); saveSettings(); removeHighlights(); tryScan(); }); $(".rsa-color-input").on("change", function () { const settingName = $(this)[0].id.substring(4); rsaSettings[settingName] = this.value; saveSettings(); setEleStatus(); removeHighlights(); tryScan(); }); $("#rsa-titleCase").trigger("click", () => { const titleCase = getId("rsa-titleCase"); if (titleCase?.checked) { $("#rsa-container-checkTWD").css("display", "block"); $("#rsa-container-checkTTS").css("display", "block"); $("#rsa-container-checkVI").css("display", "block"); } else { $("#rsa-container-checkTWD").css("display", "none"); $("#rsa-container-checkTTS").css("display", "none"); $("#rsa-container-checkVI").css("display", "none"); } }); // $('#rsa-ShowNodeShields').click(function() { // if (!getId('rsa-ShowNodeShields').checked) $('.rsa-option-container.sub').hide(); // else $('.rsa-option-container.sub').show(); // }); $("#rsa-resetSettings").on("click", () => { const defaultSettings = { lastSaveAction: 0, enableScript: true, HighSegShields: false, ShowSegShields: true, SegShieldMissing: false, SegShieldError: false, SegHasDir: false, SegInvDir: false, HighNodeShields: true, ShowNodeShields: false, ShowExitShields: false, ShowTurnTTS: false, AlertTurnTTS: false, ShowTowards: false, ShowVisualInst: false, NodeShieldMissing: false, HighSegClr: "#0066ff", MissSegClr: "#00ff00", ErrSegClr: "#cc00ff", HighNodeClr: "#ff00bf", MissNodeClr: "#ff0000", SegHasDirClr: "#ffff00", SegInvDirClr: "#66ffff", TitleCaseClr: "#ff9933", TitleCaseSftClr: "#ffff66", ShowRamps: true, AlternativeShields: false, mHPlus: false, titleCase: false, checkTWD: false, checkTTS: false, checkVI: false, mapLayerVisible: false, iconLayerVisible: false, }; rsaSettings = defaultSettings; saveSettings(); setEleStatus(); }); // Add translated UI text if (!Strings[LANG]) LANG = "en"; const messageKeys = Object.keys(Strings[LANG]); for (let i = 0; i < messageKeys.length; i++) { const key = messageKeys[i]; $(`#rsa-text-${key}`).text(Strings[LANG][key]); } $("#rsa-resetSettings").attr("value", Strings[LANG].resetSettings); checkOptions(); } async function loadSettings() { const localSettings = JSON.parse(localStorage.getItem("RSA_Settings")); const serverSettings = await WazeWrap.Remote.RetrieveSettings("RSA_Settings"); if (!serverSettings) { console.error("RSA: Error communicating with WW settings server"); } const defaultSettings = { lastSaveAction: 0, enableScript: true, HighSegShields: false, ShowSegShields: true, SegShieldMissing: false, SegShieldError: false, SegHasDir: false, SegInvDir: false, HighNodeShields: true, ShowNodeShields: false, ShowExitShields: false, ShowTurnTTS: false, AlertTurnTTS: false, ShowTowards: false, ShowVisualInst: false, NodeShieldMissing: false, HighSegClr: "#0066ff", MissSegClr: "#00ff00", ErrSegClr: "#cc00ff", HighNodeClr: "#ff00bf", MissNodeClr: "#ff0000", SegHasDirClr: "#ffff00", SegInvDirClr: "#66ffff", TitleCaseClr: "#ff9933", TitleCaseSftClr: "#ffff66", ShowRamps: true, AlternativeShields: false, mHPlus: false, titleCase: false, checkTWD: false, checkTTS: false, checkVI: false, mapLayerVisible: false, iconLayerVisible: false, }; rsaSettings = $.extend({}, defaultSettings, localSettings); if (serverSettings && serverSettings.lastSaveAction > rsaSettings.lastSaveAction) { $.extend(rsaSettings, serverSettings); // console.log('RSA: server settings used'); } else { // console.log('RSA: local settings used'); } } async function saveSettings() { const { enableScript, HighSegShields, ShowSegShields, SegShieldMissing, SegShieldError, HighNodeShields, ShowNodeShields, ShowExitShields, SegHasDir, SegInvDir, ShowTurnTTS, AlertTurnTTS, ShowTowards, ShowVisualInst, NodeShieldMissing, HighSegClr, MissSegClr, ErrSegClr, HighNodeClr, MissNodeClr, SegHasDirClr, SegInvDirClr, TitleCaseClr, TitleCaseSftClr, ShowRamps, AlternativeShields, mHPlus, titleCase, checkTWD, checkTTS, checkVI, mapLayerVisible, iconLayerVisible, } = rsaSettings; const localSettings = { lastSaveAction: Date.now(), enableScript, HighSegShields, ShowSegShields, SegShieldMissing, SegShieldError, HighNodeShields, ShowNodeShields, ShowExitShields, SegHasDir, SegInvDir, ShowTurnTTS, AlertTurnTTS, ShowTowards, ShowVisualInst, NodeShieldMissing, HighSegClr, MissSegClr, ErrSegClr, HighNodeClr, MissNodeClr, SegHasDirClr, SegInvDirClr, TitleCaseClr, TitleCaseSftClr, ShowRamps, AlternativeShields, mHPlus, titleCase, checkTWD, checkTTS, checkVI, mapLayerVisible, iconLayerVisible, }; // Grab keyboard shortcuts and store them for saving // for (const name in W.accelerators.Actions) { // const {shortcut, group} = W.accelerators.Actions[name]; // if (group === 'wmersa') { // let TempKeys = ''; // if (shortcut) { // if (shortcut.altKey === true) { // TempKeys += 'A'; // } // if (shortcut.shiftKey === true) { // TempKeys += 'S'; // } // if (shortcut.ctrlKey === true) { // TempKeys += 'C'; // } // if (TempKeys !== '') { // TempKeys += '+'; // } // if (shortcut.keyCode) { // TempKeys += shortcut.keyCode; // } // } else { // TempKeys = '-1'; // } // localSettings[name as keyof typeof localSettings] = TempKeys; // } // } // Required for the instant update of changes to the keyboard shortcuts on the UI rsaSettings = localSettings; if (localStorage) { localStorage.setItem("RSA_Settings", JSON.stringify(localSettings)); } const serverSave = await WazeWrap.Remote.SaveSettings("RSA_Settings", localSettings); if (serverSave === null) { console.warn("RSA: User PIN not set in WazeWrap tab"); } else { if (serverSave === false) { console.error("RSA: Unable to save settings to server"); } } } function checkOptions() { const countries = sdk.DataModel.Countries.getAll(); // const countries = W.model.countries.getObjectArray(); if (countries.length < 1) { setTimeout(() => { checkOptions(); }, 500); return; } let allowFeat = false; for (let i = 0; i < countries.length; i++) { if (RoadAbbr[countries[i].id]) allowFeat = true; } const segShieldMissing = $("#rsa-SegShieldMissing"); const segShieldError = $("#rsa-SegShieldError"); const nodeShieldMissing = $("#rsa-NodeShieldMissing"); const textSegShieldMissing = $("#rsa-text-SegShieldMissing"); const textSegShieldError = $("#rsa-text-SegShieldError"); const textNodeShieldMissing = $("#rsa-text-NodeShieldMissing"); if (!allowFeat) { textSegShieldMissing.prop("checked", false); textSegShieldError.prop("checked", false); textNodeShieldMissing.prop("checked", false); textSegShieldMissing.text(`${Strings[LANG].SegShieldMissing} ${Strings[LANG].disabledFeat}`); textSegShieldError.text(`${Strings[LANG].SegShieldError} ${Strings[LANG].disabledFeat}`); textNodeShieldMissing.text(`${Strings[LANG].NodeShieldMissing} ${Strings[LANG].disabledFeat}`); segShieldMissing.prop("disabled", true); segShieldError.prop("disabled", true); nodeShieldMissing.prop("disabled", true); rsaSettings.SegShieldMissing = false; rsaSettings.SegShieldError = false; rsaSettings.NodeShieldMissing = false; saveSettings(); } else { textSegShieldMissing.prop("checked", rsaSettings.SegShieldMissing); textSegShieldError.prop("checked", rsaSettings.SegShieldError); textNodeShieldMissing.prop("checked", rsaSettings.NodeShieldMissing); textSegShieldMissing.text(Strings[LANG].SegShieldMissing); textSegShieldError.text(Strings[LANG].SegShieldError); textNodeShieldMissing.text(Strings[LANG].NodeShieldMissing); segShieldMissing.prop("disabled", false); segShieldError.prop("disabled", false); nodeShieldMissing.prop("disabled", false); } const topCountry = sdk.DataModel.Countries.getTopCountry(); if (topCountry === null || topCountry.id !== 235) { $("#rsa-container-titleCase").css("display", "none"); $("#rsa-container-TitleCaseClr").css("display", "none"); $("#rsa-container-TitleCaseSftClr").css("display", "none"); } else { $("#rsa-container-titleCase").css("display", "block"); $("#rsa-container-TitleCaseClr").css("display", "block"); $("#rsa-container-TitleCaseSftClr").css("display", "block"); } } function autoFixButton() { $("#rsa-autoWrapper").css("display", "inline-block"); $("#rsa-autoWrapper > div").off(); // console.log(BadNames); // Create function to fix case types when button clicked $("#rsa-autoWrapper > div").on("click", () => { // const turnGraph = W.model.getTurnGraph(); const turnGraph = sdk.DataModel.Turns.getAll(); for (let i = 0; i < BadNames.length; i++) { // Check if street or turn if (BadNames[i]) { const strt = BadNames[i]; let dir = strt.direction; if (dir !== null) { if (dir.match(/\b(north)\b/i) != null) dir = "Nᴏʀᴛʜ"; if (dir.match(/\b(south)\b/i) != null) dir = "Sᴏᴜᴛʜ"; if (dir.match(/\b(east)\b/i) != null) dir = "Eᴀꜱᴛ"; if (dir.match(/\b(west)\b/i) != null) dir = "Wᴇꜱᴛ"; W.model.actionManager.add(new UpdateObj(strt, { direction: dir })); } } else { function fixName(name) { let temp = name; temp = temp.replace(/\b(north)\b/gi, "Nᴏʀᴛʜ"); temp = temp.replace(/\b(south)\b/gi, "Sᴏᴜᴛʜ"); temp = temp.replace(/\b(east)\b/gi, "Eᴀꜱᴛ"); temp = temp.replace(/\b(west)\b/gi, "Wᴇꜱᴛ"); temp = temp.replace(/\b(TO)\b/gi, "ᴛᴏ"); temp = temp.replace(/\b(VIA)\b/gi, "ᴠɪᴀ"); temp = temp.replace(/\b(JCT)\b/gi, "ᴊᴄᴛ"); return temp; } const turn = BadNames[i]; let turnDat = turn.getTurnData(); const turnGuid = turnDat.getTurnGuidance(); // let newGuid = turnGuid; console.log(turn); for (const s in turnGuid.roadShields) { turnGuid.roadShields[s].direction = fixName(turnGuid.roadShields[s].direction); } if (rsaSettings.checkTWD && turnGuid.towards) turnGuid.towards = fixName(turnGuid.towards); if (rsaSettings.checkTTS && turnGuid.tts) turnGuid.tts = fixName(turnGuid.tts); if (rsaSettings.checkVI && turnGuid.visualInstruction) turnGuid.visualInstruction = fixName(turnGuid.visualInstruction); console.log(turnGuid); turnDat = turnDat.withTurnGuidance(turnGuid); W.model.actionManager.add(new SetTurn(turnGraph, turn.withTurnData(turnDat))); } } }); } function removeAutoFixButton() { $("#rsa-autoWrapper > div").off(); $("#rsa-autoWrapper").css("display", "none"); } function addShieldClick() { // const selFea = W.selectionManager.getSelectedFeatures(); const selFea = sdk.Editing.getSelection(); if (selFea && selFea.objectType === "segment") { $(".add-new-road-shield").trigger("click"); } else { WazeWrap.Alerts.error(GM_info.script.name, "You must have only 1 segment selected to use the shield editing menu"); } } function tryScan() { if (!rsaSettings.enableScript) return; // Reset the array of objects that need names fixed BadNames = []; removeHighlights(); if (sdk.Map.getZoomLevel() <= MIN_ZOOM_LEVEL) return; // let selFea = W.selectionManager.getSelectedFeatures(); // Scan all segments on screen if (rsaSettings.ShowSegShields || rsaSettings.SegShieldMissing || rsaSettings.SegShieldError || rsaSettings.HighSegShields || rsaSettings.titleCase) { // _.each(W.model.segments.getObjectArray(), s => { // scanSeg(s); // } for (const s of sdk.DataModel.Segments.getAll()) { processSeg(s); } } // Scan all nodes on screen if (rsaSettings.HighNodeShields || rsaSettings.ShowNodeShields || rsaSettings.titleCase) { const nodeSet = new Set(sdk.DataModel.Nodes.getAll()); for (const n of nodeSet) { processNode(n); } } } const majorRoads = new Set([3, 4, 5, 6]); function processSeg(seg) { if ((!rsaSettings.ShowRamps && seg.roadType === 4) || (rsaSettings.mHPlus && !majorRoads.has(seg.roadType))) return; // let segAtt = seg.attributes; // let streetID = segAtt.primaryStreetID; // const streetID: number | null = seg.primaryStreetId; // if (streetID === null) return; // // let oldStreet = W.model.streets.getObjectById(streetID).attributes; // let street: Street | null = sdk.DataModel.Streets.getById({ streetId: streetID }); // if (street === null || street.cityId === null) return; // const city: City | null = sdk.DataModel.Cities.getById({ cityId: street.cityId }); // if (city === null) return; // const stateID = city.stateId; let address = sdk.DataModel.Segments.getAddress({ segmentId: seg.id }); if (rsaSettings.AlternativeShields) { for (const altAddress of address.altStreets) { // let oldAltStreet = W.model.streets.getObjectById(segAtt.streetIDs[i]).attributes; if (alternativeType === "AlternativePrimaryCity") { if (altAddress.city !== null) { address = altAddress; break; } } if (alternativeType === "AlternativeNoCity") { if (altAddress.city?.name === "") { address = altAddress; break; } } } } // let oldStateName = W.model.states.getObjectById(cityID.stateID).attributes.name; const stateName = address.state === null ? "" : address.state.name; const countryID = address.country?.id; const candidate = isSegmentCandidate(address, stateName, countryID); // Display shield on map function checkDeclutterSettings(seg) { let result = false; const zoomLevel = sdk.Map.getZoomLevel(); if (zoomLevel > MIN_ZOOM_LEVEL) { if (seg.length > minShieldDisplayLengths[zoomLevel]) { result = true; } } return result; } if (address.street !== null && address.street.signType !== null) { if (rsaSettings.ShowSegShields && checkDeclutterSettings(seg)) { displaySegShields(seg, address.street.signType, address.street.signText, address.street.direction); } // If candidate and has shield if (rsaSettings.HighSegShields && candidate.isCandidate) { if (isValidShield(seg, candidate.iconID)) { createHighlight(seg, rsaSettings.HighSegClr); } else { createHighlight(seg, rsaSettings.ErrSegClr); } } // If not candidate and has shield if (rsaSettings.SegShieldError && !candidate.isCandidate) createHighlight(seg, rsaSettings.ErrSegClr); if (rsaSettings.SegHasDir && address.street?.direction) createHighlight(seg, rsaSettings.SegHasDirClr); // Highlight seg shields with direction if (rsaSettings.SegInvDir && !address.street?.direction) createHighlight(seg, rsaSettings.SegInvDirClr); } // If candidate and missing shield if (rsaSettings.SegShieldMissing && candidate.isCandidate && address.street !== null && address.street.signType === null) createHighlight(seg, rsaSettings.MissSegClr); // Streets without capitalized letters if (rsaSettings.titleCase) { const badName = matchTitleCase(address.street); if (badName) { createHighlight(seg, rsaSettings.TitleCaseClr, true); // autoFixButton(); } } } function processNode(node) { if (node === null) return; const guidance = { tts: false, visual: false, exit: false, shield: false, towards: false, }; const turns = sdk.DataModel.Turns.getTurnsThroughNode({ nodeId: node.id }); for (const turn of turns) { if (!turn.isAllowed) continue; // let oldTurn = W.model.getTurnGraph().getTurnThroughNode(node,turn.fromSegmentId,turn.toSegmentId); guidance.tts = guidance.tts || turn.hasCustomTTS; guidance.shield = guidance.shield || turn.hasShieldsPopulated; guidance.towards = guidance.towards || turn.hasTowardsGuidance; guidance.visual = guidance.visual || turn.hasVisualInstruction; if (rsaSettings.titleCase) { const badName = matchTitleCaseThroughNode(turn); if (badName.isBad) { const color = badName.softIssue ? rsaSettings.TitleCaseSftClr : rsaSettings.TitleCaseClr; createHighlight(node, color, true); // autoFixButton(); } } } if (rsaSettings.ShowNodeShields && sdk.Map.getZoomLevel() > ZoomLevel.ZM2 && (guidance.exit || guidance.tts || guidance.shield || guidance.visual || guidance.towards)) displayNodeIcons(node, guidance); } // Function written by kpouer to accommodate French conventions of shields being based on alt names function isSegmentCandidate(address, stateName, countryId) { let candidate = isStreetCandidate(address.street, stateName, countryId); if (!candidate.isCandidate && address.country !== null && address.country?.id !== undefined && CheckAltName.has(address.country.id)) { for (const altAddress of address.altStreets) { candidate = isStreetCandidate(altAddress.street, stateName, countryId); if (candidate.isCandidate) { return candidate; } } } return candidate; } function isStreetCandidate(street, stateName, countryId) { const info = { isCandidate: false, iconID: null }; if (street === null || countryId === null || countryId === undefined || !RoadAbbr[countryId]) { return info; } // if (stateName === null) stateName = ""; //Check to see if the country has states configured in RSA by looking for a key with nothing in it if (street.name) { const noStates = "" in RoadAbbr[countryId]; const abbrvs = noStates ? RoadAbbr[countryId][""] : { ...RoadAbbr[countryId][stateName], ...RoadAbbr[countryId]["*"] }; const abbreviationKeys = Object.keys(abbrvs); for (let i = 0; i < abbreviationKeys.length; i++) { const abrKey = abbreviationKeys[i]; const abbr = new RegExp(abrKey, "g"); const isMatch = street.name.match(abbr); if (isMatch && street.name.includes(isMatch[0])) { info.isCandidate = true; info.iconID = abbrvs[abrKey]; break; } } } return info; } function iconTextValidation(signType, signText, iconId) { let result = true; if (signType === null || typeof signType === "undefined" || typeof signText === "undefined" || (iconId instanceof Set && !iconId.has(signType)) || (!(iconId instanceof Set) && signType !== iconId)) { result = false; } if (signType !== null && !iconsAllowingNoText.has(signType) && (signText === null || typeof signText === "undefined" || signText === "")) { result = false; } return result; } function isValidShield(seg, iconID) { // let primaryStreet = W.model.streets.getObjectById(segAtt.primaryStreetID); if (seg === null || seg.primaryStreetId === null) return false; const primaryStreet = sdk.DataModel.Streets.getById({ streetId: seg.primaryStreetId }); if (primaryStreet === null || primaryStreet.signText === null || !iconTextValidation(primaryStreet.signType, primaryStreet.signText, iconID)) return false; if (primaryStreet.name?.includes(primaryStreet.signText)) { return true; } for (let i = 0; i < seg.alternateStreetIds.length; i++) { const street = sdk.DataModel.Streets.getById({ streetId: seg.alternateStreetIds[i] }); if (street?.name?.includes(primaryStreet.signText)) { return true; } } return false; } function matchTitleCase(street) { if (!street) return; const dir = street.direction; let isBad = false; if (dir !== "" && dir !== null) { // console.log(dir); if (dir.match(/\\b(north|south|east|west)\\b/i) !== null) isBad = true; if (dir.match(/([ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘʀꜱᴛᴜᴠᴡʏᴢ][a-z]|[a-z][ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘʀꜱᴛᴜᴠᴡʏᴢ])/) !== null) isBad = true; if (isBad) { if (BadNames.length === 0) { BadNames.push(street); } else { let isDuplicate = false; for (let i = 0; i < BadNames.length; i++) { // if (BadNames[i].type) console.log(BadNames[i].id === street.id); if (typeof BadNames[i] && BadNames[i].id === street.id) isDuplicate = true; } if (!isDuplicate) BadNames.push(street); } } } return isBad; } function matchTitleCaseThroughNode(turn) { const info = { isBad: false, softIssue: false }; return info; const turnGuid = turnData.getTurnGuidance(); const shields = turnGuid.getRoadShields(); const twd = turnGuid.getTowards(); const tts = turnGuid.getTTS(); const VI = turnGuid.getVisualInstruction(); function checkText(txt, isSoft = false) { if (txt !== "" && txt !== null) { if (txt.match(/\b(north|south|east|west)\b/i) != null) { info.isBad = true; if (isSoft) info.softIssue = true; } if (txt.match(/\b(TO|VIA|JCT)\b/i) != null) { info.isBad = true; if (isSoft) info.softIssue = true; } if (txt.match(/([ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘʀꜱᴛᴜᴠᴡʏᴢ][a-z]|[a-z][ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘʀꜱᴛᴜᴠᴡʏᴢ])/) != null) { info.isBad = true; if (isSoft) info.softIssue = true; } } } function checkTTStext(txt, isSoft = false) { if (txt !== "" && txt !== null) { if (txt.match(/(Nᴏʀᴛʜ|Sᴏᴜᴛʜ|Eᴀꜱᴛ|Wᴇꜱᴛ)/) != null) { info.isBad = true; if (isSoft) info.softIssue = true; } if (txt.match(/(ᴛᴏ|ᴠɪᴀ|ᴊᴄᴛ)/) != null) { info.isBad = true; if (isSoft) info.softIssue = true; } if (txt.match(/([ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘʀꜱᴛᴜᴠᴡʏᴢ][a-z]|[a-z][ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘʀꜱᴛᴜᴠᴡʏᴢ])/) != null) { info.isBad = true; if (isSoft) info.softIssue = true; } } } if (shields) { _.each(shields, (s) => { checkText(s.direction); }); } if (twd && twd !== "" && rsaSettings.checkTWD) checkText(twd, true); if (tts && tts !== "" && rsaSettings.checkTTS) checkTTStext(tts, true); if (VI && VI !== "" && rsaSettings.checkVI) checkText(VI, true); if (info.isBad) BadNames.push(turn); return info; } function displayNodeIcons(node, guidance) { const GUIDANCE = { shields: { setting: "ShowNodeShields", exists: guidance.shield, color: "", width: 30, height: 30, sign: "6", txt: "TG", }, exitsign: { setting: "ShowExitShields", exists: guidance.exit, color: "", width: 30, height: 20, sign: "2159", txt: "EX", }, tts: { setting: "ShowTurnTTS", exists: guidance.tts, color: "", width: 30, height: 30, sign: "7", txt: "TIO", }, towards: { setting: "ShowTowards", exists: guidance.towards, color: "", width: 30, height: 30, sign: "7", txt: "TW", }, visualIn: { setting: "ShowVisualInst", exists: guidance.visual, color: "", width: 30, height: 30, sign: "7", txt: "VI", }, }; let count = 0; const pixelPos = proj4("EPSG:4326", "EPSG:3857", node.geometry.coordinates); const startPoint = { x: pixelPos[0], y: pixelPos[1] }; const lblStart = { x: startPoint.x - labelDistance().label, y: startPoint.y + labelDistance().label }; // Array of points for line connecting node to icons const points = []; const pointCoordinates = []; // Point coords // let pointNode = new OpenLayers.Geometry.Point(startPoint.x, startPoint.y); const pointNode = turf.point(node.geometry.coordinates, { styleName: "styleNode", style: { strokeColor: rsaSettings.HighNodeClr, strokeOpacity: 0.75, strokeWidth: 4, fillColor: rsaSettings.HighNodeClr, fillOpacity: 0.75, pointRadius: 3, }, }, { id: `node_${startPoint.x} ${startPoint.y}` }); points.push(pointNode); pointCoordinates.push(node.geometry.coordinates); // Label coords // var pointLabel = new OpenLayers.Geometry.Point(lblStart.x, lblStart.y); const nodeLabelCoordinates = proj4("EPSG:3857", "EPSG:4326", [lblStart.x, lblStart.y]); const nodeLabel = turf.point(nodeLabelCoordinates, { styleName: "styleNode", style: { strokeColor: rsaSettings.HighNodeClr, strokeOpacity: 0.75, strokeWidth: 4, fillColor: rsaSettings.HighNodeClr, fillOpacity: 0.75, pointRadius: 3, }, }, { id: `pointNode_${startPoint.x} ${startPoint.y}` }); points.push(nodeLabel); pointCoordinates.push(nodeLabelCoordinates); sdk.Map.addFeaturesToLayer({ features: points, layerName: rsaMapLayer.layerName }); const newLine = turf.lineString(pointCoordinates, { styleName: "styleNode", style: { strokeColor: rsaSettings.HighNodeClr, strokeOpacity: 0.75, strokeWidth: 4, fillColor: rsaSettings.HighNodeClr, fillOpacity: 0.75, pointRadius: 3, }, }, { id: `line_${points[0].toString()}` }); sdk.Map.addFeatureToLayer({ feature: newLine, layerName: rsaIconLayer.layerName }); _.each(GUIDANCE, (q) => { if (q.exists && rsaSettings[q.setting]) { // console.log(q); let xpoint = lblStart.x; let ypoint = lblStart.y; const lblDis = labelDistance(); switch (count) { case 1: xpoint = lblStart.x + lblDis.icon; ypoint = lblStart.y; break; case 2: xpoint = lblStart.x; ypoint = lblStart.y - lblDis.icon; break; case 3: xpoint = lblStart.x + lblDis.icon; ypoint = lblStart.y - lblDis.icon; break; case 4: xpoint = lblStart.x + lblDis.icon * 2; ypoint = lblStart.y; break; default: break; } // Label coords // let pointLabel = new OpenLayers.Geometry.Point(xpoint, ypoint); // labelFeat = new OpenLayers.Feature.Vector(pointLabel, null, styleLabel); const pointLabelFeature = turf.point(proj4("EPSG:3857", "EPSG:4326", [xpoint, ypoint]), { styleName: "styleLabel", style: { sign: q.sign, txt: q.txt, height: q.height, width: q.width, fillOpacity: 1 }, }, { id: `pointLabel_${xpoint.toString()}_${ypoint.toString()}` }); sdk.Map.addFeatureToLayer({ feature: pointLabelFeature, layerName: rsaIconLayer.layerName }); count++; } }); } function displaySegShields(segment, shieldID, shieldText, shieldDir) { const iconURL = `https://renderer-am.waze.com/renderer/v1/signs/${shieldID}?text=${shieldText}`; // let SegmentPoints = []; const oldparam = { x: null, y: null }; const labelDis = labelDistance(); let width = 37; let height = 37; if (shieldText !== null) { if (shieldText.length > 4 && shieldText.length < 7) { width = 50; height = 40; } else if (shieldText.length > 6 && shieldText.length < 9) { width = 80; height = 45; } else if (shieldText.length > 8 && shieldText.length < 13) { width = 100; height = 50; } } // oldparam.x = null; // oldparam.y = null; let AtLeastOne = false; $.each(segment.geometry.coordinates, (idx, param) => { const pointParam = proj4("EPSG:4326", "EPSG:3857", param); // Build a new segment with same geometry // SegmentPoints.push(new OpenLayers.Geometry.Point(param[0], param[1])); // let newPoint = { // type: "Feature", // geometry: { // type: "Point", // coordinates: [param[0], param[1]], // }, // id: "point_" + param[0].toString() + " " + param[1].toString(), // }; // SegmentPoints.push(newPoint); // let shieldWithLabelStyle = { // externalGraphic: iconURL, // graphicWidth: width, // graphicHeight: height, // graphicYOffset: -20, // // graphicZIndex: 6000, // style: "opacity: 1", // fillOpacity: 1, // fill: "black", // stroke: "black", // label: shieldDir !== null ? shieldDir : "", // fontColor: "green", // labelOutlineColor: "white", // labelOutlineWidth: 1, // fontSize: 12, // display: "grid", // labelYOffset: 0, // }; if (oldparam.x && oldparam.y && oldparam.x !== null && oldparam.y !== null) { if (Math.abs(oldparam.x - pointParam[0]) > labelDis.space || Math.abs(oldparam.y - pointParam[1]) > labelDis.space || !AtLeastOne) { const centerparam = { x: undefined, y: undefined }; centerparam.x = (oldparam.x + pointParam[0]) / 2; centerparam.y = (oldparam.y + pointParam[1]) / 2; if ((centerparam.x && Math.abs(centerparam.x - pointParam[0]) > labelDis.space) || (centerparam.y && Math.abs(centerparam.y - pointParam[1]) > labelDis.space) || !AtLeastOne) { // let LabelPoint = new OpenLayers.Geometry.Point(centerparam.x, centerparam.y); // const pointFeature = new OpenLayers.Feature.Vector(LabelPoint, null, style); const coordCenterPoint = proj4("EPSG:3857", "EPSG:4326", [centerparam.x, centerparam.y]); const shieldFeature = turf.point(coordCenterPoint, { styleName: "shield", style: { externalGraphic: iconURL, graphicWidth: width, graphicHeight: height, label: shieldDir !== null ? shieldDir : "", labelYOffset: shieldDir !== null ? -20 : 0, }, }, { id: `shield_${centerparam.x.toString()}_${centerparam.y.toString()}` }); // Shield icon style // shieldWithLabelStyle.labelYOffset = -1 * labelDis.label; sdk.Map.addFeatureToLayer({ feature: shieldFeature, layerName: rsaIconLayer.layerName }); AtLeastOne = true; } } } oldparam.x = pointParam[0]; oldparam.y = pointParam[1]; }); } function createHighlight(obj, color, overSized = false) { // const geo = obj.getOLGeometry().clone(); const geo = structuredClone(obj.geometry); const isNode = obj instanceof Node; if (isNode) { // Point coords // let pointNode = new OpenLayers.Geometry.Point(geo.x, geo.y); const pointFeature = turf.point(geo.coordinates, { styleName: "styleNode", style: { strokeColor: color, strokeOpacity: overSized ? 1 : 0.75, strokeWidth: 4, fillColor: color, fillOpacity: 0.75, pointRadius: overSized ? 7 : 3, }, }, { id: `point_${geo.coordinates[0]}_${geo.coordinates[1]}` }); sdk.Map.addFeatureToLayer({ feature: pointFeature, layerName: rsaIconLayer.layerName }); } else { // console.log('seg highlight') // Object.assign(styleRules.segHighlight.style, { // strokeColor: color, // strokeOpacity: overSized ? 1 : 0.75, // strokeWidth: overSized ? 7 : 4, // fillColor: color, // fillOpacity: 0.75, // }); // const newFeat = new OpenLayers.Geometry.LineString(geo.components, {}); // const newVector = new OpenLayers.Feature.Vector(newFeat, null, style); // rsaMapLayer.addFeatures([newVector]); const newLineFeature = turf.lineString(geo.coordinates, { styleName: "segHighlight", style: { strokeColor: color, strokeOpacity: overSized ? 1 : 0.75, strokeWidth: overSized ? 7 : 4, fillColor: color, fillOpacity: 0.75, }, }, { id: `line_${geo}` }); sdk.Map.addFeatureToLayer({ feature: newLineFeature, layerName: rsaMapLayer.layerName }); } } function removeHighlights() { sdk.Map.removeAllFeaturesFromLayer(rsaMapLayer); sdk.Map.removeAllFeaturesFromLayer(rsaIconLayer); } function labelDistance() { // Return object with two variables - label is the distance used to place the direction below the icon, // space is the space between geo points needed to render another icon const label_distance = { icon: 0, label: 0, space: 0 }; switch (sdk.Map.getZoomLevel()) { case ZoomLevel.ZM10: label_distance.label = 2; label_distance.space = 30; label_distance.icon = 1.1; break; case ZoomLevel.ZM9: label_distance.label = 4; label_distance.space = 30; label_distance.icon = 2.2; break; case ZoomLevel.ZM8: label_distance.label = 8; label_distance.space = 30; label_distance.icon = 4.5; break; case ZoomLevel.ZM7: label_distance.label = 14; label_distance.space = 30; label_distance.icon = 8.3; break; case ZoomLevel.ZM6: label_distance.label = 28; label_distance.space = 30; label_distance.icon = 17; break; case ZoomLevel.ZM5: label_distance.label = 50; label_distance.space = 30; label_distance.icon = 34; break; case ZoomLevel.ZM4: label_distance.label = 100; label_distance.space = 40; label_distance.icon = 68; break; case ZoomLevel.ZM3: label_distance.label = 300; label_distance.space = 70; label_distance.icon = 140; break; case ZoomLevel.ZM2: label_distance.label = 300; label_distance.space = 200; label_distance.icon = 140; break; case ZoomLevel.ZM1: label_distance.label = 300; label_distance.space = 250; label_distance.icon = 140; break; } return label_distance; } initRSA(); }