您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
WME UrSuS Tools: LV Layers
// ==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);