您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Miscelannia
当前为
// ==UserScript== // @name LV WME Helper // @namespace https://dev.laacz.lv/ // @description Miscelannia // @include https://www.waze.com/*/editor* // @include https://www.waze.com/editor* // @include https://beta.waze.com/* // @exclude https://www.waze.com/*user/*editor/* // @require https://gf.qytechs.cn/scripts/24851-wazewrap/code/WazeWrap.js // @require https://cdnjs.cloudflare.com/ajax/libs/axios/0.25.0/axios.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/jsts/2.0.6/jsts.min.js // @license CC-BY-4.0; https://creativecommons.org/licenses/by/4.0/ // @version 2.03 // @white // @connect waze.dev.laacz.lv // @grant GM.xmlHttpRequest // ==/UserScript== // noinspection DuplicatedCode /* global W */ /* global WazeWrap */ /* global axios */ (function () { /** * @typedef Address * @property code {number} * @property name {string} * @property waze_house_number {string} * @property iela_name {string} * @property ciems_name {string} * @property pilseta_name {string} * @property pagasts_name {string} * @property novads_name {string} * @property full_name {string} * @property parent_code {number} * @property geom {object} * @property lat {float} * @property lng {float} * @property Point {Point} */ /** * Fetched and mutated address list. * @type {Address[]} */ let addresses = []; // Reassigned by requure() let UpdateObject = null; let Landmark = null; let AddLandmark = null; let DeleteSegment = null; // Regluar expressions for validating stuff const reStreetNames = /(^.+(aleja|apvedceļš|bulvāris|ceļš|dambis|gatve|iela|krastmala|laukums|līnija|prospekts|šķērslīnija|šoseja) (\d+.+$))/; const reHN = /^(\d+[a-zA-Z]*)( k-\d+)?$/; // Game loop's interval let updateTimeout = undefined; // Indicates that REST request is in progress let wmelvLoadingIndicator = true; function wmelvLoading(value) { if (value !== undefined) { wmelvLoadingIndicator = value; qs('#wmelv-loading-indicator').style.visibility = value ? 'visible' : 'hidden'; } return wmelvLoadingIndicator; } /** * Stores last clicked point on the map * @type {Point|null} */ let lastClick = null; /** * Settings object with getters, setters, and default values. */ const settings = { configuration: { minHNZoomLevel: 16, hlIncorrectAddress: true, hlSmallArea: true, hlLowerCaseHN: true, hlNoHN: true, hlNameHNMismatch: true, addressFixer: false, hlDupes: true, hlIela: true, autoHN: false, // autoHNSegmentSelection: true, }, get: function (key, def) { return typeof this.configuration[key] !== 'undefined' ? this.configuration[key] : def; }, set: function (key, value) { this.configuration[key] = value; this.save(); }, save() { if (localStorage) { localStorage.setItem("_wmelv3_settings", JSON.stringify(this.configuration)); } }, load() { let loadedSettings = JSON.parse(localStorage.getItem("_wmelv3_settings")); this.config = Object.assign(this.configuration, loadedSettings ? loadedSettings : {}); } }; /** * querySelectorAll shorthand * @param selector * @returns {*[]} */ function qsa(selector) { return Array.from(document.querySelectorAll(selector), e => e); } /** * querySelector shorthand. * @param selector * @returns {*} */ function qs(selector) { return document.querySelector(selector); } /** * Shamelessly taken from WME PlaceNames Russian: * https://gf.qytechs.cn/en/scripts/15310-wme-placenames-russian/code */ function fixPlaceArea(place) { let requiredArea = 516, oldGeometry = place.geometry.clone(), newGeometry = place.geometry.clone(), centerPT = newGeometry.getCentroid(), oldArea = oldGeometry.getGeodesicArea(W.map.getProjectionObject()), scale = Math.sqrt(requiredArea / oldArea); newGeometry.resize(scale, centerPT); let wazeActionUpdateFeatureGeometry = require("Waze/Action/UpdateFeatureGeometry"), action = new wazeActionUpdateFeatureGeometry(place, W.model.venues, oldGeometry, newGeometry); place.attributes.fixArea = false; W.model.actionManager.add(action); } function fixCurrentlySelectedArea(e) { if (e) e.preventDefault(); if (!W.selectionManager.hasSelectedFeatures() || W.selectionManager.getSelectedFeatures()[0].model.type !== "venue" || !W.selectionManager.getSelectedFeatures()[0].model.isGeometryEditable()) { return; } fixPlaceArea(W.selectionManager.getSelectedFeatures()[0].model); wmelvUpdate(); } /** * Colorful logger ;) * @type {{warn(...[*]): void, debug(...[*]): void, crit(...[*]): void, log(*, ...[*]): void, info(...[*]): void}} */ const Logger = { log(style, ...args) { console.log("%c●%c", style, 'color: #000; background-color: #fff;', ...args) }, debug(...args) { Logger.log('background-color: gray; color: #fff; font-weight: bold; padding: .2em .5em;', ...args) }, info(...args) { Logger.log('background-color: navy; color: #fff; font-weight: bold; padding: .2em .5em;', ...args) }, crit(...args) { Logger.log('background-color: maroon; color: #fff; font-weight: bold; padding: .2em .5em;', ...args) }, warn(...args) { Logger.log('background-color: orange; color: #fff; font-weight: bold; padding: .2em .5em;', ...args) }, } /** * Returns closest address to a given point on the map. * @param point {OpenLayers.Geometry.Point} * @return Address|null */ function getClosestAddress(point) { return addresses.length ? addresses.reduce((prev, curr) => { if (!prev) return curr; return prev.Point.distanceTo(point) < curr.Point.distanceTo(point) ? prev : curr; }) : null; } /** * Helper to build a bbox string from the map's extent. * @returns {string} */ function wmelvBBOX() { const bounds = W.map.getExtent(); bounds.transform("EPSG:900913", "EPSG:4326"); return bounds.toBBOX(); } /** * Adds stuff to addresses which cannot be added in the backend. * @param addresses * @returns {*} */ function wmelvMutateAddresses(addresses) { if (addresses && addresses.length) { addresses = addresses.map((ads) => { ads.Point = new OpenLayers.Geometry.Point(ads.lng, ads.lat); return ads; }) } return addresses; } /** * Creates a new place, given a geometry and attributes, selects it and registers in the actionmanager's history. * @param geometry * @param params * @returns {*} */ function wmelvCreateNewPlace(geometry, params) { let place = new Landmark(); if (!params) params = {}; if (!params.categories || !params.categories.length) params.categories = ["OTHER"]; place.geometry = geometry; place.attributes.name = params.name ? params.name : ''; place.attributes.lockRank = params.lockRank ? params.lockRank : 2; params.categories.forEach(cat => { place.attributes.categories.push(cat); }); place.attributes.entryExitPoints.push(new NavigationPoint(place.geometry.getCentroid())); W.model.actionManager.add(new AddLandmark(place)); W.selectionManager.setSelectedModels([place]); if (params.address && Object.keys(params.address).length) { W.model.actionManager.add(new UpdateObject(place, params.address)); } return place; } function fixCurrentlySelectedVenueAddress() { } /** * Game loop as they say. */ function wmelvUpdate() { if (updateTimeout) { clearTimeout(updateTimeout); } if (!wmelvLoading) { Object.keys(W.model.venues.objects).forEach((k) => { // Object.values(W.model.venues.objects).forEach((v) => { const venue = W.model.venues.objects[k]; const centroid = venue.geometry.getCentroid(); centroid.transform('EPSG:900913', "EPSG:4326"); const closest = getClosestAddress(centroid); const el = qs('#' + venue.geometry.id); if (!el) { return } if (closest && 'attributes' in venue) { let v = venue.attributes; // Logger.info(v.attributes.name, 'closest address is', closest.full_name) let hn = v.houseNumber; let street = {name: ''}; let city = {name: ''}; if (v.streetID) { street = W.model.streets.objects[v.streetID]; } if (street) { city = W.model.cities.objects[street.cityID].attributes } const full_address = `${hn}, ${street.name}, ${city.name}`; const area = W.model.venues.objects[k].geometry.toString().indexOf('POLYGON') === 0 ? W.model.venues.objects[k].geometry.getGeodesicArea(W.map.getProjectionObject()) : false; W.model.venues.objects[k].attributes.fixLowerCase = (v.houseNumber && v.houseNumber.toUpperCase() !== v.houseNumber) || (v.houseNumber && v.name && v.name.toUpperCase() === v.houseNumber.toUpperCase() && v.name !== v.houseNumber.toUpperCase()) || (v.name && v.name.replace(/ k-\d+$/, '').match(/^\d+[a-z]+/) && v.name.replace(/ k-\d+$/, '').toUpperCase() !== v.name.replace(/ k-\d+$/, '')); W.model.venues.objects[k].attributes.fixNameHNMismatch = !v.residential && ((v.houseNumber && !v.name) || (v.houseNumber && v.name && v.name.match(reHN) && v.houseNumber.toLowerCase() !== v.name.toLowerCase().replace(' k-', '-'))); W.model.venues.objects[k].attributes.fixNoHN = !v.houseNumber && v.streetID && W.model.streets.objects[v.streetID] && W.model.streets.objects[v.streetID].name && W.model.streets.objects[v.streetID].cityID && W.model.cities.objects[W.model.streets.objects[v.streetID].cityID] && W.model.cities.objects[W.model.streets.objects[v.streetID].cityID].attributes.name && v.categories.indexOf('PARKING_LOT') === -1 && v.categories.indexOf('TAXI_STATION') === -1 && v.categories.indexOf('PARK') === -1; W.model.venues.objects[k].attributes.fixIela = v.name.toLowerCase().match(reStreetNames); W.model.venues.objects[k].attributes.fixArea = !v.residential && area !== false && area < 509 ? area : false; // wmelvCounts.fixArea += !!W.model.venues.objects[k].attributes.fixArea; // wmelvCounts.fixLowerCase += !!W.model.venues.objects[k].attributes.fixLowerCase; // wmelvCounts.fixIela += !!W.model.venues.objects[k].attributes.fixIela; W.model.venues.objects[k].attributes.fixAddress = closest.waze_name !== full_address && v.categories.indexOf('PARKING_LOT') === -1 && v.categories.indexOf('TAXI_STATION') === -1 && v.categories.indexOf('PARK') === -1; W.model.venues.objects[k].attributes.ads = closest; // if (full_address !== closest.waze_name) { // Logger.warn(`[${full_address}] is not at [${closest.waze_name}]`) // el.setAttribute('stroke', '#ff0000'); // el.setAttribute("stroke-width", "4"); // el.setAttribute("stroke-dash-array", "none"); // } } else { // Logger.warn(v.attributes.name, 'has no closest address') } }); wmelvDraw(); } updateTimeout = setTimeout(wmelvUpdate, 345); } /** * Updates visualizations. */ function wmelvDraw() { Object.values(W.model.venues.objects).forEach((v) => { let el = qs('#' + v.geometry.id), hled = false; if (el) { if (!el.getAttribute('ogAttributes')) { el.setAttribute('ogAttributes', { 'stroke': el.getAttribute('stroke'), "stroke-width": el.getAttribute("stroke-width"), "stroke-dash-array": el.getAttribute("stroke-dash-array"), }); } if (!hled && settings.get('hlIncorrectAddress') && v.attributes.fixAddress) { el.setAttribute('stroke', '#ff00ff'); el.setAttribute("stroke-width", "4"); el.setAttribute("stroke-dash-array", "none"); hled = true; } if (!hled && ((settings.get('hlLowerCaseHN') && v.attributes.fixLowerCase) || (settings.get('hlNoHN') && v.attributes.fixNoHN) || (settings.get('hlIela') && v.attributes.fixIela))) { el.setAttribute('stroke', '#ff0000'); el.setAttribute("stroke-width", "4"); el.setAttribute("stroke-dash-array", "none"); hled = true; } if (!hled && settings.get('hlSmallArea') && el && v.attributes.fixArea) { el.setAttribute('stroke', '#0000ff'); el.setAttribute("stroke-width", "4"); el.setAttribute("stroke-dash-array", "none"); hled = true; } if (!hled && settings.get('hlNameHNMismatch') && el && v.attributes.fixNameHNMismatch) { el.setAttribute('stroke', '#ffff00'); el.setAttribute("stroke-width", "4"); el.setAttribute("stroke-dash-array", "none"); hled = true; } if (!hled && settings.get('hlDupes') && el && v.attributes.fixDupes) { el.setAttribute('stroke', '#00ffff'); el.setAttribute("stroke-width", "4"); el.setAttribute("stroke-dash-array", "none"); hled = true; } // const shouldRevert = !hled && el.getAttribute('ogAttributes').all((k, v) => el.getAttribute(k) === v); // if (!hled) { // Logger.info('Reverting HL'); // const attrs = el.getAttribute('ogAttributes'); // el.setAttribute('stroke', attrs['stroke']); // el.setAttribute("stroke-width", attrs["stroke-width"]); // el.setAttribute("stroke-dash-array", attrs["stroke-dash-array"]); // } } }); } /** * Fetches VZD addresses from an API. Restricts to viewport plus a tiny buffer. */ function wmeLoadAddresses() { if (!settings.get('autoHN') || W.map.getZoom() < 16) { if (W.map.getLayersByName("pointLayer").length) { W.map.removeLayer(W.map.getLayersByName("pointLayer")[0]); } return; } const request = { bounds: wmelvBBOX(), } wmelvLoading(true); GM.xmlHttpRequest({ method: 'POST', url: '//waze.dev.laacz.lv/api/2/addresses', data: JSON.stringify(request), headers: { 'Content-Type': 'application/json' }, onload: function (response) { addresses = JSON.parse(response.responseText); addresses = wmelvMutateAddresses(addresses) if (W.map.getLayersByName("pointLayer").length) { W.map.removeLayer(W.map.getLayersByName("pointLayer")[0]); } const pointLayer = new OpenLayers.Layer.Vector("pointLayer"); const proj = new OpenLayers.Projection("EPSG:4326"); const features = []; for (const addr of addresses) { const point = new OpenLayers.Geometry.Point(addr.lng, addr.lat).transform(proj, W.map.getProjectionObject()); const ft = new OpenLayers.Feature.Vector(point, null, null); ft.style = { label: addr.name, pointRadius: 15, fillColor: addr.color, fillOpacity: 0.8, strokeColor: "#cc6633", strokeWidth: 2, strokeOpacity: 0.8, fontColor: "black", labelOutlineColor: "white", labelOutlineWidth: 3, }; features.push(ft); } pointLayer.addFeatures(features); W.map.addLayer(pointLayer); wmelvLoading(false); wmelvUpdate(); }, onerror: () => { wmelvLoading(false); }, onabort: () => { wmelvLoading(false); }, ontimeout: () => { wmelvLoading(false); }, }); } /** * Triggered when selection changes (user selects or deselects a WME feature) * @param e {Event} */ function wmeSelectionChanged(e) { if (e && W.selectionManager.hasSelectedFeatures() && W.selectionManager.getSelectedFeatures().length === 1 && W.selectionManager.getSelectedFeatures()[0].model.type === "venue") { const venue = W.selectionManager.getSelectedFeatures()[0].model.attributes; let warnings = [] let html = `<div class="action-buttons"><div class="alert addresses"></div>`; if (venue.fixAddress) warnings.push('Ēkas adrese, iespējams, nav korekta (tuvākā ir ' + venue.ads.waze_name + '; <a href="#" id="fixCurrentlySelectedVenueAddress">salabot</a>)'); if (venue.fixLowerCase) warnings.push('Ēkas numurs satur mazo burtu (<a href="" id="fixThisLowerCase">salabot</a>)'); if (venue.fixNameHNMismatch) warnings.push('Ēkas numurs nesakrīt ar numuru nosaukumā<br/>' + '(<a href="#" id="fixNameHNMismatchToAddress">pareiza adrese</a>, <a href="" id="fixNameHNMismatchToName">pareizs nosaukums</a>)'); if (venue.fixIela) warnings.push('Vietas nosaukums satur "' + venue.name.match(reStreetNames)[0] + '" (<a href="#" id="fixIelaInName">salabot</a>)'); if (venue.fixNoHN) warnings.push('Adrese ir, bet ēkas numura nav'); if (venue.fixArea) warnings.push('Laukuma platība ' + Math.floor(venue.fixArea) + 'm² ir mazāka par 509m² (<a href="#" id="fixThisArea">salabot</a>)'); html += warnings.map(warning => `<div class="alert alert-danger">${warning}</div>`).join(''); html += '</div>'; /** * Update landmark edit tab. */ if (!qs('#wmelv-landmark-edit')) { let div = document.createElement('div'); div.id = 'wmelv-landmark-edit'; qs('#venue-edit-general').insertBefore(div, qs('#venue-edit-general').firstChild); } qs('#wmelv-landmark-edit').innerHTML = html; if (qs('#fixCurrentlySelectedVenueAddress')) { qs('#fixCurrentlySelectedVenueAddress').addEventListener('click', (e) => { e.preventDefault(); let venue = W.selectionManager.getSelectedFeatures()[0]; const centroid = venue.geometry.getCentroid(); centroid.transform('EPSG:900913', "EPSG:4326"); const closest = getClosestAddress(centroid); const street = Object.values(W.model.streets.objects).find((street) => street.name === closest.iela_name); const changes = { name: closest.name.replace(' k-', '-'), houseNumber: closest.iela_name ? closest.waze_house_number : null, streetID: street ? street.id : null, }; if (changes) W.model.actionManager.add(new UpdateObject(venue.model, changes)); }) } if (qs('#fixNameHNMismatchToAddress')) { qs('#fixNameHNMismatchToAddress').addEventListener('click', (e) => { e.preventDefault(); let venue = W.selectionManager.getSelectedFeatures()[0], changes = { name: venue.model.attributes.houseNumber.replace('-', ' k-'), }; if (changes) W.model.actionManager.add(new UpdateObject(venue.model, changes)); }) } if (qs('#fixNameHNMismatchToName')) { qs('#fixNameHNMismatchToName').addEventListener('click', (e) => { e.preventDefault(); let venue = W.selectionManager.getSelectedFeatures()[0], changes = { houseNumber: venue.model.attributes.name.replace(' k-', '-'), }; if (changes) W.model.actionManager.add(new UpdateObject(venue.model, changes)); }) } if (qs('#fixThisArea')) { qs('#fixThisArea').addEventListener('click', fixCurrentlySelectedArea); } if (qs('#fixIelaInName')) { qs('#fixIelaInName').addEventListener('click', (e) => { e.preventDefault(); let venue = W.selectionManager.getSelectedFeatures()[0], name = venue.model.attributes.name, changes = { name: name.replace(reStreetNames, '$3'), }; if (changes) W.model.actionManager.add(new UpdateObject(venue.model, changes)); }); } if (qs('#fixThisLowerCase')) { qs('#fixThisLowerCase').addEventListener('click', (e) => { e.preventDefault(); let changes = {}; if (venue.attributes.houseNumber && venue.attributes.houseNumber.toUpperCase() !== venue.attributes.houseNumber) { changes.houseNumber = venue.attributes.houseNumber.toUpperCase(); } if (venue.attributes.name && venue.attributes.name.match(/^\d+[a-z][^a-z]*/)) { changes.name = venue.attributes.name.toUpperCase().replace(' K-', ' k-'); if (venue.attributes.houseNumber) changes.houseNumber = venue.attributes.houseNumber.toUpperCase(); } if (changes) W.model.actionManager.add(new UpdateObject(venue, changes)); wmelvUpdate(); }); } } } /** * Creates WME tab and registers all corresponding event listeners on inputs. */ function wmelvRegisterTab() { let style = document.getElementById('wmelv-style'); if (!style) { style = document.createElement('style'); style.id = 'wmelv-style'; document.head.appendChild(style); } style.innerText = ` #wmelv-loading-indicator { text-align: center; display: inline-block; } #wmelv-loading-indicator path, #wmelv-loading-indicator rect { fill: #FF6700; } #sidepanel-wmelv hr { height: 1px; width: 100%; border-top: 1px solid #ccc; } #sidepanel-wmelv label { white-space: normal; } .waze-btn:disabled { cursor: no-drop; } #applyAllAddresses { text-align: center; } .count { background-color: #009900; color: #fff; font-size: 90%; border-radius: 25%; padding-left: .5rem; margin-left: 1rem; padding-right: .5rem; } #wmelv-landmark-edit .alert { margin-bottom: .25rem; text-transform: none; font-size: 12px; } #wmelv-landmark-edit .alert-danger { border: 1px solid #ed503b; } .alert .waze-btn.waze-btn-blue { box-shadow: none; } #zoom-level-warning { color: red; font-weight: bold; } .wme-lv-details { font-weight: bold; color: green; } #wmelv-convert-to-area { margin-top: .25rem; } #wmelv-venues-list ul { margin: 1rem; padding: 0; } #wmelv-venues-list ul li { list-style-type: none; margin: 0; padding: 0; } #wmelv-venues-list [data-type]:before { content: ""; display: inline-block; position: relative; top: 1px; background-image: url(//editor-assets.waze.com/production/img/buttons756c103910d73f4d45328e08f6016871.png); width: 11px; height: 11px; margin-right: 5px; } #wmelv-venues-list [data-type="point"]:before { background-position: -49px -58px; } #wmelv-venues-list [data-type="area"]:before { background-position: -25px -58px; } #wmelv-venues-list li a { text-decoration: none; } .wmelv-lock-rank { box-shadow: 0 4px 4px 0 #def7ff; color: #fff; background: #32a852; height: 23px; line-height: 23px; margin-right: 1px; text-align: center; font-weight: normal; font-size: 13px; padding-left: 8px; padding-right: 8px; border-radius: 13px; } [data-lock-rank="0"] .wmelv-lock-rank, [data-lock-rank="1"] .wmelv-lock-rank { background: #ff7f00; } `; settings.load(); const html = ` <div class="form-group"> <span id="zoom-level-warning" style="display: none;">Zoom par mazu. Funkcionalitāte atslēgta.</span> </div> <div class="form-group"> <div class="controls-container"> <input type="checkbox" class="settings-input" name="hlSmallArea" id="hlSmallArea" ${settings.get('hlSmallArea') ? 'checked' : ''} ><label for="hlSmallArea"> Vietas, kuras mazākas par 509m² (zils)</label> </div> </div> <div class="form-group"> <div class="controls-container"> <input type="checkbox" class="settings-input" name="hlIncorrectAddress" id="hlIncorrectAddress" ${settings.get('hlIncorrectAddress') ? 'checked' : ''} ><label for="hlIncorrectAddress"> Vietas, kurām adrešu reģistra adrese atšķiras no Waze (lillā)</label> </div> </div> <div class="form-group"> <div class="controls-container"> <input type="checkbox" class="settings-input" name="hlNoHN" id="hlNoHN" ${settings.get('hlNoHN') ? 'checked' : ''} ><label for="hlNoHN"> Adresē ir iela, pilsēta, bet nav ēkas numura (sarkans)</label> </div> </div> <div class="form-group"> <div class="controls-container"> <input type="checkbox" class="settings-input" name="hlIela" id="hlIela" ${settings.get('hlIela') ? 'checked' : ''} ><label for="hlIela"> Vietas nosaukumā ir vārds "iela" (sarkans)</label> </div> </div> <div class="form-group"> <div class="controls-container"> <input type="checkbox" class="settings-input" name="hlLowerCaseHN" id="hlLowerCaseHN" ${settings.get('hlLowerCaseHN') ? 'checked' : ''} ><label for="hlLowerCaseHN"> Ēkas numurā ir mazie burti (sarkans)</label> </div> </div> <div class="form-group"> <div class="controls-container"> <input type="checkbox" class="settings-input" name="hlNameHNMismatch" id="hlNameHNMismatch" ${settings.get('hlNameHNMismatch') ? 'checked' : ''} ><label for="hlNameHNMismatch"> Ēkas numurs adresē un numurs nosaukumā nesakrīt (dzeltens)</label> </div> </div> <div class="form-group" data-hide> <div class="controls-container"> <input type="checkbox" class="settings-input" name="hlDupes" id="hlDupes" ${settings.get('hlDupes') ? 'checked' : ''} ><label for="hlDupes"> Identiski objekti, viens uz otra (gaiši zils)</label> </div> </div> <!-- <div class="form-group" data-api-required> <div class="controls-container"> <input type="checkbox" class="settings-input" name="addressFixer" id="addressFixer" ${settings.get('addressFixer') ? 'checked' : ''} ><label for="addressFixer"> Adrešu labotājs</label> </div> </div> --> <div class="form-group" data-api-required> <div class="controls-container"> <input type="checkbox" class="settings-input" name="autoHN" id="autoHN" ${settings.get('autoHN') ? 'checked' : ''} ><label for="autoHN"> Ielādēt adreses automātiski</label> </div> </div> <!-- <div class="form-group" data-api-required> <div class="controls-container"> <input type="checkbox" class="settings-input" name="autoHNSegmentSelection" id="autoHNSegmentSelection" ${settings.get('autoHNSegmentSelection') ? 'checked' : ''} ><label for="autoHNSegmentSelection"> Iezīmējot segmentu, rādīt tikai tās ielas HN</label> </div> </div> --> <!-- <div id="wmelv-place-info" data-api-required> <hr> <p id="wmlelv-place-info">Noklikšķini kartē un tadā.</p> <div class="action-buttons"> <button class="waze-btn waze-btn-smaller" type="submit" id="wmelvCreatePlace" data-action="create-place" data-ratio="1:1">Izveidot 1:1</button> <button class="waze-btn waze-btn-smaller" type="submit" id="wmelvCreatePlace2" data-action="create-place" data-ratio="2:1">Izveidot 2:1</button> </div> </div> --> <hr> <p> Tu esi ${W.loginManager.user.userName} (level ${W.loginManager.user.rank + 1}), es esmu skripts. </p> <hr> <div class="form-group" data-api-required> <label class="control-label">Funkcionalitāte sāk darboties, ja zoom ir vismaz:</label> <div class="controls"> <div class="form-control waze-radio-container" style="display: block;"> <input type="radio" name="minHNZoomLevel" value="3" id="minHNZoomLevel-3" ${parseInt(settings.get('minHNZoomLevel')) === 3 ? 'checked' : ''}> <label for="minHNZoomLevel-3">3 (drosmīgajiem)</label> <input type="radio" name="minHNZoomLevel" value="4" id="minHNZoomLevel-4" ${parseInt(settings.get('minHNZoomLevel')) === 4 ? 'checked' : ''}> <label for="minHNZoomLevel-4">4</label> <input type="radio" name="minHNZoomLevel" value="5" id="minHNZoomLevel-5" ${parseInt(settings.get('minHNZoomLevel')) === 5 ? 'checked' : ''}> <label for="minHNZoomLevel-5">5</label> <input type="radio" name="minHNZoomLevel" value="6" id="minHNZoomLevel-6" ${parseInt(settings.get('minHNZoomLevel')) === 6 ? 'checked' : ''}> <label for="minHNZoomLevel-6">6</label> </div> </div> </div> <!-- <div class="form-group"> <label class="control-label" for="segmentToHouseWidth">Ēkas platums, veidojot to no segmenta</label> <div class="controls"> <input class="form-control settings-input" name="segmentToHouseWidth" type="number" id="segmentToHouseWidth" value="${settings.get('segmentToHouseWidth')}"> </div> </div> --> <hr> <dl> <dt>2.03</dt> <dd>Iespēja koriģēt kļūda (laukumu, adreses, utt) ar vienu pogas klikšķi.</dd> <dd>Paplašinājums vairs nesalauž Google StreetView.</dd> <dd>Vēl kārtīgi jātestē, jo daudz kas nestrādā.</dd> <dd>Ielādes indikācija blakus cilnes nosaukumam.</dd> <dd></dd> <dt>2.02</dt> <dd>Salasāmāki māju numuri un nosaukumi.</dd> <dt>2.01</dt> <dd>Labota kļūda ar ķekškastīti pie VZD adrešu neatbilstību krāsošanas</dd> <dt>2.00</dt> <dd>Pirmā publiskā versija</dd> </dl> <hr> `; //<div class="loader loader--style3" id="wmelv-loading-indicator" title="2"><svg version="1.1" id="loader-1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="40px" height="40px" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve"><path fill="#000" d="M43.935,25.145c0-10.318-8.364-18.683-18.683-18.683c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615c8.072,0,14.615,6.543,14.615,14.615H43.935z"><animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="0.6s" repeatCount="indefinite"/></path></svg></div> new WazeWrap.Interface.Tab('WME LV', html, () => { Array.from(document.querySelectorAll("#user-tabs > ul > li")).map((el) => { const a = el.querySelector('a') if (a && a.innerText === 'WME LV') { a.innerHTML = ` WME LV <svg id="wmelv-loading-indicator" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="10px" height="10px" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve"><path fill="#000" d="M43.935,25.145c0-10.318-8.364-18.683-18.683-18.683c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615c8.072,0,14.615,6.543,14.615,14.615H43.935z"><animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 25 25" to="360 25 25" dur="0.6s" repeatCount="indefinite"/></path></svg> ` } }) // Attach settings change handler to corresponding inputs qsa('.settings-input').forEach(element => { element.addEventListener('change', event => { settings.set(event.target.name, event.target.type === 'checkbox' ? event.target.checked : event.target.value); wmelvUpdate(); wmeLoadAddresses(); }) }); qsa('[name="minHNZoomLevel"]').forEach(element => { element.addEventListener('change', event => { settings.set('minHNZoomLevel', parseInt(event.target.value)); }); }); // qsa('[data-action="create-place"]').forEach(el => { // el.addEventListener('click', (e) => { // log.info(e.target) // const vertex = 22.57; // // let place = new Landmark() // let poly = new OpenLayers.Geometry.LinearRing([ // new OpenLayers.Geometry.Point(lastClick.lon - vertex, lastClick.lat - (e.target.dataset.ratio === '2:1' ? vertex / 2 : vertex)), // new OpenLayers.Geometry.Point(lastClick.lon - vertex, lastClick.lat + (e.target.dataset.ratio === '2:1' ? vertex / 2 : vertex)), // new OpenLayers.Geometry.Point(lastClick.lon + vertex, lastClick.lat + (e.target.dataset.ratio === '2:1' ? vertex / 2 : vertex)), // new OpenLayers.Geometry.Point(lastClick.lon + vertex, lastClick.lat - (e.target.dataset.ratio === '2:1' ? vertex / 2 : vertex)), // new OpenLayers.Geometry.Point(lastClick.lon - vertex, lastClick.lat - (e.target.dataset.ratio === '2:1' ? vertex / 2 : vertex)), // ]); // poly.rotate(10, poly.getCentroid()); // // place = wmelvCreateNewPlace(new OpenLayers.Geometry.Polygon([poly]), {}); // // const closest = getClosestAddress(lastClick) // if (closest) { // setVenueAddress(place.attributes.id, 0); // fixPlaceArea(place); // } // }); // }); }); // // update(); } /** * Registers global handlers which apply to W and W.map. */ function wmelvRegisterGlobalHandlers() { W.map.events.register('zoomend', this, () => { // updateVenuesFilterList(); // updateAddressSuggestions(); }); W.map.events.register('moveend', this, () => { wmeLoadAddresses(); }); W.selectionManager.events.register('selectionchanged', this, wmeSelectionChanged); /** * Registers click handler to the main map. That's me - being a smartass. */ // W.map.events.register('mousedown', (e) => { // console.log(e.target); // if (e && e.xy) { // lastClick = W.map.getLonLatFromViewPortPx(e.xy).clone(); // const point = (new OpenLayers.Geometry.Point(lastClick.lon, lastClick.lat)).transform('EPSG:900913', 'EPSG:4326'); // const closest = getClosestAddress(point); // console.log(closest); // qs('#wmlelv-place-info').innerHTML = closest // ? `Tuvākā vieta: <strong>${closest.waze_name}<strong>` // : 'Noklikšķini adreses tuvumā kartē un tadā.'; // } // }, true) } /** * Initializes application. */ function init() { Logger.info('WMELV initializing...'); UpdateObject = require("Waze/Action/UpdateObject"); Landmark = require("Waze/Feature/Vector/Landmark"); AddLandmark = require("Waze/Action/AddLandmark"); DeleteSegment = require("Waze/Action/DeleteSegment"); wmelvRegisterGlobalHandlers(); wmelvRegisterTab(); wmeLoadAddresses(); wmelvUpdate(); Logger.info('WMELV initialized.'); } /** * Starts waiting for W to load. Max 1000 times (100 seconds) * @param tries {number} */ function bootstrap(tries = 1) { if (W && W.map && W.model && W.loginManager.user && typeof W.selectionManager !== 'undefined' && typeof WazeWrap !== "undefined" && WazeWrap.Ready ) { init(); } else if (tries < 1000) { setTimeout(() => { bootstrap(tries + 1); }, 200); } } Logger.info('WMELV waiting...'); bootstrap(); }()); /* end ======================================================================= */
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址