// ==UserScript==
// @name WME UT Kadastrs
// @namespace http://ursus.id.lv
// @version 1.0.1
// @description WME UrSuS Tools: LV Kadastrs
// @author UrSuS
// @match https://*.waze.com/*editor*
// @license MIT/BSD/X11
// @icon data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB3aWR0aD0iNjMuOTk5OTk2bW0iCiAgIGhlaWdodD0iNjQuMDAwMDE1bW0iCiAgIHZpZXdCb3g9IjAgMCA2My45OTk5OTYgNjQuMDAwMDE1IgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmc1IgogICBpbmtzY2FwZTp2ZXJzaW9uPSIxLjIgKGRjMmFlZGFmMDMsIDIwMjItMDUtMTUpIgogICBzb2RpcG9kaTpkb2NuYW1lPSJ3bWUga2FkYXN0cnMuc3ZnIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxzb2RpcG9kaTpuYW1lZHZpZXcKICAgICBpZD0ibmFtZWR2aWV3NyIKICAgICBwYWdlY29sb3I9IiNmZmZmZmYiCiAgICAgYm9yZGVyY29sb3I9IiM2NjY2NjYiCiAgICAgYm9yZGVyb3BhY2l0eT0iMS4wIgogICAgIGlua3NjYXBlOnNob3dwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiCiAgICAgaW5rc2NhcGU6cGFnZWNoZWNrZXJib2FyZD0iMCIKICAgICBpbmtzY2FwZTpkZXNrY29sb3I9IiNkMWQxZDEiCiAgICAgaW5rc2NhcGU6ZG9jdW1lbnQtdW5pdHM9Im1tIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpbmtzY2FwZTp6b29tPSIxLjAzMzA4MjIiCiAgICAgaW5rc2NhcGU6Y3g9IjY3Ljc1ODQwMSIKICAgICBpbmtzY2FwZTpjeT0iNzU3LjQ0MjEzIgogICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMTkyMCIKICAgICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMDA1IgogICAgIGlua3NjYXBlOndpbmRvdy14PSItOSIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iLTkiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJsYXllcjEiCiAgICAgc2hvd2d1aWRlcz0idHJ1ZSI+CiAgICA8c29kaXBvZGk6Z3VpZGUKICAgICAgIHBvc2l0aW9uPSIzMi4wMDAwMDMsMzIuMDAwMDA3IgogICAgICAgb3JpZW50YXRpb249IjEsMCIKICAgICAgIGlkPSJndWlkZTgzMCIKICAgICAgIGlua3NjYXBlOmxvY2tlZD0iZmFsc2UiIC8+CiAgICA8c29kaXBvZGk6Z3VpZGUKICAgICAgIHBvc2l0aW9uPSIzMi4wMDAwMDEsMzIuMDAwMDA5IgogICAgICAgb3JpZW50YXRpb249IjAsLTEiCiAgICAgICBpZD0iZ3VpZGU4MzIiCiAgICAgICBpbmtzY2FwZTpsb2NrZWQ9ImZhbHNlIiAvPgogIDwvc29kaXBvZGk6bmFtZWR2aWV3PgogIDxkZWZzCiAgICAgaWQ9ImRlZnMyIiAvPgogIDxnCiAgICAgaW5rc2NhcGU6bGFiZWw9IkxheWVyIDEiCiAgICAgaW5rc2NhcGU6Z3JvdXBtb2RlPSJsYXllciIKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC01NC40MzczMywtMTczLjI3MjY1KSI+CiAgICA8cmVjdAogICAgICAgc3R5bGU9ImZpbGw6I2EwMmMyYztzdHJva2Utd2lkdGg6MjYuNDU4MyIKICAgICAgIGlkPSJyZWN0ODE4IgogICAgICAgd2lkdGg9IjY0IgogICAgICAgaGVpZ2h0PSI2NCIKICAgICAgIHg9IjU0LjQzNzMzMiIKICAgICAgIHk9IjE3My4yNzI2NiIgLz4KICAgIDxnCiAgICAgICB0cmFuc2Zvcm09Im1hdHJpeCgxLjE5MzY3MDgsMCwwLDEuMTkzNjcwOCw1Ni42Mzc5MTgsMTc1LjM4OTExKSIKICAgICAgIGlkPSJnODI0Ij4KICAgICAgPHBhdGgKICAgICAgICAgZD0ibSAyNy41LDIuNjc0IGMgLTYuMTgxLDAgLTExLjk0NCwyLjc3NyAtMTUuODMzLDcuNzA4IEMgOC45NTgsMTMuODU0IDcuNSwxOC4xNiA3LjUsMjIuNTM1IHYgMy42OCBDIDcuNSwyNy44MTIgNi44NzUsMjkuMzQgNS44MzMsMzAuNDUxIDUsMzEuMjg1IDMuOTU4LDMxLjkxIDIuODQ3LDMyLjE4OCBjIDAuNDE3LDEuMDQxIDEuMzg5LDIuNjM4IDMuMTI1LDQuMzc1IDEuNDU5LDEuNTI3IDMuMTk1LDIuNzc3IDUuMDcsMy42OCB2IC0wLjA2OSBjIDEuMTgsLTEuODA2IDMuMTI1LC0yLjg0OCA1LjI3NywtMi44NDggMC40MTcsMCAwLjc2NCwwLjA3IDEuMTgxLDAuMTM5IDIuNSwwLjQ4NiA0LjQ0NCwyLjQzMSA0LjkzMSw0Ljg2MSBoIDUuMTM4IGMgNS4zNDgsMCAxMC40MTcsLTIuMjIyIDE0LjA5OCwtNS44MzMgNS42OTQsLTUuNjk0IDcuNDMsLTE0LjIzNiA0LjMwNSwtMjEuNTk3IEMgNDIuODQ3LDcuNDY1IDM1LjYyNSwyLjY3NCAyNy41LDIuNjc0IFoiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNhMDJjMmMiCiAgICAgICAgIGlkPSJwYXRoODIwIiAvPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDI3LjUsMC4xNzQgQyAyMC42MjUsMC4xNzQgMTQuMTY3LDMuMjI5IDkuNzkyLDguNzE1IDYuNjY3LDEyLjY3NCA1LDE3LjUzNSA1LDIyLjYwNCB2IDMuNjExIGMgMCwxLjg3NSAtMS4zMTksMy42MTEgLTMuODg5LDMuNzUgLTAuNjI1LDAgLTEuMTExLDAuNDg2IC0xLjE4LDEuMTExIC0wLjA3LDEuNjY3IDEuNzM2LDQuNzkyIDQuMjM2LDcuMjkyIDEuNzM2LDEuNzM2IDMuNzUsMy4xMjUgNS45MDIsNC4yMzYgLTAuNjk0LDMuODIgMi4yOTIsNy4yOTIgNi4xODEsNy4yOTIgaCAwLjA2OSBjIDIuOTg3LDAgNS40ODcsLTIuMDgzIDYuMTEyLC00LjkzMSBoIDUuMjA4IGMgMC41NTUsMi44NDggMy4wNTUsNC45MzEgNi4xMTEsNC45MzEgMC42OTQsMCAxLjQ1OCwtMC4xMzkgMi4xNTMsLTAuMzQ3IDEuNzM2LC0wLjU1NiAzLjA1NSwtMS44NzUgMy42OCwtMy42MTIgMC41NTYsLTEuNTk3IDAuNDg2LC0zLjE5NCAwLC00LjUxMyAxLjM4OSwtMC45MDMgMi42MzksLTEuODc1IDMuODIsLTMuMDU2IEMgNDcuNjM5LDM0LjIwMSA1MCwyOC41MDcgNTAsMjIuNjA0IDUwLDE2LjYzMiA0Ny42MzksMTEuMDc2IDQzLjQwMyw2Ljg0IDM5LjE2NywyLjQ2NSAzMy40NzIsMC4xNzQgMjcuNSwwLjE3NCBaIG0gMCwyLjUgYyA4LjA1NiwwIDE1LjM0Nyw0Ljg2MSAxOC40NzIsMTIuMjkxIDMuMTI1LDcuNDMxIDEuMzg5LDE1Ljk3MiAtNC4zMDUsMjEuNTk4IC0zLjY4MSwzLjY4IC04Ljc1LDUuODMzIC0xNC4wOTgsNS44MzMgSCAyMi40MzEgQyAyMS45NDQsMzkuODk2IDIwLDM4LjAyMSAxNy41LDM3LjUzNSBjIC0wLjQxNywtMC4wNyAtMC43NjQsLTAuMTM5IC0xLjE4MSwtMC4xMzkgLTIuMDgzLDAgLTQuMDk3LDEuMDQyIC01LjI3NywyLjg0NyB2IDAuMDcgQyA5LjE2NywzOS4zNCA3LjUsMzguMDkgNS45NzIsMzYuNjMyIDQuMjM2LDM0Ljg5NiAzLjI2NCwzMy4yMjkgMi44NDcsMzIuMjU3IDQuMDI4LDMxLjk3OSA1LDMxLjM1NCA1LjgzMywzMC41MjEgNi44NzUsMjkuMzQgNy41LDI3Ljg4MiA3LjUsMjYuMjg1IHYgLTMuNjgxIGMgMCwtNC4zNzUgMS40NTgsLTguNjggNC4xNjcsLTEyLjE1MyBDIDE1LjU1Niw1LjM4MiAyMS4zMTksMi42NzQgMjcuNSwyLjY3NCBaIgogICAgICAgICBpZD0icGF0aDgyMiIKICAgICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZiIgLz4KICAgIDwvZz4KICAgIDxnCiAgICAgICBhcmlhLWxhYmVsPSJVVCIKICAgICAgIGlkPSJ0ZXh0ODI4IgogICAgICAgc3R5bGU9ImZvbnQtc2l6ZTozMC42NzMycHg7bGluZS1oZWlnaHQ6MS4yNTtmb250LWZhbWlseTpXYXplOy1pbmtzY2FwZS1mb250LXNwZWNpZmljYXRpb246V2F6ZTtsZXR0ZXItc3BhY2luZzowcHg7d29yZC1zcGFjaW5nOjBweDtmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMTE1MDI0Ij4KICAgICAgPHBhdGgKICAgICAgICAgZD0ibSA4OC4zMTk3NzQsMjA4LjEyNTI2IHEgMCwyLjc5MTI2IC0xLjI1NzYwMiw0LjYwMDk4IC0xLjI1NzYwMSwxLjc3OTA1IC0zLjI4MjAzMiwyLjYzNzkgLTIuMDI0NDMxLDAuODU4ODUgLTQuMzU1NTk1LDAuODU4ODUgLTIuMzAwNDksMCAtNC4zMjQ5MjEsLTAuODU4ODUgLTIuMDI0NDMxLC0wLjg1ODg1IC0zLjI4MjAzMiwtMi42Mzc5IC0xLjI1NzYwMiwtMS43NzkwNCAtMS4yNTc2MDIsLTQuNTcwMyB2IC0xMy4xODk0OCBxIDAsLTAuMjQ1MzggMC4xODQwNCwtMC40Mjk0MiAwLjE4NDAzOSwtMC4yMTQ3MiAwLjQ2MDA5OCwtMC4yMTQ3MiBoIDIuNzkxMjYxIHEgMC4yNzYwNTksMCAwLjQ2MDA5OCwwLjIxNDcyIDAuMjE0NzEyLDAuMTg0MDQgMC4yMTQ3MTIsMC40Mjk0MiB2IDEyLjkxMzQyIHEgMCwyLjE0NzEyIDEuMjU3NjAyLDMuMzc0MDUgMS4yNTc2MDEsMS4yMjY5MyAzLjQ5Njc0NCwxLjIyNjkzIDIuMjY5ODE3LDAgMy41Mjc0MTksLTEuMjI2OTMgMS4yNTc2MDEsLTEuMjI2OTMgMS4yNTc2MDEsLTMuMzc0MDUgdiAtMTIuOTEzNDIgcSAwLC0wLjI0NTM4IDAuMTg0MDM5LC0wLjQyOTQyIDAuMjE0NzEyLC0wLjIxNDcyIDAuNDkwNzcxLC0wLjIxNDcyIGggMi43OTEyNjEgcSAwLjI0NTM4NiwwIDAuNDI5NDI1LDAuMjE0NzIgMC4yMTQ3MTMsMC4xODQwNCAwLjIxNDcxMywwLjQyOTQyIHoiCiAgICAgICAgIGlkPSJwYXRoODc4IiAvPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDkwLjQzNjIxNSwxOTcuNDUwOTkgdiAtMi40NTM4NiBxIDAsLTAuMjc2MDUgMC4xODQwNCwtMC40NjAwOSAwLjE4NDAzOSwtMC4yMTQ3MiAwLjQ2MDA5OCwtMC4yMTQ3MiBoIDE2Ljk5Mjk1NyBxIDAuMjc2MDUsMCAwLjQ2MDA5LDAuMjE0NzIgMC4xODQwNCwwLjE4NDA0IDAuMTg0MDQsMC40NjAwOSB2IDIuNDUzODYgcSAwLDAuMjc2MDYgLTAuMTg0MDQsMC40NjAxIC0wLjE4NDA0LDAuMTg0MDQgLTAuNDYwMDksMC4xODQwNCBoIC02LjM4MDAzIHYgMTcuMDIzNjIgcSAwLDAuMjc2MDYgLTAuMjE0NzEsMC40OTA3NyAtMC4xODQwNCwwLjE4NDA0IC0wLjQ2MDEsMC4xODQwNCBoIC0yLjkxMzk1NCBxIC0wLjI3NjA1OSwwIC0wLjQ2MDA5OCwtMC4xODQwNCAtMC4xODQwNCwtMC4yMTQ3MSAtMC4xODQwNCwtMC40OTA3NyB2IC0xNy4wMjM2MiBoIC02LjM4MDAyNSBxIC0wLjI3NjA1OSwwIC0wLjQ2MDA5OCwtMC4xODQwNCAtMC4xODQwNCwtMC4xODQwNCAtMC4xODQwNCwtMC40NjAxIHoiCiAgICAgICAgIGlkPSJwYXRoODgwIiAvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+Cg==
// @exclude https://www.waze.com/user/editor*
// @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
// @require https://greasyfork.org/scripts/383120-proj4-wazedev/code/proj4-Wazedev.js
// @connect lvmgeoserver.lvm.lv
// @connect docs.google.com
// @grant GM_info
// @grant GM_xmlhttpRequest
// ==/UserScript==
/* globals proj4 */
(function (proj4) {
'use strict';
const sScriptName = GM_info.script.name;
GM_info.script.version;
let wmeSDK;
let aGlobalFetchedAddresses = [];
let aWMEValidAddressVenues = [];
let aWMEPolygonHighlightFeatures = [];
let aAddressConnectionLinesFeatures = [];
let aWMEPolygonHighlightBlueFeatures = [];
let aMissingFetchedAddresses = [];
let aHoverFeatures = [];
let iPopupTimeout;
let $KadastrsMenuPopupDiv;
let oAddHouseNumber;
let aVasarnicas = [];
function fetchSheetData() {
const SHEET_ID = "1W230EX3e0ECeF44Ls0GtvI_Iwn9tceidJYT7T4vjJJw";
const SHEET_NAME = "Sheet1";
const url = `https://docs.google.com/spreadsheets/d/${SHEET_ID}/gviz/tq?tqx=out:csv&sheet=${SHEET_NAME}`;
GM_xmlhttpRequest({
method: "GET",
url: url,
onload: response => {
if (response.status === 200) {
const csvData = response.responseText;
const aRows = csvData.trim().split("\n");
const aParsedResult = aRows.slice(1).map(row => {
const aCols = row.split(",");
return {
name: aCols[0].trim().replace(/^"(.*)"$/, "$1"),
parent: aCols[1].trim().replace(/^"(.*)"$/, "$1")
};
});
aVasarnicas = aParsedResult;
}
else {
console.error("Failed to fetch data:", response);
}
}
});
}
function createElem(type, attrs = {}, eventListener = {}) {
const oElement = document.createElement(type);
for (const [sKey, vValue] of Object.entries(attrs)) {
if (sKey in oElement) {
oElement[sKey] = vValue;
}
else if (sKey === "classList" && Array.isArray(vValue)) {
oElement.classList.add(...vValue);
}
else {
oElement.setAttribute(sKey, vValue);
}
}
for (const [sEventType, fnHandler] of Object.entries(eventListener)) {
if (fnHandler) {
oElement.addEventListener(sEventType, fnHandler);
}
}
return oElement;
}
function getOLMapExtent() {
let extent = W.map.getExtent();
if (Array.isArray(extent)) {
extent = new OpenLayers.Bounds(extent);
extent.transform("EPSG:4326", "EPSG:3857");
}
return extent;
}
function addKFetchButton() {
const divOverlayMain = document.getElementById("overlay-buttons-region");
if (!divOverlayMain) {
return;
}
const mStyle = {
position: "absolute",
top: "0px",
right: "60px",
width: "44px",
zIndex: "1"
};
const mainDiv = createElem("div");
Object.assign(mainDiv.style, mStyle);
const btnDiv = createElem("div", {
classList: ["overlay-buttons-container top"]
});
const owz = createElem("wz-button", {
color: "clear-icon",
classList: ["overlay-button"],
disabled: "false"
}, { click: fetchKadastrsData });
const h6 = createElem("h6", {
classList: ["w-icon"],
textContent: "K"
});
h6.style["font-family"] = "Waze Boing Medium";
h6.style["line-height"] = "24px";
owz.appendChild(h6);
btnDiv.appendChild(owz);
mainDiv.appendChild(btnDiv);
divOverlayMain.appendChild(mainDiv);
}
function initScript() {
if (!unsafeWindow.getWmeSdk) {
throw new Error("SDK not available");
}
wmeSDK = unsafeWindow.getWmeSdk({
scriptId: "wmeUTKadastrs",
scriptName: "UrSuS Tools: Kadastrs"
});
if (typeof proj4 === "undefined") {
const oScript = document.createElement("script");
oScript.type = "text/javascript";
oScript.src = "https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4.js";
document.getElementsByTagName("head")[0].appendChild(oScript);
}
oAddHouseNumber = require("Waze/Actions/AddHouseNumber");
addKFetchButton();
fetchSheetData();
}
void unsafeWindow.SDK_INITIALIZED.then(initScript);
async function fetchKadastrsData() {
wazedevtoastr.options = {
closeButton: false,
debug: false,
newestOnTop: false,
progressBar: false,
rtl: false,
positionClass: "toast-bottom-center",
preventDuplicates: false,
onclick: null,
showDuration: 300,
hideDuration: 1000,
timeOut: 5000,
extendedTimeOut: 1000,
showEasing: "swing",
hideEasing: "linear",
showMethod: "fadeIn",
hideMethod: "fadeOut"
};
if (wmeSDK.Map.getZoomLevel() < 17) {
WazeWrap.Alerts.warning(sScriptName, `You are on ${wmeSDK.Map.getZoomLevel()} Zoom Level, HouseNumbers won't be fetched!`);
}
WazeWrap.Alerts.info(sScriptName, "KadastrsAddress Fetching started");
let sURL = "https://lvmgeoserver.lvm.lv/geoserver/publicwfs/wfs?layer=publicwfs&SERVICE=WFS&REQUEST=GetFeature";
sURL +=
"&VERSION=2.0.0&TYPENAMES=publicwfs:arisbuilding&STARTINDEX=0&COUNT=500&SRSNAME=urn:ogc:def:crs:EPSG::3059&BBOX=";
sURL += getBBox3059();
sURL += ",urn:ogc:def:crs:EPSG::3059&outputFormat=application/json";
const sVenueResponseJSON = await makeGetRequest(sURL);
processFetchedDataNewMode(sVenueResponseJSON);
}
async function processFetchedDataNewMode(responseText) {
const oParser = new OpenLayers.Format.GeoJSON();
aGlobalFetchedAddresses = oParser.read(responseText);
WazeWrap.Alerts.info(sScriptName, `${aGlobalFetchedAddresses.length} Kadastrs Address Fetched`);
let sWazeVenueURL = `https://${window.location.hostname}/row-Descartes/app/Features?bbox=${getBBoxv2()}`;
sWazeVenueURL += "&language=en-GB&v=2&venueLevel=4&venueFilter=1%2C1%2C0%2C0";
const sVenueResponseJSON = await makeGetRequest(sWazeVenueURL);
const oParsedObject = JSON.parse(sVenueResponseJSON);
let aWazeVenues = oParsedObject.venues.objects;
aWMEValidAddressVenues = [];
WazeWrap.Alerts.info(sScriptName, `${aWazeVenues.length} WME Address Fetched`);
let aWazeHouseNumbers = [];
if (wmeSDK.Map.getZoomLevel() >= 17) {
const aSegments = W.model.segments
.getObjectArray()
.filter((oObject) => oObject.getAttribute("hasHNs"));
const oMapExtGeometry = getOLMapExtent().toGeometry();
const aSegmentsOnScreen = aSegments
.map((oSegment) => {
if (oMapExtGeometry.intersects(oSegment.getAttribute("geometry"))) {
return oSegment.getID();
}
})
.filter((oItem) => !!oItem);
const oResults = await W.controller.descartesClient.getHouseNumbers(aSegmentsOnScreen);
aWazeHouseNumbers = oResults.segmentHouseNumbers.objects;
}
aMissingFetchedAddresses = [...aGlobalFetchedAddresses];
aWazeVenues.map((oVenue) => {
let { name: sStreetName, city: sCity } = findStreetName(oVenue.streetID);
let oAddressRegex;
if (!oVenue.houseNumber && sStreetName === "") {
if (oVenue.name) {
const sConverted = `"${oVenue.name.replace(", ", '", ')}${sCity !== "" ? '"' : ""}`;
oAddressRegex = getRegex([sConverted, sCity]);
}
}
else if (!oVenue.houseNumber) {
if (sStreetName.slice(-4) === "pag.") {
const aAddress = sStreetName.split(", ");
sStreetName = `"${aAddress[0]}", ${aAddress[1]}`;
}
else {
sStreetName = `"${sStreetName}"`;
}
oAddressRegex = getRegex([sStreetName, sCity]);
}
else {
const sHouseNumber = oVenue.houseNumber.toUpperCase().replace("-", " k-");
const bIsVasarnica = aVasarnicas.some(mRecord => mRecord.name === sStreetName && mRecord.parent === sCity);
if (bIsVasarnica) {
oAddressRegex = getRegex([`"${sStreetName} ${sHouseNumber}"`, sCity]);
}
else {
oAddressRegex = getRegex([`${sStreetName} ${sHouseNumber}`, sCity]);
}
}
if (oAddressRegex) {
excludeKadastrsAddressConsistentWithWME(oAddressRegex, oVenue);
}
});
WazeWrap.Alerts.info(sScriptName, `${aMissingFetchedAddresses.length} Kadastrs Addresses Not Present`);
const aConvertedAddresses = aGlobalFetchedAddresses
.map(mRowKadastrsAddress => {
const mKadastrsAddress = convertKadastrsAddressStringToParts(mRowKadastrsAddress.attributes.std, "");
if (!mKadastrsAddress) {
return undefined;
}
return {
cityName: mKadastrsAddress.cityName,
streetName: mKadastrsAddress.streetName,
houseNumber: mKadastrsAddress.houseNumber,
name: mKadastrsAddress.name,
cityId: "",
streetID: ""
};
})
.filter(oItem => !!oItem);
const iFailedAddressIndex = populateIds(aConvertedAddresses);
if (iFailedAddressIndex) {
const mMissingAddress = aGlobalFetchedAddresses[iFailedAddressIndex];
const aLonLat = proj4("EPSG:3059", "EPSG:4326", [mMissingAddress.geometry.x, mMissingAddress.geometry.y]);
wmeSDK.Map.setMapCenter({
lonLat: { lon: aLonLat[0], lat: aLonLat[1] },
zoomLevel: 19
});
}
aConvertedAddresses.forEach(mConvertedAddress => {
const sHN = mConvertedAddress.houseNumber.includes(" k-")
? mConvertedAddress.houseNumber.replace(" k-", "-")
: mConvertedAddress.houseNumber;
aWazeVenues = aWazeVenues.filter(mVenue => mVenue.streetID !== mConvertedAddress.streetID || mVenue.houseNumber?.toUpperCase() !== sHN);
});
WazeWrap.Alerts.info(sScriptName, `${aWazeVenues.length} WME Venues with incorrect or missing Addresses`);
aWazeHouseNumbers.map(oWazeHouseNumber => {
const mSegStreet = W.model.segments.getObjectById(oWazeHouseNumber.attributes.segID).getAddress().attributes
?.street?.attributes;
const { name: sStreetName, city: sCity } = findStreetName(mSegStreet.id);
const oAddressRegex = getRegex([sStreetName + " " + oWazeHouseNumber.attributes.number.toUpperCase(), sCity]);
excludeKadastrsAddressConsistentWithWME(oAddressRegex, oWazeHouseNumber);
});
addKadastrsLayerWithFeatures(aGlobalFetchedAddresses);
clearHighlightedAdressFeatures();
let bIsVenueLayerHidden = false;
aWazeVenues.forEach(oVenue => {
const OLVenue = W.map.venueLayer.getOlFeatureByFeatureId(oVenue.id);
if (!OLVenue) {
bIsVenueLayerHidden = true;
return;
}
highlightVenue2(OLVenue);
});
aWMEValidAddressVenues.forEach(oVenue => {
const OLVenue = W.map.venueLayer.getOlFeatureByFeatureId(oVenue.id);
if (!OLVenue) {
bIsVenueLayerHidden = true;
return;
}
highlightVenue2(OLVenue, true);
});
if (bIsVenueLayerHidden) {
WazeWrap.Alerts.warning(sScriptName, "Please activate Venues or Residential Layer");
}
setTimeout(() => W.map.getLayerByUniqueName("venues").redraw(), 0);
}
function addKadastrsLayerWithFeatures(aKadastrsFeatures) {
const aFeaturesForLayer = [];
const pointLayer = new OpenLayers.Layer.Vector("LVWMEKadastrsPointLayer", {
rendererOptions: {
zIndexing: true
}
});
const oExistingLayer = W.map.getLayersByName("LVWMEKadastrsPointLayer")[0];
const layerContainer = W.selectionManager.getWebMapSelectionMediator().getRootContainerLayer();
if (oExistingLayer) {
oExistingLayer.destroyFeatures();
W.map.removeLayer(oExistingLayer);
const indexToRemove = W.map.layers.indexOf(oExistingLayer);
if (indexToRemove !== -1) {
layerContainer.layers.splice(indexToRemove, 1);
}
}
aKadastrsFeatures.forEach(mFeature => {
const aCoords = proj4("EPSG:3059", "EPSG:900913", [mFeature.geometry.x, mFeature.geometry.y]);
mFeature.geometry.x = aCoords[0];
mFeature.geometry.y = aCoords[1];
const point = new OpenLayers.Geometry.Point(aCoords[0], aCoords[1]);
const featureStyle = {
label: "K",
pointRadius: 15,
fillColor: "#00695C",
fillOpacity: 0.8,
strokeColor: "#cc6633",
strokeWidth: 2,
strokeOpacity: 0.8,
fontColor: "black",
labelOutlineColor: "white",
labelOutlineWidth: 3,
repositoryObject: {
isDeleted: () => false,
isNew: () => false,
getType: () => null,
getID: () => -1
}
};
const feature = new OpenLayers.Feature.Vector(point, null, featureStyle);
feature.data = mFeature;
aFeaturesForLayer.push(feature);
});
pointLayer.addFeatures(aFeaturesForLayer);
const selectControl = new OpenLayers.Control.SelectFeature(pointLayer, {
hover: true,
onSelect: onFeatureHoverEvent,
onUnselect: onFeatureUnHoverEvent
});
W.map.addControl(selectControl);
selectControl.activate();
W.map.addLayer(pointLayer);
layerContainer.layers.push(pointLayer);
layerContainer.collectRoots();
}
function checkTooltip() {
window.clearTimeout(iPopupTimeout);
}
function onFeatureHoverEvent(e) {
window.clearTimeout(iPopupTimeout);
const mKadastrsAddress = convertKadastrsAddressStringToParts(e.data.attributes.std, "waze");
if (!mKadastrsAddress) {
return;
}
const placeGeom = e.geometry.getCentroid();
const placePt = new OpenLayers.Geometry.Point(placeGeom.x, placeGeom.y);
if (!$KadastrsMenuPopupDiv) {
$KadastrsMenuPopupDiv = createElem("div", {
id: "kadastrsMenuDiv",
style: "z-index:9998; visibility:visible; position:absolute; margin: 0px; top: 0px; left: 0px;",
"data-tippy-root": false
}, { mouseenter: checkTooltip, mouseleave: hideTooltipAfterDelay });
Object.assign($KadastrsMenuPopupDiv.style, {
zIndex: 9998,
visibility: "visible",
position: "absolute",
margin: "0px",
top: "0px",
left: "0px"
});
W.map.getEl()[0].appendChild($KadastrsMenuPopupDiv);
}
const divElemRoot = createElem("div", {
id: "kadastrsMenuDiv-tooltip",
classList: ["tippy-box"],
"data-state": "hidden",
tabindex: "-1",
"data-theme": "light-border",
"data-animation": "fade",
role: "tooltip",
"data-placement": "top",
style: "max-width: 350px; transition-duration:300ms;"
});
const divTippyContent = createElem("div", {
id: "kadastrsMenuDiv-content",
classList: ["tippy-content"],
"data-state": "hidden",
style: "transition-duration: 300ms;"
});
const oAddressTextDiv = createElem("div", {
classList: ["coordinates-wrapper"]
});
const oVenuesTextDiv = createElem("div", {
classList: ["coordinates-wrapper"],
style: "white-space: pre-wrap;"
});
let sVenues = "❌";
if (e.data.data.Venues) {
sVenues = e.data.data.Venues.map((oVenue) => oVenue.name).join("\r\n•");
if (e.data.data.Venues.length > 1) {
sVenues = "\r\n•" + sVenues + "\r\n";
}
}
oVenuesTextDiv.innerHTML = `Venues: ${sVenues} \n Residential: ${(e.data.data.Residential ?? []).length === 1 ? "✅" : e.data.data.Residential ?? "❌"} HN: ${(e.data.data.HN ?? []).length === 1 ? "✅" : e.data.data.HN ?? "❌"}`;
divTippyContent.appendChild(oVenuesTextDiv);
const oInputForm = createElem("div", {
classList: ["wz-text-input-inner-container"]
});
const oInputInput = createElem("wz-text-input", {
value: e.data.attributes.std
});
oInputInput.appendChild(oInputForm);
oAddressTextDiv.appendChild(oInputInput);
divTippyContent.appendChild(oAddressTextDiv);
const mSDKSelection = wmeSDK.Editing.getSelection();
if (mSDKSelection?.ids.length === 1) {
const oApplyAddressForm = createElem("div", {
classList: ["external-providers-control", "form-group"]
});
divTippyContent.appendChild(oApplyAddressForm);
const oApplyAddressFormLabel = createElem("wz-label", {
"html-for": ""
});
oApplyAddressFormLabel.innerText = "Apply Address to selected Venue:";
oApplyAddressForm.appendChild(oApplyAddressFormLabel);
const fnFullyApplyToSelectedClick = () => applyAddress(e, "full");
const oWZButtonFullyApplyToSelectedPlace = createElem("wz-button", {
color: "secondary",
size: "sm",
classList: ["overlay-button"],
disabled: "false",
textContent: "Full"
}, { click: fnFullyApplyToSelectedClick });
const oWZIconFullyApplyToSelectedPlace = createElem("i", {
classList: ["w-icon w-icon-location-check-fill"],
style: "font-size:18px;"
});
oWZButtonFullyApplyToSelectedPlace.prepend(oWZIconFullyApplyToSelectedPlace);
oApplyAddressForm.appendChild(oWZButtonFullyApplyToSelectedPlace);
const fnApplyKeepingNameToSelectedClick = () => applyAddress(e, "");
const oWZButtonApplyKeepingNameToSelectedPlace = createElem("wz-button", {
color: "secondary",
size: "sm",
classList: ["overlay-button"],
disabled: "false",
textContent: "Keep Name"
}, { click: fnApplyKeepingNameToSelectedClick });
const oWZIconApplyKeepingNameToSelectedPlace = createElem("i", {
classList: ["w-icon w-icon-location-fill"],
style: "font-size: 18px;"
});
oWZButtonApplyKeepingNameToSelectedPlace.prepend(oWZIconApplyKeepingNameToSelectedPlace);
oApplyAddressForm.appendChild(oWZButtonApplyKeepingNameToSelectedPlace);
const fnPasteViensetaAddressClick = () => applyAddress(e, "vienseta");
const oWZButtonApplyAsViensetaToSelectedPlace = createElem("wz-button", {
color: "secondary",
size: "sm",
classList: ["overlay-button"],
disabled: "false",
textContent: "Keep Name adding Vienseta"
}, { click: fnPasteViensetaAddressClick });
const oWZIconApplyAsViensetaToSelectedPlace = createElem("i", {
classList: ["w-icon w-icon-home"],
style: "font-size: 18px;"
});
oWZButtonApplyAsViensetaToSelectedPlace.prepend(oWZIconApplyAsViensetaToSelectedPlace);
oApplyAddressForm.appendChild(oWZButtonApplyAsViensetaToSelectedPlace);
}
const oCreateVenueForm = createElem("div", {
classList: ["external-providers-control", "form-group"]
});
divTippyContent.appendChild(oCreateVenueForm);
const oCreateVenueFormLabel = createElem("wz-label", {
"html-for": ""
});
oCreateVenueFormLabel.innerText = "Create Venue:";
oCreateVenueForm.appendChild(oCreateVenueFormLabel);
if (!e.data.data.Residential) {
const fnCreateResidentialClick = () => createResidential(e);
const oWZIconCreateResidential = createElem("i", {
classList: ["w-icon w-icon-navigation-now-fill"],
style: "font-size:18px;"
});
const oWZButtonCreateResidential = createElem("wz-button", {
color: "secondary",
size: "sm",
classList: ["overlay-button"],
disabled: "false",
textContent: "Residential"
}, { click: fnCreateResidentialClick });
oWZButtonCreateResidential.prepend(oWZIconCreateResidential);
oCreateVenueForm.appendChild(oWZButtonCreateResidential);
}
if (!e.data.data.HN) {
const fnCreateHNClick = () => createHN(e);
const oWZButtonCreateHN = createElem("wz-button", {
color: "secondary",
size: "sm",
classList: ["overlay-button"],
disabled: "false",
textContent: "HN"
}, { click: fnCreateHNClick });
const oWZIconCreateHN = createElem("i", {
classList: ["w-icon w-icon-home"],
style: "font-size:18px;"
});
oWZButtonCreateHN.prepend(oWZIconCreateHN);
oCreateVenueForm.appendChild(oWZButtonCreateHN);
}
const fnForceCreateClick = () => createVenue(e);
const oWZButtonCreatePlace = createElem("wz-button", {
color: "secondary",
size: "sm",
classList: ["overlay-button"],
disabled: "false",
textContent: `${e.data.data.Venues ? "Force Create Place" : "Place"}`
}, { click: fnForceCreateClick });
const oWZIconCreatePlace = createElem("i", {
classList: ["w-icon w-icon-polygon"],
style: "font-size:18px;"
});
oWZButtonCreatePlace.prepend(oWZIconCreatePlace);
oCreateVenueForm.appendChild(oWZButtonCreatePlace);
divElemRoot.appendChild(divTippyContent);
$KadastrsMenuPopupDiv.replaceChildren(divElemRoot);
const aLonLat = proj4("EPSG:900913", "EPSG:4326", [placeGeom.x, placeGeom.y]);
const mPopupPixelPosition = W.map.getPixelFromLonLat({
lon: aLonLat[0],
lat: aLonLat[1]
});
mPopupPixelPosition.origX = mPopupPixelPosition.x;
$KadastrsMenuPopupDiv.clientWidth / 2;
const dataPlacement = "right";
$KadastrsMenuPopupDiv.style.transform = `translate(${Math.round(mPopupPixelPosition.x + 24)}px, ${Math.round(mPopupPixelPosition.y - 24)}px)`;
$KadastrsMenuPopupDiv.querySelector("#kadastrsMenuDiv-tooltip")?.setAttribute("data-placement", dataPlacement);
$KadastrsMenuPopupDiv.querySelector("#kadastrsMenuDiv-tooltip")?.setAttribute("data-state", "visible");
$KadastrsMenuPopupDiv.querySelector("#kadastrsMenuDiv-content")?.setAttribute("data-state", "visible");
let aFoundVenues = [];
if (e.data.data.Venues) {
aFoundVenues = [...aFoundVenues, ...e.data.data.Venues];
}
if (e.data.data.Residential) {
aFoundVenues = [...aFoundVenues, ...e.data.data.Residential];
}
if (e.data.data.HN) {
aFoundVenues = [...aFoundVenues, ...e.data.data.HN];
}
aHoverFeatures = [];
aFoundVenues.forEach(sFoundVenueKey => {
highlightVenue(sFoundVenueKey);
});
aFoundVenues.forEach(sFoundVenueKey => {
drawConnectionLines(sFoundVenueKey, placePt);
});
aHoverFeatures = [...aAddressConnectionLinesFeatures];
W.map.getLayerByUniqueName("venues").addFeatures(aHoverFeatures);
setTimeout(() => W.map.getLayerByUniqueName("venues").redraw(), 0);
}
function createGeometry(e) {
const vertex = 29.4;
const poly = new OpenLayers.Geometry.LinearRing([
new OpenLayers.Geometry.Point(e.data.geometry.x - vertex, e.data.geometry.y - vertex / 2),
new OpenLayers.Geometry.Point(e.data.geometry.x - vertex, e.data.geometry.y + vertex / 2),
new OpenLayers.Geometry.Point(e.data.geometry.x + vertex, e.data.geometry.y + vertex / 2),
new OpenLayers.Geometry.Point(e.data.geometry.x + vertex, e.data.geometry.y - vertex / 2),
new OpenLayers.Geometry.Point(e.data.geometry.x - vertex, e.data.geometry.y - vertex / 2)
]);
poly.rotate(10, poly.getCentroid());
return new OpenLayers.Geometry.Polygon([poly]);
}
function applyAddress(e, sMode) {
const mAddressBuffer = convertKadastrsAddressStringToParts(e.data.attributes.std, "waze");
if (!mAddressBuffer) {
return;
}
const selection = wmeSDK.Editing.getSelection();
if (!selection || selection.objectType !== "venue") {
return;
}
if (selection.ids.length > 0) {
if (sMode === "vienseta") {
let oStreet = findStreetId(mAddressBuffer.cityName, mAddressBuffer.name);
if (!oStreet) {
oStreet = findStreetId(`${mAddressBuffer.cityName}, ${mAddressBuffer.pagastsName}`, mAddressBuffer.name);
}
if (!oStreet) {
const oNewStreet = wmeSDK.DataModel.Streets.addStreet({
cityId: mAddressBuffer.cityID,
streetName: mAddressBuffer.name
});
updateVenue(selection.ids[0].toString(), { streetID: oNewStreet.id });
}
else {
updateVenue(selection.ids[0].toString(), { streetID: oStreet.attributes.id });
}
}
else {
updateVenue(selection.ids[0].toString(), {
houseNumber: mAddressBuffer.houseNumber,
streetID: mAddressBuffer.streetID,
name: sMode === "full" ? mAddressBuffer.name : undefined
});
}
}
}
function updateVenue(sVenueId, mAddressData) {
if (mAddressData.houseNumber?.includes(" k-")) {
mAddressData.houseNumber = mAddressData.houseNumber.replace(" k-", "-");
}
if (mAddressData.streetID) {
wmeSDK.DataModel.Venues.updateAddress({
venueId: sVenueId,
houseNumber: mAddressData.houseNumber,
streetId: mAddressData.streetID
});
}
if (mAddressData.name) {
try {
wmeSDK.DataModel.Venues.updateVenue({
venueId: sVenueId,
name: mAddressData.name,
lockRank: 2
});
}
catch (oError) {
}
}
}
function createResidential(e) {
const WMEAddressParams = convertKadastrsAddressStringToParts(e.data.attributes.std, "waze");
if (!WMEAddressParams) {
return;
}
const oGeometry = createGeometry(e);
const movedPoi = oGeometry.getCentroid();
movedPoi.x += 7;
movedPoi.y -= 7;
const sVenueId = wmeSDK.DataModel.Venues.addVenue({
category: "RESIDENTIAL",
geometry: W.userscripts.toGeoJSONGeometry(movedPoi)
}).toString();
updateVenue(sVenueId, WMEAddressParams);
wmeSDK.Editing.setSelection({
selection: {
ids: [sVenueId],
objectType: "venue"
}
});
}
function createHN(e) {
const WMEAddressParams = convertKadastrsAddressStringToParts(e.data.attributes.std, "waze");
if (!WMEAddressParams) {
return;
}
const oGeometry = createGeometry(e);
const aStreetSegments = W.model.segments.getByAttributes({
primaryStreetID: WMEAddressParams.streetID
});
if (aStreetSegments.length > 0) {
const closestSegment = aStreetSegments.reduce((min, segment) => oGeometry.distanceTo(segment.getOLGeometry(), { details: true }).distance <
oGeometry.distanceTo(min.getOLGeometry(), { details: true }).distance
? segment
: min);
const oHNPoint = oGeometry.getCentroid();
oHNPoint.x += 7;
oHNPoint.y += 7;
const fractionPoint = findClosestPoint(oHNPoint, closestSegment.getOLGeometry());
if (!fractionPoint) {
return;
}
const oFractionPoint = new OpenLayers.Geometry.Point(fractionPoint.x, fractionPoint.y);
const epsg900913 = new OpenLayers.Projection("EPSG:900913");
const epsg4326 = new OpenLayers.Projection("EPSG:4326");
oHNPoint.transform(epsg900913, epsg4326);
oFractionPoint.transform(epsg900913, epsg4326);
const oHouseNumber = new Vs({
forced: false,
fractionPoint: {
coordinates: [oFractionPoint.x, oFractionPoint.y],
type: "Point"
},
geoJSONGeometry: {
coordinates: [oHNPoint.x, oHNPoint.y],
type: "Point"
},
number: WMEAddressParams.houseNumber,
segID: closestSegment.getID(),
id: W.model.segmentHouseNumbers.generateUniqueID()
});
W.model.actionManager.add(new oAddHouseNumber(oHouseNumber));
}
}
function createVenue(e) {
const WMEAddressParams = convertKadastrsAddressStringToParts(e.data.attributes.std, "waze");
if (!WMEAddressParams) {
alert(`Street not found on map. Please check if it actually exist ${e.data.attributes.std}`);
return;
}
const oGeometry = createGeometry(e);
const sVenueId = wmeSDK.DataModel.Venues.addVenue({
category: "OTHER",
geometry: W.userscripts.toGeoJSONGeometry(oGeometry)
}).toString();
updateVenue(sVenueId, WMEAddressParams);
wmeSDK.Editing.setSelection({
selection: {
ids: [sVenueId],
objectType: "venue"
}
});
}
function drawConnectionLines(foundVenueKey, placePt) {
const label = "";
let placeGeomTarget;
if (foundVenueKey.type === "houseNumber") {
placeGeomTarget = foundVenueKey.getOLGeometry().getCentroid();
}
else {
placeGeomTarget = W.model.venues.objects[foundVenueKey.id].getOLGeometry().getCentroid();
}
const poiPt = new OpenLayers.Geometry.Point(placeGeomTarget.x, placeGeomTarget.y);
const lsLine = new OpenLayers.Geometry.LineString([placePt, poiPt]);
const addressConnectionLineFeature = new OpenLayers.Feature.Vector(lsLine, {}, {
strokeWidth: 3,
strokeDashstyle: "12 8",
strokeColor: "#FF0",
label,
labelYOffset: 45,
fontColor: "#FF0",
fontWeight: "bold",
labelOutlineColor: "#000",
labelOutlineWidth: 4,
fontSize: "18"
});
aAddressConnectionLinesFeatures.push(addressConnectionLineFeature);
}
function highlightVenue(foundVenue, placePt) {
if (foundVenue.type === "houseNumber") ;
else {
const placeGeomTarget = W.model.venues.objects[foundVenue.id].getOLGeometry().getCentroid();
new OpenLayers.Geometry.Point(placeGeomTarget.x, placeGeomTarget.y);
const OLVenue = W.map.venueLayer.getOlFeatureByFeatureId(foundVenue.id);
if (OLVenue.geometry.getArea() !== 0) {
OLVenue.geometry.getGeodesicArea(W.map.getProjectionObject());
}
if (OLVenue.geometry.getArea() !== 0) {
const mStyle = {
fillColor: "#00695C",
fillOpacity: 0.5,
strokeWidth: 3,
strokeDashstyle: "12 8",
strokeColor: "blue",
label: "",
labelYOffset: 45,
fontColor: "#FF0",
fontWeight: "bold",
labelOutlineColor: "#000",
labelOutlineWidth: 4,
fontSize: "18"
};
OLVenue.style = mStyle;
aWMEPolygonHighlightBlueFeatures.push(OLVenue);
}
}
}
function hideTooltipAfterDelay() {
iPopupTimeout = window.setTimeout(hideCustomPopup, 300);
}
function onFeatureUnHoverEvent(e) {
hideTooltipAfterDelay();
aAddressConnectionLinesFeatures.forEach(feature => {
feature.destroy();
feature = null;
});
aAddressConnectionLinesFeatures = [];
aWMEPolygonHighlightBlueFeatures.forEach(feature => {
feature.style = null;
});
aWMEPolygonHighlightBlueFeatures = [];
setTimeout(() => W.map.getLayerByUniqueName("venues").redraw(), 0);
}
function highlightVenue2(OLVenue, bIsValid) {
if (OLVenue.geometry.getArea() !== 0) {
OLVenue.geometry.getGeodesicArea(W.map.getProjectionObject());
}
if (OLVenue.geometry.getArea() !== 0) {
const mStyle = {
fillColor: "#00695C",
fillOpacity: 0.5,
strokeWidth: 3,
strokeDashstyle: "12 8",
strokeColor: `${bIsValid ? "green" : "red"}`,
label: "",
labelYOffset: 45,
fontColor: "#FF0",
fontWeight: "bold",
labelOutlineColor: "#000",
labelOutlineWidth: 4,
fontSize: "18"
};
OLVenue.style = mStyle;
aWMEPolygonHighlightFeatures.push(OLVenue);
}
}
function clearHighlightedAdressFeatures() {
if (aWMEPolygonHighlightFeatures.length > 0) {
let layer = aWMEPolygonHighlightFeatures[0].layer;
aWMEPolygonHighlightFeatures.forEach(feature => {
feature.style = null;
layer = feature.layer;
});
layer?.redraw();
aWMEPolygonHighlightFeatures = [];
}
}
function hideCustomPopup() {
if ($KadastrsMenuPopupDiv) {
$KadastrsMenuPopupDiv.querySelector("#kadastrsMenuDiv-content")?.setAttribute("data-state", "hidden");
$KadastrsMenuPopupDiv.querySelector("#kadastrsMenuDiv-tooltip")?.setAttribute("data-state", "hidden");
$KadastrsMenuPopupDiv.replaceChildren();
}
}
function findStreetId(sCityName, sStreetName, bVienseta) {
return Object.values(W.model.streets.objects).find((street) => {
if (!W.model.cities.objects[street.attributes.cityID]) {
console.log("Error: no City");
}
if (street.attributes.name === sStreetName &&
W.model.cities.objects[street.attributes.cityID].attributes.name.includes(sCityName)) {
return true;
}
});
}
function populateIds(addresses) {
const streetCache = {};
for (const [index, address] of addresses.entries()) {
if (!streetCache[address.streetName]) {
const oStreet = findStreetId(address.cityName, address.streetName);
if (!oStreet && address.streetName !== "") {
const sErrorMsg = "Error: Can't find street: " + address.streetName + " in City: " + address.cityName;
console.log(sErrorMsg);
alert(sErrorMsg);
return index;
}
if (oStreet) {
streetCache[address.streetName] = oStreet.attributes.id;
}
}
address.streetID = streetCache[address.streetName];
}
return undefined;
}
function convertKadastrsAddressStringToParts(sAddress, sMode) {
const aAddress = sAddress.split(", ");
const bNoCity = aAddress[1].slice(-4) === "pag.";
const sCityName = bNoCity ? "" : aAddress[1];
const sPagastsName = bNoCity ? aAddress[1] : aAddress[2];
bNoCity ? aAddress[2] : aAddress[3];
bNoCity ? aAddress[3] : aAddress[4];
const sStreetNameOrHN = aAddress[0];
let sName = "";
let sHN = "";
let bVienseta = false;
let bVasarnica = false;
if (bNoCity) {
sName = `${sStreetNameOrHN.slice(1, -1)}, ${sPagastsName}`;
const sStreetName = "";
return {
cityName: sCityName,
streetName: sStreetName,
houseNumber: sHN,
name: sName
};
}
else {
if (sStreetNameOrHN.startsWith('"') && sStreetNameOrHN.endsWith('"')) {
sName = sStreetNameOrHN.slice(1, -1);
const aVasarnica = sName.split(" ");
const sLast = aVasarnica.pop();
const sVasarnicaName = aVasarnica.join(" ");
const bIsVasarnica = aVasarnicas.some(mRecord => mRecord.name === sVasarnicaName && mRecord.parent === aAddress[1]);
if (bIsVasarnica) {
bVasarnica = true;
sHN = aVasarnica.length > 0 ? sLast ?? "" : "";
sName = sHN;
}
else {
bVienseta = true;
}
}
else {
const aStreetNameAndHN = sStreetNameOrHN.split(" ");
sName = "";
sHN = aStreetNameAndHN.pop() ?? "";
if (sHN.includes("k-")) {
sHN = `${aStreetNameAndHN.pop()} ${sHN}`;
sName = sHN.replace(" k", "");
}
else {
sName = sHN;
}
}
const iLastIndex = sStreetNameOrHN.lastIndexOf(" " + sHN);
const sStreetName = sHN === ""
? ""
: iLastIndex === -1
? sStreetNameOrHN
: bVasarnica
? sStreetNameOrHN.substring(1, iLastIndex)
: sStreetNameOrHN.substring(0, iLastIndex);
if (sMode !== "waze") {
return {
cityName: sCityName,
streetName: bVienseta ? "" : sStreetName,
houseNumber: sHN,
name: sName
};
}
else {
const oStreet = Object.values(W.model.streets.objects).find((street) => {
if (street.attributes.name === sStreetName &&
W.model.cities.objects[street.attributes.cityID].attributes.name.includes(sCityName)) {
return true;
}
});
let oCity;
if (!oStreet) {
oCity = Object.values(W.model.cities.objects).find((oCity) => {
return oCity.attributes.name === sCityName;
});
}
return {
cityID: oStreet ? oStreet.attributes.cityID : oCity ? oCity.attributes.id : undefined,
streetID: oStreet ? oStreet.attributes.id : undefined,
houseNumber: sHN,
name: sName,
cityName: sCityName,
pagastsName: sPagastsName
};
}
}
}
function makeGetRequest(sURL) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: "GET",
url: sURL,
onload: response => resolve(response.responseText),
onerror: error => reject(error)
});
});
}
function excludeKadastrsAddressConsistentWithWME(oAddressRegex, oVenueOrHouseNumber) {
const indexToRemove = aMissingFetchedAddresses.findIndex(mFetchedAddresses => oAddressRegex.test(mFetchedAddresses.attributes.std));
if (indexToRemove > -1) {
aMissingFetchedAddresses.splice(indexToRemove, 1);
}
const indexToUpdate = aGlobalFetchedAddresses.findIndex(mFetchedAddresses => oAddressRegex.test(mFetchedAddresses.attributes.std));
if (indexToUpdate > -1) {
if (oVenueOrHouseNumber.type === "houseNumber") {
if (!aGlobalFetchedAddresses[indexToUpdate].data.HN) {
aGlobalFetchedAddresses[indexToUpdate].data.HN = [];
}
aGlobalFetchedAddresses[indexToUpdate].data.HN.push(oVenueOrHouseNumber);
}
else {
aWMEValidAddressVenues.push(oVenueOrHouseNumber);
if (oVenueOrHouseNumber.categories[0] === "RESIDENCE_HOME") {
if (!aGlobalFetchedAddresses[indexToUpdate].data.Residential) {
aGlobalFetchedAddresses[indexToUpdate].data.Residential = [];
}
aGlobalFetchedAddresses[indexToUpdate].data.Residential.push(oVenueOrHouseNumber);
}
else {
if (!aGlobalFetchedAddresses[indexToUpdate].data.Venues) {
aGlobalFetchedAddresses[indexToUpdate].data.Venues = [];
}
aGlobalFetchedAddresses[indexToUpdate].data.Venues.push(oVenueOrHouseNumber);
}
}
}
}
function getRegex(aStrings) {
const regexPattern = aStrings.map(v => v).join("\\s*,\\s*");
return new RegExp(regexPattern);
}
function findStreetName(iStreetId) {
if (!W.model.streets.objects[iStreetId]) {
return {
name: "",
city: ""
};
}
const sName = W.model.streets.objects[iStreetId].attributes.name;
const iCity = W.model.streets.objects[iStreetId].attributes.cityID;
const sCity = W.model.cities.objects[iCity].attributes.countryID === 123 ? W.model.cities.objects[iCity].attributes.name : "";
return {
name: sName,
city: sCity
};
}
function getBBoxv2() {
const mapExtent = W.map.getExtent();
return mapExtent.toString();
}
function getBBox3059() {
const extent = W.map.getExtent();
if (Array.isArray(extent)) {
proj4.defs("EPSG:3059", "+proj=tmerc +lat_0=0 +lon_0=24 +k=0.9996 +x_0=500000 +y_0=-6000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs");
const aConvertedPoints = [
...proj4("EPSG:4326", "EPSG:3059", extent.slice(0, 2)).reverse(),
...proj4("EPSG:4326", "EPSG:3059", extent.slice(2, 4)).reverse()
];
const string = aConvertedPoints.join();
return string;
}
}
class Vs {
type = "houseNumber";
attributes;
_prevID;
version;
state;
constructor(e) {
this.attributes = e;
}
static defaults() {
return {
forced: false,
fractionPoint: null,
id: "",
side: null,
valid: false
};
}
changeID(e) {
(this._prevID = this.getID()), this.setID(e);
}
merge(e) {
Object.assign(this.attributes, e);
}
setID(e) {
this.attributes.id = e;
}
setVersion(e) {
this.version = e;
}
setState(e) {
this.state = e;
}
getAttributes() {
return this.attributes;
}
getAttribute(e) {
return this.attributes[e];
}
getGeometry() {
return this.getAttribute("geoJSONGeometry");
}
getID() {
return this.attributes.id;
}
getUniqueIdentifier() {
return {
objectId: this.getID(),
objectType: this.getType()
};
}
getUniqueID() {
return `${this.getType()}: ${this.getID()}`;
}
getType() {
return this.type;
}
getSide() {
return this.attributes.side;
}
getSegmentId() {
return this.attributes.segID;
}
setSegmentId(e) {
this.attributes.segID = e;
}
getNumber() {
return this.attributes.number;
}
setNumber(e) {
this.attributes.number = e;
}
isForced() {
return this.attributes.forced;
}
isValid() {
return this.attributes.valid;
}
getFractionPoint() {
return this.attributes.fractionPoint;
}
setFractionPoint(e) {
this.attributes.fractionPoint = e;
}
isDeleted() {
return Boolean(this.state && this.state === "DELETE");
}
}
function findClosestPoint(point, lineString) {
let closestPoint = null;
let closestDistance = Infinity;
for (let i = 0; i < lineString.components.length - 1; i++) {
const segmentStart = lineString.components[i];
const segmentEnd = lineString.components[i + 1];
const segmentVector = {
x: segmentEnd.x - segmentStart.x,
y: segmentEnd.y - segmentStart.y
};
const pointVector = {
x: point.x - segmentStart.x,
y: point.y - segmentStart.y
};
const dotProduct = pointVector.x * segmentVector.x + pointVector.y * segmentVector.y;
const t = dotProduct / (segmentVector.x * segmentVector.x + segmentVector.y * segmentVector.y);
const closestPointOnSegment = {};
if (t < 0) {
closestPointOnSegment.x = segmentStart.x;
closestPointOnSegment.y = segmentStart.y;
}
else if (t > 1) {
closestPointOnSegment.x = segmentEnd.x;
closestPointOnSegment.y = segmentEnd.y;
}
else {
closestPointOnSegment.x = segmentStart.x + t * segmentVector.x;
closestPointOnSegment.y = segmentStart.y + t * segmentVector.y;
}
const distance = calculateDistance(closestPointOnSegment, point);
if (distance < closestDistance) {
closestDistance = distance;
closestPoint = closestPointOnSegment;
}
}
return closestPoint;
}
function calculateDistance(point1, point2) {
const dx = point1.x - point2.x;
const dy = point1.y - point2.y;
return Math.sqrt(dx * dx + dy * dy);
}
})(proj4);