// ==UserScript==
// @name WME PlaceNames
// @version 0.1
// @description Show area place names in WME, color and highlight places by type and properties
// @include https://www.waze.com/editor/*
// @include https://www.waze.com/*/editor/*
// @include https://editor-beta.waze.com/editor/*
// @include https://editor-beta.waze.com/*/editor/*
// @copyright 2014, ragacs
// @namespace https://gf.qytechs.cn/users/6330
// ==/UserScript==
var wmepn_version = "0.1"
// Using parts from highlight and route speed scripts by various authors
/* bootstrap, will call initialiseLandmarkNames() */
function bootstrapLandmarkNames()
{
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();
}) ();
}
/* begin running the code! */
setTimeout(initialiseLandmarkNames, 999);
}
function testWhite(x) {
var white = new RegExp(/^\s$/);
return white.test(x.charAt(0));
};
function wordWrap(str, maxWidth) {
var newLineStr = "\n"; done = false; res = '';
do {
found = false;
// Inserts new line at first whitespace of the line
for (i = maxWidth - 1; i >= 0; i--) {
if (testWhite(str.charAt(i))) {
res = res + [str.slice(0, i), newLineStr].join('');
str = str.slice(i + 1);
found = true;
break;
}
}
// Inserts new line at maxWidth position, the word is too long to wrap
if (!found) {
res += [str.slice(0, maxWidth), newLineStr].join('');
str = str.slice(maxWidth);
}
if (str.length < maxWidth)
{
res = res + str;
done = true;
}
} while (!done);
return res;
}
function resetLandmarks()
{
for (var mark in Waze.model.venues.objects) {
var venue = Waze.model.venues.get(mark);
var poly = getId(venue.geometry.id);
if (poly !== null) {
if (poly.getAttribute("stroke-opacity") != 1) {
poly.setAttribute("fill","#d191d6");
poly.setAttribute("stroke","#d191d6");
poly.setAttribute("fill-opacity",0.3);
poly.setAttribute("stroke-opacity",1);
}
}
}
showLandmarkNames();
}
function showLandmarkNames() {
var routeLayer = undefined;
var rlayers = unsafeWindow.Waze.map.getLayersBy("uniqueName","__DrawPlaceNames");
if(rlayers.length == 0) {
var drc_style1 = new unsafeWindow.OpenLayers.Style({
strokeDashstyle: 'solid',
strokeColor : "${strokeColor}",
strokeOpacity: 1.0,
strokeWidth: "${strokeWidth}",
fillColor: '#0040FF',
fillOpacity: 1.0,
pointRadius: "${pointRadius}",
label : "${labelText}",
fontFamily: "Tahoma, Courier New",
labelOutlineColor: '#FFEEEE',
labelOutlineWidth: 2,
labelAlign: 'cm',
fontColor: "#301130",
fontOpacity: 1.0,
fontSize: "11px",
display: 'block'
});
var drc_mapLayer1 = new unsafeWindow.OpenLayers.Layer.Vector("Place Names", {
displayInLayerSwitcher: true,
uniqueName: "__DrawPlaceNames",
styleMap: new unsafeWindow.OpenLayers.StyleMap(drc_style1)
});
drc_mapLayer1.setVisibility(true);
//drc_mapLayer1.moveLayerToTop();
unsafeWindow.Waze.map.addLayer(drc_mapLayer1);
//var zLandmarks = Waze.map.getLayersBy("uniqueName", "landmarks")[0].getZIndex();
//var zPlaceNames = drc_mapLayer1.getZIndex();
//Waze.map.getLayersBy("uniqueName", "landmarks")[0].setZIndex(zPlaceNames);
//drc_mapLayer1.setZIndex(zLandmarks);
routeLayer = drc_mapLayer1;
}
else routeLayer = rlayers[0];
routeLayer.removeAllFeatures();
if (typeof Waze.model.venues == "undefined") {
return;
}
var showNames = routeLayer.getVisibility() && Waze.map.getLayersBy("uniqueName", "landmarks")[0].getVisibility();
// if checkbox unticked, reset places to original style
if (!showNames
&& !getId('_cbLandmarkColors').checked
&& !getId('_cbLandmarkHiliteNoName').checked) {
for (var mark in Waze.model.venues.objects) {
var venue = Waze.model.venues.get(mark);
var poly = getId(venue.geometry.id);
if (poly !== null) {
if (poly.getAttribute("stroke-opacity") != 1) {
poly.setAttribute("fill","#d191d6");
poly.setAttribute("stroke","#d191d6");
poly.setAttribute("fill-opacity",0.3);
poly.setAttribute("stroke-opacity",1);
}
}
}
return;
}
var specificCity = getId('_cbLandmarkHiliteNoName').checked;
var colorLandmarks = getId('_cbLandmarkColors').checked;
//var routeLayer = unsafeWindow.Waze.map.getLayersBy("uniqueName","landmarks")[0];
//routeLayer.styleMap.styles.default = drc_style1;
for (var mark in Waze.model.venues.objects) {
var venue = Waze.model.venues.get(mark);
var poly = getId(venue.geometry.id);
if (poly !== null && venue.geometry.toString().match(/^POLYGON/)) {
venueStreet = Waze.model.streets.get(venue.attributes.streetID);
selectedCityMatch = (venue.attributes.name.length == 0);
if(showNames && venue.attributes.name.length > 0)
{
// Add label texts
var labelFeatures = [];
var pt = new OpenLayers.Geometry.Point((venue.geometry.bounds.left + venue.geometry.bounds.right)/2, (venue.geometry.bounds.top + venue.geometry.bounds.bottom)/2);
var closest =_.min(routeLayer.features, function(feature) {
return feature.geometry.distanceTo(pt);
});
//console.log(closest);
var wrappedText = wordWrap(venue.attributes.name, 30);
var textFeature = new OpenLayers.Feature.Vector( pt, {labelText: wrappedText, fontColor: '#F0F0F0', pointRadius: 0 } );
labelFeatures.push(textFeature);
routeLayer.addFeatures(labelFeatures);
//if(closest != Infinity && closest.geometry.bounds.intersectsBounds(textFeature.geometry.bounds))
//{
// routeLayer.removeFeatures(labelFeatures);
//}
}
// Production polygons: #d191d6, Beta editor polygons: #c290c6
if ((poly.getAttribute("fill") == "#d191d6" || poly.getAttribute("fill") == "#c290c6") && poly.getAttribute("stroke-opacity") == 1) {
var categories = venue.attributes.categories;
if(colorLandmarks)
{
// gas station = orange
if (categories.indexOf("GAS_STATION") > -1) {
poly.setAttribute("fill","#f90");
poly.setAttribute("stroke","#f90");
}
// parking lot = cyan
else if (categories.indexOf("PARKING_LOT") > -1) {
poly.setAttribute("fill","#099");
poly.setAttribute("stroke","#0cc");
}
// water = blue
else if (categories.indexOf("RIVER_STREAM") > -1 ||
categories.indexOf("SEA_LAKE_POOL") > -1) {
poly.setAttribute("fill","#09f");
poly.setAttribute("stroke","#06c");
}
// park/grass/trees = green
else if (categories.indexOf("PARK") > -1 ||
categories.indexOf("FARM") > -1 ||
categories.indexOf("FOREST_GROVE") > -1 ||
categories.indexOf("GOLF_COURSE") > -1) {
poly.setAttribute("fill","#4f4");
poly.setAttribute("stroke","#6a6");
}
}
poly.setAttribute("stroke-opacity",0.97);
// highlight places which have no name
if (poly.getAttribute("fill") == "#d191d6" || poly.getAttribute("fill") == "#c290c6") {
if (specificCity && selectedCityMatch) {
poly.setAttribute("fill","#ff8");
poly.setAttribute("stroke","#cc0");
}
}
// if was yellow and now not yellow, reset
else if (poly.getAttribute("fill") == "#ff8" && (!specificCity || !selectedCityMatch)) {
poly.setAttribute("fill","#d191d6");
poly.setAttribute("stroke","#d191d6");
poly.setAttribute("stroke-opacity",1);
}
}
}
}
}
function toggleOptions () {
return false;
}
/* helper function */
function getElementsByClassName(classname, node) {
if(!node) node = document.getElementsByTagName("body")[0];
var a = [];
var re = new RegExp('\\b' + classname + '\\b');
var els = node.getElementsByTagName("*");
for (var i=0,j=els.length; i<j; i++)
if (re.test(els[i].className)) a.push(els[i]);
return a;
}
function getId(node) {
return document.getElementById(node);
}
/* =========================================================================== */
function initialiseLandmarkNames()
{
// global variables
advancedMode = false;
betaMode = location.hostname.match(/editor-beta.waze.com/);
lastSelected = null;
lastModified = false;
selectedLines = [];
// add new box to left of the map
var addon = document.createElement('section');
addon.id = "landmarkname-addon";
if (navigator.userAgent.match(/Chrome/)) {
addon.innerHTML = '<b>'
+ 'WME PlaceNames</b> v' + wmepn_version;
} else {
addon.innerHTML = '<b>'
+ 'WME PlaceNames</b> v' + wmepn_version;
}
// highlight landmarks
section = document.createElement('p');
section.style.padding = "8px 16px";
//section.style.textIndent = "-16px";
section.id = "nameLandmarks";
section.innerHTML = '<input type="checkbox" id="_cbLandmarkColors" /> <b>Color places</b><br>'
+ '<input type="checkbox" id="_cbLandmarkHiliteNoName" /> <b>Highlight places without name</b><br>';
addon.appendChild(section);
var userTabs = getId('user-info');
var navTabs = getElementsByClassName('nav-tabs', userTabs)[0];
var tabContent = getElementsByClassName('tab-content', userTabs)[0];
newtab = document.createElement('li');
newtab.innerHTML = '<a href="#sidepanel-landmarknames" data-toggle="tab">PlaceNames</a>';
navTabs.appendChild(newtab);
addon.id = "sidepanel-landmarknames";
addon.className = "tab-pane";
tabContent.appendChild(addon);
// setup onclick handlers for instant update:
getId('_cbLandmarkColors').onclick = resetLandmarks;
getId('_cbLandmarkHiliteNoName').onclick = resetLandmarks;
// restore saved settings
if (localStorage.WMELandmarkNamesScript) {
console.log("WME LandmarkNames: loading options");
options = JSON.parse(localStorage.WMELandmarkNamesScript);
getId('_cbLandmarkColors').checked = options[1];
getId('_cbLandmarkHiliteNoName').checked = options[2];
} else {
getId('_cbLandmarkColors').checked = true;
getId('_cbLandmarkHiliteNoName').checked = true;
}
if (typeof Waze.model.venues == "undefined") {
getId('_cbLandmarkColors').checked = false;
getId('_cbLandmarkHiliteNoName').checked = false;
getId('_cbLandmarkColors').disabled = true;
getId('_cbLandmarkHiliteNoName').disabled = true;
}
// overload the WME exit function
saveLandmarkNamesOptions = function() {
if (localStorage) {
console.log("WME LandmarkNames: saving options");
var options = [];
// preserve previous options which may get lost after logout
if (localStorage.WMELandmarkNamesScript)
options = JSON.parse(localStorage.WMELandmarkNamesScript);
options[1] = getId('_cbLandmarkColors').checked;
options[2] = getId('_cbLandmarkHiliteNoName').checked;
localStorage.WMELandmarkNamesScript = JSON.stringify(options);
}
}
window.addEventListener("beforeunload", saveLandmarkNamesOptions, false);
// begin periodic updates
window.setInterval(showLandmarkNames,500);
// trigger code when page is fully loaded, to catch any missing bits
window.addEventListener("load", function(e) {
var mapProblems = getId('map-problems-explanation')
if (mapProblems !== null) mapProblems.style.display = "none";
});
// register some events...
Waze.map.events.register("zoomend", null, showLandmarkNames);
Waze.map.events.register("changelayer", null, showLandmarkNames);
}
/* engage! =================================================================== */
bootstrapLandmarkNames();
/* end ======================================================================= */