您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Overlay alerts from the Waze LiveMap
当前为
// ==UserScript== // @name WME LiveMap Alerts Overlay // @author davielde // @description Overlay alerts from the Waze LiveMap // @include https://www.waze.com/editor/* // @include https://www.waze.com/*/editor/* // @include https://editor-beta.waze.com/* // @version 0.3.1 // @grant none // @namespace https://greasyfork.org/users/5252 // ==/UserScript== // Many thanks to Timbones and Twister-UK, whose code (WMECH and URO+) provided a large foundation for this work //------------------------------------------------------------------------------------------------ function bootstrapLiveMapAlerts() { var bGreasemonkeyServiceDefined = false; try { bGreasemonkeyServiceDefined = (typeof Components.interfaces.gmIGreasemonkeyService === "object"); } catch (err) { /* Ignore */ } if (typeof unsafeWindow === "undefined" || ! bGreasemonkeyServiceDefined) { unsafeWindow = ( function () { var dummyElem = document.createElement('p'); dummyElem.setAttribute('onclick', 'return window;'); return dummyElem.onclick(); }) (); } setTimeout(initializeLiveMapAlerts, 999); } //-------------------------------------------------------------------------------------------------------- function checkLayerNum() { var lmaoLayer = null; for(i=0; i<Waze.map.layers.length; i++) { if(Waze.map.layers[i].uniqueName == '__livemap_alerts') lmaoLayer = i; } console.log('WME LMAO: layer number = ' + lmaoLayer); return lmaoLayer; } //-------------------------------------------------------------------------------------------------------- function getBounds() { var alertBounds = Waze.map.getExtent(); alertBounds.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326")); //console.log('WME LMAO: Current bounds = Left ' + alertBounds.left + ', Right ' + alertBounds.right + ', Bottom ' + alertBounds.bottom + ', Top ' + alertBounds.top);//verify transform return alertBounds; } //-------------------------------------------------------------------------------------------------------- function getRoutingServer(){ var server = Waze.location.code; //console.log('WME LMAO: server = ' + server); switch(server){ case 'usa': var routingURL = '/rtserver/web/GeoRSS'; break; case 'row': var routingURL = '/row-rtserver/web/GeoRSS'; break; case 'il': var routingURL = '/il-rtserver/web/GeoRSS'; break; default: var routingURL = '/rtserver/web/GeoRSS'; }; return routingURL; } //-------------------------------------------------------------------------------------------------------- function getFeatureYOffset(){ var yOffset = -30; return yOffset; } //-------------------------------------------------------------------------------------------------------- function getLiveMapAlerts(){ LiveMapAlerts_Layer.destroyFeatures(); var alertBounds = getBounds(); var url = getRoutingServer(); var data = { format: "JSON", types: "alerts", left: alertBounds.left, right: alertBounds.right, bottom: alertBounds.top, top: alertBounds.bottom }; $.ajax({ dataType: "json", url: url, data: data, success: function(json) { var alertData = json.alerts; try { for(var i=0; i<alertData.length; i++) { var lat = alertData[i].location.y; var long = alertData[i].location.x; var image = alertData[i].type; var title = alertData[i].reportDescription; console.log("WME LMAO: " + alertData[i].type, alertData[i].location.x, alertData[i].location.y); addImage(lat,long,image,alertData[i]); } } catch(e) { console.log('WME LMAO: No alerts in view'); } } }); } //-------------------------------------------------------------------------------------------------------- function addImage(lat, long, type, detail) { var coords = OpenLayers.Layer.SphericalMercator.forwardMercator(long, lat); var point = new OpenLayers.Geometry.Point(coords.lon,coords.lat); var alertPx = Waze.map.getPixelFromLonLat(new OpenLayers.LonLat(coords.lon,coords.lat)); var imgRoot = '/assets'; switch(type){ case 'ROAD_CLOSED': var icon = '/livemap/alerts/road_closed-243aa9787857ee55f762c52ceb13813b.png'; break; case 'ACCIDENT': var icon = '/livemap/alerts/accident-c5f76aaa426f2731d2e10c6ac99fe918.png'; break; case 'JAM': var icon = '/livemap/alerts/jam-8269807a1e2a79c944a9577483ac8df7.png'; break; case 'POLICEMAN': //Chrome var icon = '/livemap/alerts/police-503317f465b6295c7bf084ff773848e3.png'; break; case 'POLICE': //Firefox var icon = '/livemap/alerts/police-503317f465b6295c7bf084ff773848e3.png'; break; case 'HAZARD': //Firefox var icon = '/livemap/alerts/hazard-ed111f132551125f297b76ef4cca9101.png'; break; case 'WEATHERHAZARD': //Chrome returns this for *all* hazards... var icon = '/livemap/alerts/hazard-ed111f132551125f297b76ef4cca9101.png'; break; case 'OTHER': var icon = '/livemap/alerts/chit_chat-bf263765e4d45fe419bba74735b240bf.png'; break; default: var icon = '/livemap/alerts/hazard-ed111f132551125f297b76ef4cca9101.png'; }; var attributes = { type: detail.type, subtype: detail.subtype, description: detail.reportDescription, street: detail.street, city: detail.city, near: detail.nearBy, reportby: detail.reportBy, pubMillis: detail.pubMillis, pixel: alertPx }; var style = { externalGraphic: imgRoot + icon, graphicWidth: 30, graphicHeight: 32, //graphicZIndex: 9999, graphicYOffset: getFeatureYOffset(), title: 'LiveMap', cursor: 'help' }; var imageFeature = new OpenLayers.Feature.Vector(point, attributes, style); LiveMapAlerts_Layer.addFeatures([imageFeature]); //console.log('WME LMAO: Added alert at ' + lat + ',' + long); } //-------------------------------------------------------------------------------------------------------- function getFriendlyType(rawType){ switch(rawType){ case 'JAM': var friendlyType = 'Jam'; break; case 'POLICE': //Firefox var friendlyType = 'Police'; break; case 'POLICEMAN': //Chrome var friendlyType = 'Police'; break; case 'CHIT_CHAT': var friendlyType = 'Chit Chat'; break; case 'TRAFFIC_JAM': var friendlyType = 'Traffic Jam'; break; case 'HAZARD': var friendlyType = 'Hazard'; break; case 'WEATHERHAZARD': //Chrome JSON has all hazards as weather hazard var friendlyType = 'Hazard'; break; case 'ACCIDENT': var friendlyType = 'Accident'; break; case 'CONSTRUCTION': var friendlyType = 'Construction'; break; case 'ROAD_CLOSED': var friendlyType = 'Road Closed'; break; case 'OTHER': var friendlyType = 'Chit Chat'; break; default: var friendlyType = 'Unknown'; }; return friendlyType; } //-------------------------------------------------------------------------------------------------------- function getFriendlySubType(rawSubType){ switch(rawSubType){ case 'POLICE_VISIBLE': var friendlySubType = 'Visible Police Trap'; break; case 'POLICE_HIDING': var friendlySubType = 'Hidden Police Trap'; break; case 'ROAD_CLOSED_HAZARD': var friendlySubType = 'Hazard Closure'; break; case 'ROAD_CLOSED_CONSTRUCTION': var friendlySubType = 'Construction Closure'; break; case 'ROAD_CLOSED_EVENT': var friendlySubType = 'Closure'; break; case 'ACCIDENT_MINOR': var friendlySubType = 'Minor Accident'; break; case 'ACCIDENT_MAJOR': var friendlySubType = 'Major Accident'; break; case 'JAM_MODERATE_TRAFFIC': var friendlySubType = 'Moderate Traffic'; break; case 'JAM_HEAVY_TRAFFIC': var friendlySubType = 'Heavy Traffic'; break; case 'JAM_STAND_STILL_TRAFFIC': var friendlySubType = 'Stand Still Traffic'; break; case 'JAM_LIGHT_TRAFFIC': var friendlySubType = 'Light Traffic'; break; case 'HAZARD_ON_ROAD': var friendlySubType = 'Hazard on Road'; break; case 'HAZARD_ON_SHOULDER': var friendlySubType = 'Hazard on Shoulder'; break; case 'HAZARD_WEATHER': var friendlySubType = 'Weather Hazard'; break; case 'HAZARD_ON_ROAD_OBJECT': var friendlySubType = 'Object on Road'; break; case 'HAZARD_ON_ROAD_POT_HOLE': var friendlySubType = 'Pothole'; break; case 'HAZARD_ON_ROAD_ROAD_KILL': var friendlySubType = 'Road Kill'; break; case 'HAZARD_ON_ROAD_CAR_STOPPED': var friendlySubType = 'Car Stopped on Road'; break; case 'HAZARD_ON_SHOULDER_CAR_STOPPED': var friendlySubType = 'Car Stopped on Shoulder'; break; case 'HAZARD_ON_SHOULDER_ANIMALS': var friendlySubType = 'Animals on Shoulder'; break; case 'HAZARD_ON_SHOULDER_MISSING_SIGN': var friendlySubType = 'Missing Sign'; break; case 'HAZARD_WEATHER_FOG': var friendlySubType = 'Fog'; break; case 'HAZARD_WEATHER_HAIL': var friendlySubType = 'Hail'; break; case 'HAZARD_WEATHER_HEAVY_RAIN': var friendlySubType = 'Heavy Rain'; break; case 'HAZARD_WEATHER_HEAVY_SNOW': var friendlySubType = 'Heavy Snow'; break; case 'HAZARD_WEATHER_FLOOD': var friendlySubType = 'Flood'; break; case 'HAZARD_WEATHER_MONSOON': var friendlySubType = 'Monsoon'; break; case 'HAZARD_WEATHER_TORNADO': var friendlySubType = 'Tornado'; break; case 'HAZARD_WEATHER_HEAT_WAVE': var friendlySubType = 'Heat Wave'; break; case 'HAZARD_WEATHER_HURRICANE': var friendlySubType = 'Hurricane'; break; case 'HAZARD_WEATHER_FREEZING_RAIN': var friendlySubType = 'Freezing Rain'; break; case 'HAZARD_ON_ROAD_LANE_CLOSED': var friendlySubType = 'Closed Lane'; break; case 'HAZARD_ON_ROAD_OIL': var friendlySubType = 'Fresh Oil Spill'; break; case 'HAZARD_ON_ROAD_ICE': var friendlySubType = 'Recently Formed Ice'; break; case 'HAZARD_ON_ROAD_CONSTRUCTION': var friendlySubType = 'Construction'; break; default: var friendlySubType = ''; }; return friendlySubType; } //-------------------------------------------------------------------------------------------------------- function initializeLiveMapAlerts() { console.log("WME LMAO: Initializing"); var lmaoVisibility = true; LiveMapAlerts_Layer = new OpenLayers.Layer.Vector("LiveMap Alerts",{ rendererOptions: { zIndexing: true }, uniqueName: '__livemap_alerts' } ); I18n.translations.en.layers.name["__livemap_alerts"] = "LiveMap Alerts"; // restore saved settings if (localStorage.WMELiveMapAlerts) { console.log("WME LMAO: loading options"); var options = JSON.parse(localStorage.getItem("WMELiveMapAlerts")); lmaoVisibility = options[0]; } // overload the WME exit function saveLMAOOptions = function() { if (localStorage) { console.log("WME LMAO: saving options"); var options = []; lmaoVisibility = LiveMapAlerts_Layer.visibility; options[0] = lmaoVisibility; localStorage.setItem("WMELiveMapAlerts", JSON.stringify(options)); } } window.addEventListener("beforeunload", saveLMAOOptions, false); function showAlertPopup(f){ var attributes = f.attributes; var alertType = ((attributes.type == "WEATHERHAZARD") ? "HAZARD" : attributes.type); var alertSubType = ((attributes.subtype == null) ? "" : attributes.subtype); var alertDescription = ((attributes.description == null) ? "" : attributes.description); var alertStreet = ((attributes.street == null) ? "" : attributes.street); var alertCity = ((attributes.city == null) ? "" : attributes.city); var alertNear = ((attributes.near == null) ? "" : attributes.near); var alertReportBy = ((attributes.reportby == null) ? "" : attributes.reportby); var alertPubMillis = attributes.pubMillis; var alertDateTime = new Date(parseInt(alertPubMillis)); var d = new Date(); try{ var alertAge = Math.floor((d.getTime() - attributes.pubMillis) / 60000); } //milliseconds to minutes catch(e){ var alertAge = "unknown" } var reportDetail = "<b>LiveMap Alert Details</b>" + "<br>TYPE: " + getFriendlyType(alertType) + "<br>SUBTYPE: " + getFriendlySubType(alertSubType) + "<br>DESCRIPTION: " + alertDescription + "<br>STREET: " + alertStreet + "<br>CITY: " + alertCity + "<br>NEAR: " + alertNear + "<br>REPORT BY: " + alertReportBy + "<br>DATE: " + alertDateTime.toDateString() + "<br>TIME (user local): " + alertDateTime.toLocaleTimeString() + "<br>AGE: " + alertAge + " min" ; document.getElementById("divLMAO").innerHTML = reportDetail; divLMAO.style.visibility = 'visible'; }; function hideAlertPopup(){ divLMAO.style.visibility = 'hidden'; }; LiveMapAlerts_Layer.setZIndex(9999); Waze.map.addLayer(LiveMapAlerts_Layer); Waze.map.addControl(new OpenLayers.Control.DrawFeature(LiveMapAlerts_Layer, OpenLayers.Handler.Path)); LiveMapAlerts_Layer.setVisibility(lmaoVisibility); var divPopupCheck = document.getElementById('divLMAO'); if (divPopupCheck == null){ divLMAO = document.createElement('div'); divLMAO.id = "divLMAO"; divLMAO.style.position = 'absolute'; divLMAO.style.visibility = 'hidden'; divLMAO.style.top = '175px'; divLMAO.style.left = '375px'; divLMAO.style.zIndex = 1000; divLMAO.style.backgroundColor = 'aliceblue'; divLMAO.style.borderWidth = '3px'; divLMAO.style.borderStyle = 'ridge'; divLMAO.style.borderRadius = '10px'; divLMAO.style.boxShadow = '5px 5px 10px Silver'; divLMAO.style.padding = '4px'; document.body.appendChild(divLMAO); console.log('WME LMAO: Creating popup divLMAO'); } //clear existing LMAO features LiveMapAlerts_Layer.destroyFeatures(); var lmaoLayer = checkLayerNum(); Waze.map.events.register("mousemove", Waze.map, function(e) { hideAlertPopup(); var position = this.events.getMousePosition(e); //console.log('WME LMAO: coords xy = ' + position.x + ' ' + position.y); var lmaoLayer = checkLayerNum(); if(Waze.map.layers[lmaoLayer].features.length > 0){ //var alertCount = Waze.map.layers[lmaoLayer].features.length; //console.log('WME LMAO: Current LiveMap alert count = ' + alertCount); var alertFeatures = Waze.map.layers[lmaoLayer]; for(j=0; j<Waze.map.layers[lmaoLayer].features.length; j++){ var alertX = alertFeatures.features[j].attributes.pixel.x; var alertY = alertFeatures.features[j].attributes.pixel.y + getFeatureYOffset(); if(position.x > alertX - 10 && position.x < alertX + 10 && position.y > alertY - 10 && position.y < alertY + 20){ console.log('WME LMAO: hover over alert'); showAlertPopup(alertFeatures.features[j]); } } } }); //refresh if user moves map Waze.map.events.register("moveend", Waze.map, getLiveMapAlerts); window.setTimeout(getLiveMapAlerts(), 500); } //-------------------------------------------------------------------------------------------------------------- bootstrapLiveMapAlerts();