您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Fetch information about the POI from external sources
当前为
// ==UserScript== // @name WME E50 Fetch POI Data // @version 0.0.6 // @description Fetch information about the POI from external sources // @author Anton Shevchuk // @license MIT License // @include https://www.waze.com/editor* // @include https://www.waze.com/*/editor* // @include https://beta.waze.com/editor* // @include https://beta.waze.com/*/editor* // @exclude https://www.waze.com/user/editor* // @exclude https://beta.waze.com/user/editor* // @grant none // @require https://gf.qytechs.cn/scripts/24851-wazewrap/code/WazeWrap.js // @require https://gf.qytechs.cn/scripts/389117-apihelper/code/APIHelper.js?version=729417 // @require https://gf.qytechs.cn/scripts/389577-apihelperui/code/APIHelperUI.js?version=729353 // @namespace https://gf.qytechs.cn/users/227648 // ==/UserScript== /* jshint esversion: 6 */ /* global require, $, window, W, I18n, OL, APIHelper, APIHelperUI, WazeWrap */ (function () { 'use strict'; let helper, panel; let vectorLayer, vectorPoint, vectorLine; const NAME = 'E50'; // translation structure const TRANSLATION = { 'en': { title: 'Information', questions: { changeName: 'Are you sure to change the name?' } }, 'uk': { title: 'Інформація', questions: { changeName: 'Ви впевненні що хочете змінити им\'я?' } }, 'ru': { title: 'Информация', questions: { changeName: 'Ви уверены, что хотите изменить имя?' } } }; // OpenLayer styles APIHelper.bootstrap(); APIHelper.addTranslation(NAME, TRANSLATION); APIHelper.addStyle( '.e50 legend { cursor:pointer; font-size: 12px; font-weight: bold; width: auto; text-align: right; border: 0; margin: 0; padding: 0 8px; }' + '.e50 fieldset { border: 1px solid #ddd; padding: 4px; }' + '.e50 ul { padding: 0; margin: 0 }' + '.e50 li { padding: 0; margin: 0; list-style: none; margin-bottom: 2px }' + '.e50 li a { display: block; padding: 2px 4px; text-decoration: none; border: 1px solid #e4e4e4; }' + '.e50 li a:hover { background: #ddd }' + '.e50 li a.noaddress { background: rgba(255, 255, 200, 0.5) }' + '.e50 li a.noaddress:hover { background: rgba(255, 255, 200, 1) }' ); let WazeActionUpdateObject = require('Waze/Action/UpdateObject'); let WazeActionUpdateFeatureAddress = require('Waze/Action/UpdateFeatureAddress'); class Provider { constructor(uid) { this.uid = uid; } request() { throw new Error('Abstract method'); } search(lon, lat) { try { let params = { lon: lon, lat: lat, }; this.request(params); } catch (e) { console.error(e); } } panel(parent) { let div = document.createElement('div'); div.id = 'E50-' + this.uid; this.container = div; parent.append(this.container); } collection(results) { let fieldset = document.createElement('fieldset'); let list = document.createElement('ul'); list.style.display = results.length > 2 ? 'none' : 'block'; for (let i = 0; i < results.length; i++) { let item = document.createElement('li'); item.append(this.item(results[i])); list.append(item); } let legend = document.createElement('legend'); legend.innerHTML = this.uid + ' [' + results.length + ']'; legend.onclick = function () { $(this).next().toggle(); return false; }; fieldset.append(legend, list); this.result(fieldset); } /** * Should return {DocumentElement} link * @param res */ item(res) { throw new Error('Abstract method'); } result(item) { this.container.append(item); return this; } link(lon, lat, street, number, name = null) { let a = document.createElement('a'); a.href = '#'; a.dataset.lat = lat; a.dataset.lon = lon; a.dataset.street = street; a.dataset.number = number; a.dataset.name = name ? name : ''; a.innerHTML = [street, number, name].filter(x => !!x).join(', '); a.className = NAME + '-link'; return a; } } /** * Open Street Map */ class OsmProvider extends Provider { request(params) { let url = 'https://nominatim.openstreetmap.org/reverse'; let data = { lon: params.lon, lat: params.lat, zoom: 18, addressdetails: 1, countrycodes: 'ua', 'accept-language': 'uk_UA', format: 'json', }; let self = this; $.ajax({ dataType: 'json', cache: false, url: url, data: data, error: function () { }, success: function (response) { if (!response.address) { return; } console.log(response); self.collection([response]); } }); } item(res) { let output = []; let street = null; let number = null; if (res.address.road) { street = res.address.road; } if (res.address.house_number) { number = res.address.house_number; } else { output.push(res.display_name.split(', ', 1)); } return this.link(res.lon, res.lat, street, number, output.join(', ')); } } /** * 2GIS * @link http://catalog.api.2gis.ru/doc/2.0/geo/#/default/get_2_0_geo_search */ class GisProvider extends Provider { request(params) { let url = 'https://catalog.api.2gis.ru/2.0/geo/search'; let data = { point: params.lon + ',' + params.lat, radius: 20, type: 'building', fields: 'items.address,items.geometry.centroid', locale: 'uk_UA', format: 'json', key: 'rubnkm' + '7490', }; let self = this; $.ajax({ dataType: 'json', cache: false, url: url, data: data, error: function () { }, success: function (response) { if (!response.result || !response.result.items.length) { return; } console.log(response.result); self.collection(response.result.items); } }); } item(res) { let output = []; let street = null; let number = null; if (res.address.components) { // optional street = res.address.components[0].street; number = res.address.components[0].number; } else if (res.address_name) { // optional output.push(res.address_name); } else if (res.name) { output.push(res.name); } // e.g. POINT(36.401143 49.916814) let center = res.geometry.centroid.substring(6, res.geometry.centroid.length - 1).split(' '); let lon = center[0]; let lat = center[1]; let link = this.link(lon, lat, street, number, output.join(', ')); if (res.purpose_name) { link.title = res.purpose_name; } return link; } } /** * Yandex Maps */ class YMProvider extends Provider { request(params) { let url = 'https://geocode-maps.yandex.ru/1.x/'; let data = { geocode: params.lon + ',' + params.lat, kind: 'house', results: 2, lang: 'uk_UA', format: 'json', apikey: '2fe62c0e' + '-580f-4541-b325-' + '7c896d8d9481', }; let self = this; $.ajax({ dataType: 'json', cache: false, url: url, data: data, error: function () { console.error('Yandex Maps Request Error'); }, success: function (response) { if (!response.response || !response.response.GeoObjectCollection.featureMember.length) { return; } console.log(response.response); self.collection(response.response.GeoObjectCollection.featureMember); } }); } item(res) { res = res.GeoObject; let center = res.Point.pos.split(' '); let lon = center[0]; let lat = center[1]; let street = null; let number = null; if (res.metaDataProperty.GeocoderMetaData.Address.Components) { for (let el in res.metaDataProperty.GeocoderMetaData.Address.Components) { if (res.metaDataProperty.GeocoderMetaData.Address.Components[el]['kind'] === 'street') { street = res.metaDataProperty.GeocoderMetaData.Address.Components[el]['name']; } if (res.metaDataProperty.GeocoderMetaData.Address.Components[el]['kind'] === 'house') { number = res.metaDataProperty.GeocoderMetaData.Address.Components[el]['name']; } } } let link = this.link( lon, lat, street, number ); link.title = res.name; return link; } } /** * Here Maps * @link https://developer.here.com/documentation/geocoder/topics/quick-start-geocode.html */ class HereProvider extends Provider { request(params) { let url = 'https://reverse.geocoder.api.here.com/6.2/reversegeocode.json'; let data = { app_id: 'GCFmOOrSp8882vFwTxEm', app_code: 'O-LgGkoRfypnRuik0WjX9A', prox: params.lat + ',' + params.lon + ',10', mode: 'retrieveAddresses', locationattributes: 'none,ar', addressattributes: 'str,hnr' }; let self = this; $.ajax({ dataType: 'json', cache: false, url: url, data: data, error: function () { }, success: function (response) { if (!response.Response || !response.Response.View || !response.Response.View || !response.Response.View[0] || !response.Response.View[0].Result) { return; } let results = response.Response.View[0].Result; results = results.filter(x => x.MatchLevel === 'houseNumber'); if (!results.length) { return; } console.log(results); self.collection(results); } }); } item(res) { return this.link( res.Location.DisplayPosition.Longitude, res.Location.DisplayPosition.Latitude, res.Location.Address.Street, res.Location.Address.HouseNumber ); } } /** * Bing Maps * @link https://docs.microsoft.com/en-us/bingmaps/rest-services/locations/find-a-location-by-point * http://dev.virtualearth.net/REST/v1/Locations/50.03539,36.34732?o=xml&key=AuBfUY8Y1Nzf3sRgceOYxaIg7obOSaqvs0k5dhXWfZyFpT9ArotYNRK7DQ_qZqZw&c=uk * http://dev.virtualearth.net/REST/v1/Locations/50.03539,36.34732?o=xml&key=AuBfUY8Y1Nzf3sRgceOYxaIg7obOSaqvs0k5dhXWfZyFpT9ArotYNRK7DQ_qZqZw&c=uk&includeEntityTypes=Address */ class BingProvider extends Provider { request(params) { let url = 'https://dev.virtualearth.net/REST/v1/Locations/' + params.lat + ',' + params.lon; let data = { includeEntityTypes: 'Address', c: 'uk', key: 'AuBfUY8Y1Nzf' + '3sRgceOYxaIg7obOSaqvs' + '0k5dhXWfZyFpT9ArotYNRK7DQ_qZqZw', }; let self = this; $.ajax({ dataType: 'json', cache: false, url: url, data: data, error: function () { }, success: function (response) { if (!response || !response.resourceSets || !response.resourceSets[0]) { return; } console.log(response.resourceSets[0].resources); self.collection(response.resourceSets[0].resources.filter(el => el.address.addressLine.indexOf(',') > 0)); } }); } item(res) { let address = res.address.addressLine.split(','); return this.link( res.point.coordinates[1], res.point.coordinates[0], address[0], address[1] ); } } /** * Map Quest * @link https://developer.mapquest.com/documentation/ * http://open.mapquestapi.com/geocoding/v1/reverse?key=HFk67kfdVFGRYDtlFTRNoDUfHu1HwgEa&location=30.333472,-81.470448 */ class MQProvider extends Provider { } /** * Google Place * @link https://developers.google.com/places/web-service/search */ class GPProvider extends Provider { request(params) { let url = 'https://www.waze.com/maps/api/place/nearbysearch/json'; let data = { location: params.lat + ',' + params.lon, radius: 40, fields: 'geometry,formatted_address', types: 'point_of_interest', language: 'ua', key: 'AIzaSy' + 'CebbES' + 'rWERY1MRZ56gEAfpt7tK2R6hV_I', // extract it from WME }; let self = this; $.ajax({ dataType: 'json', cache: false, url: url, data: data, error: function () { }, success: function (response) { if (!response.results || !response.results.length) { return; } console.log(response.results); self.collection(response.results); } }); } item(res) { let link = this.link( res.geometry.location.lng, res.geometry.location.lat, null, null, res.name ); link.className += ' noaddress'; link.innerHTML += ', ' + res.vicinity; return link; } } $(document) .on('ready.apihelper', ready) .on('landmark.apihelper', landmarkPanel) .on('click', '.' + NAME + '-link', applyData) .on('mouseenter', '.' + NAME + '-link', showVector) .on('mouseleave', '.' + NAME + '-link', hideVector) ; function ready() { console.info('@ready'); helper = new APIHelperUI(NAME); panel = helper.createPanel(I18n.t(NAME).title); vectorLayer = new OL.Layer.Vector("E50VectorLayer", { displayInLayerSwitcher: false, uniqueName: "__E50VectorLayer" }); W.map.addLayer(vectorLayer); } function landmarkPanel(event, element) { console.info('@landmark'); let group = panel.toHTML(); let selected = APIHelper.getSelectedVenues()[0].geometry.getCentroid().clone(); selected.transform('EPSG:900913', 'EPSG:4326'); let Osm = new OsmProvider('OSM'); Osm.panel(group); Osm.search(selected.x, selected.y); let Gis = new GisProvider('2Gis'); Gis.panel(group); Gis.search(selected.x, selected.y); let Yandex = new YMProvider('Yandex'); Yandex.panel(group); Yandex.search(selected.x, selected.y); let Here = new HereProvider('Here'); Here.panel(group); Here.search(selected.x, selected.y); let Bing = new BingProvider('Bing'); Bing.panel(group); Bing.search(selected.x, selected.y); let Google = new GPProvider('Google'); Google.panel(group); Google.search(selected.x, selected.y); element.prepend(group); } function applyData() { let poi = APIHelper.getSelectedVenues()[0]; let name = this.dataset['name']; let street = this.dataset['street']; let number = this.dataset['number']; let newName; console.log(poi); console.log(name + ': ' + street + ', ' + number); // POI Name // If exists ask user to replace or not // If not exists - use name or house number as name if (poi.getAttributes().name) { if (name && name !== poi.getAttributes().name) { if (confirm(I18n.t(NAME).questions.changeName + '\n«' + poi.getAttributes().name + '» ⟶ «' + name + '»?')) { newName = name; } } else if (number && number !== poi.getAttributes().name) { if (confirm(I18n.t(NAME).questions.changeName + '\n«' + poi.getAttributes().name + '» ⟶ «' + number + '»?')) { newName = number; } } } else { if (name) { newName = name; } else if (number) { newName = number; } } if (newName) { W.model.actionManager.add(new WazeActionUpdateObject(poi, {name: newName})); } // POI Address HouseNumber let addressHN = poi.getAddress().attributes.houseNumber; if (number) { console.log(poi); // W.model.actionManager.add(new WazeActionUpdateObject(poi, {houseNumber: number})); let address = { countryID: W.model.getTopCountry().getID(), stateID: W.model.getTopState().getID(), houseNumber: number, }; // W.model.actionManager.add(new WazeActionUpdateFeatureAddress(poi, address, {updateHouseNumber:true, streetIDField: 'primaryStreetID'})); // W.model.actionManager.add(new WazeActionUpdateObject(poi, {})); if (addressHN) { } else { } } return false; } function showVector() { let from = APIHelper.getSelectedVenues()[0].geometry.getCentroid(); let to = new OL.Geometry.Point(this.dataset.lon, this.dataset.lat).transform('EPSG:4326', 'EPSG:900913'); let distance = Math.round(WazeWrap.Geometry.calculateDistance([to, from])); vectorLine = new OL.Feature.Vector(new OL.Geometry.LineString([from, to]), {}, { strokeWidth: 4, strokeColor: '#fff', strokeLinecap: 'round', strokeDashstyle: 'dash', label: distance + 'm', labelOutlineColor: '#000', labelOutlineWidth: 3, labelAlign: 'cm', fontColor: '#fff', fontSize: '24px', fontFamily: 'Courier New, monospace', fontWeight: 'bold', labelYOffset: 24 }); vectorPoint = new OL.Feature.Vector(to, {}, { pointRadius: 8, fillOpacity: 0.5, fillColor: '#fff', strokeColor: '#fff', strokeWidth: 2, strokeLinecap: 'round' }); vectorLayer.addFeatures([vectorLine, vectorPoint]); vectorLayer.setZIndex(1001); vectorLayer.setVisibility(true); } function hideVector() { vectorLayer.removeAllFeatures(); vectorLayer.setVisibility(false); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址