// ==UserScript==
// @name WME UT LV Layers
// @namespace http://ursus.id.lv
// @version 1.0.0
// @description WME UrSuS Tools: LV Layers
// @author UrSuS
// @match https://*.waze.com/*editor*
// @license MIT
// @icon data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB3aWR0aD0iNjMuOTk5OTk2bW0iCiAgIGhlaWdodD0iNjQuMDAwMDE1bW0iCiAgIHZpZXdCb3g9IjAgMCA2My45OTk5OTYgNjQuMDAwMDE1IgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmc1IgogICBpbmtzY2FwZTp2ZXJzaW9uPSIxLjIgKGRjMmFlZGFmMDMsIDIwMjItMDUtMTUpIgogICBzb2RpcG9kaTpkb2NuYW1lPSJ3bWUga2FkYXN0cnMuc3ZnIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxzb2RpcG9kaTpuYW1lZHZpZXcKICAgICBpZD0ibmFtZWR2aWV3NyIKICAgICBwYWdlY29sb3I9IiNmZmZmZmYiCiAgICAgYm9yZGVyY29sb3I9IiM2NjY2NjYiCiAgICAgYm9yZGVyb3BhY2l0eT0iMS4wIgogICAgIGlua3NjYXBlOnNob3dwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiCiAgICAgaW5rc2NhcGU6cGFnZWNoZWNrZXJib2FyZD0iMCIKICAgICBpbmtzY2FwZTpkZXNrY29sb3I9IiNkMWQxZDEiCiAgICAgaW5rc2NhcGU6ZG9jdW1lbnQtdW5pdHM9Im1tIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpbmtzY2FwZTp6b29tPSIxLjAzMzA4MjIiCiAgICAgaW5rc2NhcGU6Y3g9IjY3Ljc1ODQwMSIKICAgICBpbmtzY2FwZTpjeT0iNzU3LjQ0MjEzIgogICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMTkyMCIKICAgICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMDA1IgogICAgIGlua3NjYXBlOndpbmRvdy14PSItOSIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iLTkiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJsYXllcjEiCiAgICAgc2hvd2d1aWRlcz0idHJ1ZSI+CiAgICA8c29kaXBvZGk6Z3VpZGUKICAgICAgIHBvc2l0aW9uPSIzMi4wMDAwMDMsMzIuMDAwMDA3IgogICAgICAgb3JpZW50YXRpb249IjEsMCIKICAgICAgIGlkPSJndWlkZTgzMCIKICAgICAgIGlua3NjYXBlOmxvY2tlZD0iZmFsc2UiIC8+CiAgICA8c29kaXBvZGk6Z3VpZGUKICAgICAgIHBvc2l0aW9uPSIzMi4wMDAwMDEsMzIuMDAwMDA5IgogICAgICAgb3JpZW50YXRpb249IjAsLTEiCiAgICAgICBpZD0iZ3VpZGU4MzIiCiAgICAgICBpbmtzY2FwZTpsb2NrZWQ9ImZhbHNlIiAvPgogIDwvc29kaXBvZGk6bmFtZWR2aWV3PgogIDxkZWZzCiAgICAgaWQ9ImRlZnMyIiAvPgogIDxnCiAgICAgaW5rc2NhcGU6bGFiZWw9IkxheWVyIDEiCiAgICAgaW5rc2NhcGU6Z3JvdXBtb2RlPSJsYXllciIKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01NC40MzczMywtMTczLjI3MjY1KSI+CiAgICA8cmVjdAogICAgICAgc3R5bGU9ImZpbGw6I2EwMmMyYztzdHJva2Utd2lkdGg6MjYuNDU4MyIKICAgICAgIGlkPSJyZWN0ODE4IgogICAgICAgd2lkdGg9IjY0IgogICAgICAgaGVpZ2h0PSI2NCIKICAgICAgIHg9IjU0LjQzNzMzMiIKICAgICAgIHk9IjE3My4yNzI2NiIgLz4KICAgIDxnCiAgICAgICB0cmFuc2Zvcm09Im1hdHJpeCgxLjE5MzY3MDgsMCwwLDEuMTkzNjcwOCw1Ni42Mzc5MTgsMTc1LjM4OTExKSIKICAgICAgIGlkPSJnODI0Ij4KICAgICAgPHBhdGgKICAgICAgICAgZD0ibSAyNy41LDIuNjc0IGMgLTYuMTgxLDAgLTExLjk0NCwyLjc3NyAtMTUuODMzLDcuNzA4IEMgOC45NTgsMTMuODU0IDcuNSwxOC4xNiA3LjUsMjIuNTM1IHYgMy42OCBDIDcuNSwyNy44MTIgNi44NzUsMjkuMzQgNS44MzMsMzAuNDUxIDUsMzEuMjg1IDMuOTU4LDMxLjkxIDIuODQ3LDMyLjE4OCBjIDAuNDE3LDEuMDQxIDEuMzg5LDIuNjM4IDMuMTI1LDQuMzc1IDEuNDU5LDEuNTI3IDMuMTk1LDIuNzc3IDUuMDcsMy42OCB2IC0wLjA2OSBjIDEuMTgsLTEuODA2IDMuMTI1LC0yLjg0OCA1LjI3NywtMi44NDggMC40MTcsMCAwLjc2NCwwLjA3IDEuMTgxLDAuMTM5IDIuNSwwLjQ4NiA0LjQ0NCwyLjQzMSA0LjkzMSw0Ljg2MSBoIDUuMTM4IGMgNS4zNDgsMCAxMC40MTcsLTIuMjIyIDE0LjA5OCwtNS44MzMgNS42OTQsLTUuNjk0IDcuNDMsLTE0LjIzNiA0LjMwNSwtMjEuNTk3IEMgNDIuODQ3LDcuNDY1IDM1LjYyNSwyLjY3NCAyNy41LDIuNjc0IFoiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNhMDJjMmMiCiAgICAgICAgIGlkPSJwYXRoODIwIiAvPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDI3LjUsMC4xNzQgQyAyMC42MjUsMC4xNzQgMTQuMTY3LDMuMjI5IDkuNzkyLDguNzE1IDYuNjY3LDEyLjY3NCA1LDE3LjUzNSA1LDIyLjYwNCB2IDMuNjExIGMgMCwxLjg3NSAtMS4zMTksMy42MTEgLTMuODg5LDMuNzUgLTAuNjI1LDAgLTEuMTExLDAuNDg2IC0xLjE4LDEuMTExIC0wLjA3LDEuNjY3IDEuNzM2LDQuNzkyIDQuMjM2LDcuMjkyIDEuNzM2LDEuNzM2IDMuNzUsMy4xMjUgNS45MDIsNC4yMzYgLTAuNjk0LDMuODIgMi4yOTIsNy4yOTIgNi4xODEsNy4yOTIgaCAwLjA2OSBjIDIuOTg3LDAgNS40ODcsLTIuMDgzIDYuMTEyLC00LjkzMSBoIDUuMjA4IGMgMC41NTUsMi44NDggMy4wNTUsNC45MzEgNi4xMTEsNC45MzEgMC42OTQsMCAxLjQ1OCwtMC4xMzkgMi4xNTMsLTAuMzQ3IDEuNzM2LC0wLjU1NiAzLjA1NSwtMS44NzUgMy42OCwtMy42MTIgMC41NTYsLTEuNTk3IDAuNDg2LC0zLjE5NCAwLC00LjUxMyAxLjM4OSwtMC45MDMgMi42MzksLTEuODc1IDMuODIsLTMuMDU2IEMgNDcuNjM5LDM0LjIwMSA1MCwyOC41MDcgNTAsMjIuNjA0IDUwLDE2LjYzMiA0Ny42MzksMTEuMDc2IDQzLjQwMyw2Ljg0IDM5LjE2NywyLjQ2NSAzMy40NzIsMC4xNzQgMjcuNSwwLjE3NCBaIG0gMCwyLjUgYyA4LjA1NiwwIDE1LjM0Nyw0Ljg2MSAxOC40NzIsMTIuMjkxIDMuMTI1LDcuNDMxIDEuMzg5LDE1Ljk3MiAtNC4zMDUsMjEuNTk4IC0zLjY4MSwzLjY4IC04Ljc1LDUuODMzIC0xNC4wOTgsNS44MzMgSCAyMi40MzEgQyAyMS45NDQsMzkuODk2IDIwLDM4LjAyMSAxNy41LDM3LjUzNSBjIC0wLjQxNywtMC4wNyAtMC43NjQsLTAuMTM5IC0xLjE4MSwtMC4xMzkgLTIuMDgzLDAgLTQuMDk3LDEuMDQyIC01LjI3NywyLjg0NyB2IDAuMDcgQyA5LjE2NywzOS4zNCA3LjUsMzguMDkgNS45NzIsMzYuNjMyIDQuMjM2LDM0Ljg5NiAzLjI2NCwzMy4yMjkgMi44NDcsMzIuMjU3IDQuMDI4LDMxLjk3OSA1LDMxLjM1NCA1LjgzMywzMC41MjEgNi44NzUsMjkuMzQgNy41LDI3Ljg4MiA3LjUsMjYuMjg1IHYgLTMuNjgxIGMgMCwtNC4zNzUgMS40NTgsLTguNjggNC4xNjcsLTEyLjE1MyBDIDE1LjU1Niw1LjM4MiAyMS4zMTksMi42NzQgMjcuNSwyLjY3NCBaIgogICAgICAgICBpZD0icGF0aDgyMiIKICAgICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZiIgLz4KICAgIDwvZz4KICAgIDxnCiAgICAgICBhcmlhLWxhYmVsPSJVVCIKICAgICAgIGlkPSJ0ZXh0ODI4IgogICAgICAgc3R5bGU9ImZvbnQtc2l6ZTozMC42NzMycHg7bGluZS1oZWlnaHQ6MS4yNTtmb250LWZhbWlseTpXYXplOy1pbmtzY2FwZS1mb250LXNwZWNpZmljYXRpb246V2F6ZTtsZXR0ZXItc3BhY2luZzowcHg7d29yZC1zcGFjaW5nOjBweDtmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMTE1MDI0Ij4KICAgICAgPHBhdGgKICAgICAgICAgZD0ibSA4OC4zMTk3NzQsMjA4LjEyNTI2IHEgMCwyLjc5MTI2IC0xLjI1NzYwMiw0LjYwMDk4IC0xLjI1NzYwMSwxLjc3OTA1IC0zLjI4MjAzMiwyLjYzNzkgLTIuMDI0NDMxLDAuODU4ODUgLTQuMzU1NTk1LDAuODU4ODUgLTIuMzAwNDksMCAtNC4zMjQ5MjEsLTAuODU4ODUgLTIuMDI0NDMxLC0wLjg1ODg1IC0zLjI4MjAzMiwtMi42Mzc5IC0xLjI1NzYwMiwtMS43NzkwNCAtMS4yNTc2MDIsLTQuNTcwMyB2IC0xMy4xODk0OCBxIDAsLTAuMjQ1MzggMC4xODQwNCwtMC40Mjk0MiAwLjE4NDAzOSwtMC4yMTQ3MiAwLjQ2MDA5OCwtMC4yMTQ3MiBoIDIuNzkxMjYxIHEgMC4yNzYwNTksMCAwLjQ2MDA5OCwwLjIxNDcyIDAuMjE0NzEyLDAuMTg0MDQgMC4yMTQ3MTIsMC40Mjk0MiB2IDEyLjkxMzQyIHEgMCwyLjE0NzEyIDEuMjU3NjAyLDMuMzc0MDUgMS4yNTc2MDEsMS4yMjY5MyAzLjQ5Njc0NCwxLjIyNjkzIDIuMjY5ODE3LDAgMy41Mjc0MTksLTEuMjI2OTMgMS4yNTc2MDEsLTEuMjI2OTMgMS4yNTc2MDEsLTMuMzc0MDUgdiAtMTIuOTEzNDIgcSAwLC0wLjI0NTM4IDAuMTg0MDM5LC0wLjQyOTQyIDAuMjE0NzEyLC0wLjIxNDcyIDAuNDkwNzcxLC0wLjIxNDcyIGggMi43OTEyNjEgcSAwLjI0NTM4NiwwIDAuNDI5NDI1LDAuMjE0NzIgMC4yMTQ3MTMsMC4xODQwNCAwLjIxNDcxMywwLjQyOTQyIHoiCiAgICAgICAgIGlkPSJwYXRoODc4IiAvPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDkwLjQzNjIxNSwxOTcuNDUwOTkgdiAtMi40NTM4NiBxIDAsLTAuMjc2MDUgMC4xODQwNCwtMC40NjAwOSAwLjE4NDAzOSwtMC4yMTQ3MiAwLjQ2MDA5OCwtMC4yMTQ3MiBoIDE2Ljk5Mjk1NyBxIDAuMjc2MDUsMCAwLjQ2MDA5LDAuMjE0NzIgMC4xODQwNCwwLjE4NDA0IDAuMTg0MDQsMC40NjAwOSB2IDIuNDUzODYgcSAwLDAuMjc2MDYgLTAuMTg0MDQsMC40NjAxIC0wLjE4NDA0LDAuMTg0MDQgLTAuNDYwMDksMC4xODQwNCBoIC02LjM4MDAzIHYgMTcuMDIzNjIgcSAwLDAuMjc2MDYgLTAuMjE0NzEsMC40OTA3NyAtMC4xODQwNCwwLjE4NDA0IC0wLjQ2MDEsMC4xODQwNCBoIC0yLjkxMzk1NCBxIC0wLjI3NjA1OSwwIC0wLjQ2MDA5OCwtMC4xODQwNCAtMC4xODQwNCwtMC4yMTQ3MSAtMC4xODQwNCwtMC40OTA3NyB2IC0xNy4wMjM2MiBoIC02LjM4MDAyNSBxIC0wLjI3NjA1OSwwIC0wLjQ2MDA5OCwtMC4xODQwNCAtMC4xODQwNCwtMC4xODQwNCAtMC4xODQwNCwtMC40NjAxIHoiCiAgICAgICAgIGlkPSJwYXRoODgwIiAvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+Cg==
// @exclude https://www.waze.com/user/editor*
// @require https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4.js
// @connect balticmaps.eu
// @grant GM_info
// @grant GM_xmlhttpRequest
// ==/UserScript==
/* globals proj4 */
(function (proj4) {
"use strict";
GM_info.script.name;
GM_info.script.version;
let wmeSDK;
let _settings = {};
let webLocationTilesContainerId;
let currentOverlay = "";
let currentOpacity = 100;
let sBalticMapsKey = "";
const _SETTINGS_STORAGE_NAME = "WME_LV_TOOLS";
const defaultSettings = {
LeftOffset: "400px",
TopOffset: "100px",
HideToolbar: false,
};
function cbLayerChange(oEvent) {
if (oEvent.target instanceof HTMLInputElement) {
const sSetting = oEvent.target.getAttribute("boundSetting");
if (sSetting) {
_settings[sSetting] = oEvent.target.checked;
}
const sLayerId = oEvent.target.getAttribute("layerId");
if (sLayerId) {
CheckUnCheckCustomWMSLayer(oEvent.target.checked, sLayerId);
}
saveSettingsToStorage();
}
}
const aLayersElementsConfig = [
{
id: "lvm-kadastrs",
url: "https://lvmgeoserver.lvm.lv/geoserver/ows?FORMAT=image/png&TRANSPARENT=TRUE&VERSION=1.3.0&SERVICE=WMS&REQUEST=GetMap&LAYERS=publicwfs:kkparcel&STYLES=&CRS=EPSG:4326&WIDTH=256&HEIGHT=256&BBOX={bbox}&STYLES=&request=GetMap",
elements: [
{
type: "input",
attributes: {
type: "checkbox",
id: "cbShowKadastrsLayer",
title: "Kadastrs",
checked: _settings.showKadastrsLayer,
boundSetting: "showKadastrsLayer",
layerId: "lvm-kadastrs",
},
events: {
change: cbLayerChange,
},
triggerChangeEvent: false,
},
{
type: "label",
attributes: {
for: "cbShowKadastrsLayer",
textContent: "Kadastrs",
},
},
],
},
{
id: "lvm-kadastrs-houses",
url: "https://lvmgeoserver.lvm.lv/geoserver/ows?FORMAT=image/png&TRANSPARENT=TRUE&VERSION=1.3.0&SERVICE=WMS&REQUEST=GetMap&LAYERS=publicwfs:kkbuilding&STYLES=&CRS=EPSG:4326&WIDTH=256&HEIGHT=256&BBOX={bbox}",
elements: [
{
type: "input",
attributes: {
type: "checkbox",
id: "cbShowKadastrsHousesLayer",
title: "Kadastrs Houses",
checked: _settings.showKadastrsHousesLayer,
boundSetting: "showKadastrsHousesLayer",
layerId: "lvm-kadastrs-houses",
},
events: {
change: cbLayerChange,
},
triggerChangeEvent: false,
},
{
type: "label",
attributes: {
for: "cbShowKadastrsHousesLayer",
textContent: "Kadastrs Houses",
},
},
],
},
{
id: "new-bing",
url: "https://ecn.t3.tiles.virtualearth.net/tiles/a{quadDigits}.jpeg?g={latestBingImageVersion}&n=z",
elements: [
{
type: "input",
attributes: {
type: "checkbox",
id: "cbShowNewBingLayer",
title: "New Bing",
checked: _settings.showNewBingLayer,
boundSetting: "showNewBingLayer",
layerId: "new-bing",
},
events: {
change: cbLayerChange,
},
triggerChangeEvent: false,
},
{
type: "label",
attributes: {
for: "cbShowNewBingLayer",
textContent: "New Bing",
},
},
],
},
{
id: "lvm-roads",
url: "https://lvmgeoproxy01.lvm.lv/A05F8B5E0EB84CAEB9499496474E3093/LVMLV/LITEvLVMbaseData/MapServer/export?F=image&FORMAT=PNG32&TRANSPARENT=true&LAYERS=show%3A19%2C20&BBOX={bbox3857}&BBOXSR=3857&DPI=350",
elements: [
{
type: "input",
attributes: {
type: "checkbox",
id: "cbShowLVMRoadsLayer",
title: "LVM Roads",
checked: _settings.showLVMRoadsLayer,
boundSetting: "showLVMRoadsLayer",
layerId: "lvm-roads",
},
events: {
change: cbLayerChange,
},
triggerChangeEvent: false,
},
{
type: "label",
attributes: {
for: "cbShowLVMRoadsLayer",
textContent: "LVM Roads",
},
},
],
},
{
id: "balticmaps",
url: "https://wms3.kartes.lv/PIER/wgs/15/{zoom}/{x}/{y}.png",
elements: [
{
type: "input",
attributes: {
type: "checkbox",
id: "cbShowBalticMapsLayer",
title: "Baltic Maps",
checked: _settings.showBalticMapsLayer,
boundSetting: "showBalticMapsLayer",
layerId: "balticmaps",
},
events: {
change: cbLayerChange,
},
triggerChangeEvent: false,
},
{
type: "label",
attributes: {
for: "cbShowBalticMapsLayer",
textContent: "Baltic Maps",
},
},
],
},
{
id: "balticmaps-orto8",
url: "https://wmsbm4.kartes.lv/{balticMapsKey}/wgs/orto_full/?SERVICE=WMS&VERSION=1.0.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&LAYERS=0&DPI=96&MAP_RESOLUTION=96&FORMAT_OPTIONS=dpi%3A96&WIDTH=256&HEIGHT=256&SRS=EPSG%3A3857&STYLES=&BBOX={bbox3857}",
elements: [
{
type: "input",
attributes: {
type: "checkbox",
id: "cbShowBalticMapsOrto8Layer",
title: "Baltic Maps Ortofoto 8th cycle (2022-2024)",
checked: _settings.showBalticMapsOrto8Layer,
boundSetting: "showBalticMapsLayer",
layerId: "balticmaps-orto8",
},
events: {
change: cbLayerChange,
},
triggerChangeEvent: false,
},
{
type: "label",
attributes: {
for: "cbShowBalticMapsOrto8Layer",
textContent: "Baltic Maps Ortofoto 8th cycle",
},
},
],
},
];
unsafeWindow.SDK_INITIALIZED.then(initScript);
function makeGetRequest(sURL) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: "GET",
url: sURL,
onload: (response) => resolve(response.responseText),
onerror: (error) => reject(error),
});
});
}
function initScript() {
if (!unsafeWindow.getWmeSdk) {
throw new Error("SDK not available");
}
wmeSDK = unsafeWindow.getWmeSdk({
scriptId: "wmeUTLayers",
scriptName: "UrSuS Tools: Layers",
});
const sStorageItem = localStorage.getItem(_SETTINGS_STORAGE_NAME);
if (sStorageItem) {
const loadedSettings = JSON.parse(sStorageItem);
_settings = { ...defaultSettings, ...loadedSettings };
}
webLocationTilesContainerId =
"#" + W.map.getLayerByUniqueName("satellite_imagery").id;
void fetchBalticMapKey();
void initScriptTab();
}
async function saveSettingsToStorage() {
if (localStorage) {
_settings.lastSaved = Date.now();
localStorage.setItem(_SETTINGS_STORAGE_NAME, JSON.stringify(_settings));
}
}
async function fetchBalticMapKey() {
const sURL = "https://balticmaps.eu/backend/public/v1/key";
const sKeyResponseJSON = await makeGetRequest(sURL);
const mBalticMapsKey = JSON.parse(sKeyResponseJSON);
sBalticMapsKey = mBalticMapsKey.key;
}
async function initScriptTab() {
const { tabLabel, tabPane } = await wmeSDK.Sidebar.registerScriptTab();
tabLabel.innerText = "WME UT Layers";
tabLabel.title = "WME UT Layers";
const description = document.createElement("p");
description.style.fontWeight = "bold";
description.textContent = "WME UT Layers";
tabPane.appendChild(description);
let buttonContainer = createElem("div", {
class: "controls-container",
});
generateDomElements(aLayersElementsConfig, buttonContainer);
tabPane.appendChild(buttonContainer);
}
function generateDomElements(aLayersConfig, oDOMContainer) {
aLayersConfig.forEach((mLayerConfig) => {
mLayerConfig.elements.forEach((item) => {
const $HTMLElement = createElem(
item.type,
item.attributes,
item.events || []
);
oDOMContainer.appendChild($HTMLElement);
if (item.triggerChangeEvent) {
$HTMLElement.dispatchEvent(new Event("change"));
}
});
console.log(
`Elements for '${mLayerConfig.id}' created. URL: ${mLayerConfig.url}`
);
const br = createElem("br");
oDOMContainer.append(br);
});
}
function createElem(type, attrs = {}, eventListener = {}) {
const element = document.createElement(type);
for (const [key, value] of Object.entries(attrs)) {
if (key in element) {
element[key] = value;
} else {
element.setAttribute(key, value);
}
}
for (const [eventType, handler] of Object.entries(eventListener)) {
if (handler) {
element.addEventListener(eventType, handler);
}
}
return element;
}
function CheckUnCheckCustomWMSLayer(checked, sLayerName) {
checked ? setWMSLayer(sLayerName) : unsetWMSLayer();
}
function setWMSLayer(sLayerName) {
setDefaultImages();
currentOverlay = sLayerName;
setImages();
wmeSDK.Events.on({
eventName: "wme-map-move-end",
eventHandler: setImages,
});
}
function unsetWMSLayer() {
setDefaultImages();
wmeSDK.Events.off({
eventName: "wme-map-move-end",
eventHandler: setImages,
});
}
function setDefaultImages() {
var innerTilesContainer = $(webLocationTilesContainerId);
$(".overlayUrSuS", innerTilesContainer).remove();
}
function setImages() {
setImagesWaze();
}
function setImagesWaze() {
var innerTilesContainer = $(webLocationTilesContainerId);
innerTilesContainer.children("img.overlayUrSuS").each(function () {
var default_url = $(this).attr("data-default_url");
var original = innerTilesContainer.find(
'img.olTileImage[src="' + default_url + '"]'
);
if (original.length == 0) {
$(this).remove();
}
});
innerTilesContainer.children("img.olTileImage").each(function () {
var content = $(this);
var coords = getCoordinatesWaze(content);
if (undefined != coords) {
var duplicate = innerTilesContainer.find(
'img.overlayUrSuS[data-coords="' + coords + '"]'
);
if (duplicate.length == 0) {
duplicate = $(
'<img src="" draggable="false" style="width: 256px; height: 256px; position: absolute; border: 0px; padding: 0px; margin: 0px; -webkit-user-select: none;">'
);
duplicate.css("opacity", currentOpacity / 100);
duplicate.addClass("overlayUrSuS");
}
if (!duplicate.is(content.next())) {
const sUrl = content.attr("src");
if (sUrl) {
duplicate.attr("data-default_url", sUrl);
}
duplicate.attr("data-coords", coords);
duplicate.css("top", content.css("top"));
duplicate.css("left", content.css("left"));
duplicate.insertAfter(content);
replaceImage(duplicate);
}
}
});
}
function replaceImage(element) {
var quadLetters = element.data("coords");
if (!quadLetters) return;
element.attr("src", getUrl(quadLetters));
}
function getUrl(quadLetters) {
const sLatestBingImageVersion = "14801";
const mLayerConfig = aLayersElementsConfig.find(
(config) => config.id === currentOverlay
);
if (!mLayerConfig) {
console.error(
`Overlay configuration with id '${currentOverlay}' not found.`
);
return null;
}
const mQuadDigits = QuadLettersToQuadDigits(quadLetters);
const mTiles = QuadDigitsToTileXYZ(mQuadDigits);
const mBBox = TileBounds(mTiles.x, mTiles.y, mTiles.z);
QuadLettersToQuadDigits(quadLetters);
let sUrl = mLayerConfig.url;
const sBBox = `${mBBox.p2.y},${mBBox.p1.x},${mBBox.p1.y},${mBBox.p2.x}`;
const sBBox3857 = getBBox3857(mBBox);
if (sUrl.includes("{bbox}")) {
sUrl = sUrl.replace("{bbox}", sBBox);
} else if (sUrl.includes("{bbox3857}")) {
sUrl = sUrl.replace("{bbox3857}", sBBox3857);
} else if (sUrl.includes("{quadDigits}")) {
sUrl = sUrl.replace("{quadDigits}", mQuadDigits);
} else {
sUrl = sUrl.replace("{x}", mTiles.x.toString());
sUrl = sUrl.replace("{y}", mTiles.y.toString());
sUrl = sUrl.replace("{zoom}", mTiles.z.toString());
}
if (sUrl.includes("{latestBingImageVersion}")) {
sUrl = sUrl.replace("{latestBingImageVersion}", sLatestBingImageVersion);
}
if (sUrl.includes("{balticMapsKey}")) {
sUrl = sUrl.replace("{balticMapsKey}", sBalticMapsKey);
}
return sUrl;
}
function TileBounds(tx, ty, zoom) {
var p = Math.pow(2, zoom);
return {
p1: {
x: (tx * 360) / p - 180,
y:
90 -
(360 * Math.atan(Math.exp(-(0.5 - ty / p) * 2 * Math.PI))) / Math.PI,
},
p2: {
x: ((tx + 1) * 360) / p - 180,
y:
90 -
(360 * Math.atan(Math.exp(-(0.5 - (ty + 1) / p) * 2 * Math.PI))) /
Math.PI,
},
};
}
function getBBox3857(mBBox) {
const aConvertedCoordinates = [
...proj4("EPSG:4326", "EPSG:900913", [mBBox.p1.x, mBBox.p2.y]),
...proj4("EPSG:4326", "EPSG:900913", [mBBox.p2.x, mBBox.p1.y]),
];
const string = aConvertedCoordinates.join();
return string;
}
function QuadDigitsToTileXYZ(quadKey) {
let x = 0;
let y = 0;
let z = quadKey.length;
for (var i = z; i > 0; i--) {
var digit = quadKey[z - i];
var mask = 1 << (i - 1);
if (digit == "0") {
continue;
} else if (digit == "1") {
x |= mask;
} else if (digit == "2") {
y |= mask;
} else if (digit == "3") {
x |= mask;
y |= mask;
}
}
return {
x: x,
y: y,
z: z,
};
}
function QuadLettersToQuadDigits(quadKey) {
var quadDigits = "";
for (var i = 1; i < quadKey.length; i++) {
switch (quadKey[i]) {
case "q":
quadDigits += "0";
break;
case "r":
quadDigits += "1";
break;
case "t":
quadDigits += "2";
break;
case "s":
quadDigits += "3";
break;
}
}
return quadDigits;
}
function getCoordinatesWaze(img) {
var satelliteTileUrl = img.attr("src");
var coords;
if (!satelliteTileUrl) {
return;
}
var pattern = new RegExp("\\/\\/www\\.googleapis\\.com\\/tile\\/v1", "g");
if (pattern.test(satelliteTileUrl)) {
const RegExp =
/\/\/www\.googleapis\.com\/tile\/v1\/tiles\/(\d+)\/(\d+)\/(\d+)/g;
const match = RegExp.exec(satelliteTileUrl);
if (match) {
coords = QuadDigitsToQuadLetters(
TileXYZToQuadDigits(match[2], match[3], parseFloat(match[1]))
);
}
}
return coords;
}
function QuadDigitsToQuadLetters(quadKey) {
var quadLetters = "t";
for (var i = 0; i < quadKey.length; i++) {
switch (quadKey[i]) {
case "0":
quadLetters += "q";
break;
case "1":
quadLetters += "r";
break;
case "2":
quadLetters += "t";
break;
case "3":
quadLetters += "s";
break;
}
}
return quadLetters;
}
function TileXYZToQuadDigits(tileX, tileY, zoom) {
var quadKey = "";
for (var i = zoom; i > 0; i--) {
var digit = 0;
var mask = 1 << (i - 1);
if ((tileX & mask) != 0) {
digit++;
}
if ((tileY & mask) != 0) {
digit++;
digit++;
}
quadKey = quadKey.concat(digit.toString());
}
return quadKey;
}
})(proj4);