WME PlaceNames

Show area place names in WME, color and highlight places by type and properties

当前为 2014-10-28 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name       WME PlaceNames
// @version    0.2
// @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://greasyfork.org/users/6330
// ==/UserScript==

var wmepn_version = "0.2"

// 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 showPoints = getId('_cbLandmarkPoints').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);
          }        
      }
    }
    if(poly !== null && venue.geometry.toString().match(/^POINT/) && showPoints == true && showNames == true && venue.attributes.name.length > 0)
    {
        // Add label texts
        var labelFeatures = [];        
        var pt = new OpenLayers.Geometry.Point(venue.geometry.x, venue.geometry.y);
        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);        
    }
  }
}

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> &nbsp; v' + wmepn_version;
  } else {
    addon.innerHTML  = '<b>'
                     + 'WME PlaceNames</b> &nbsp; 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>'
  					+  '<input type="checkbox" id="_cbLandmarkPoints" /> <b>Include point place names</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;
    getId('_cbLandmarkPoints').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];
    getId('_cbLandmarkPoints').checked    		= options[3];
  } else {
    getId('_cbLandmarkColors').checked = true;
    getId('_cbLandmarkHiliteNoName').checked = true;
    getId('_cbLandmarkPoints').checked = false;
  }

  if (typeof Waze.model.venues == "undefined") {
    getId('_cbLandmarkColors').checked = false;
    getId('_cbLandmarkHiliteNoName').checked = false;
    getId('_cbLandmarkPoints').checked = false;
    getId('_cbLandmarkColors').disabled = true;
    getId('_cbLandmarkHiliteNoName').disabled = true;
    getId('_cbLandmarkPoints').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;
        options[3] = getId('_cbLandmarkPoints').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 ======================================================================= */