WME PlaceNames

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

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name       WME PlaceNames
// @version    0.81
// @description  Show area and point 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://beta.waze.com/editor*
// @include             https://beta.waze.com/*/editor*
// @copyright  2017, ragacs
// @namespace https://greasyfork.org/users/6330
// @grant               none
// ==/UserScript==

var wmepn_translations = 
    {
        "en":
        {
            enable_script: "Enable script",
            enable_script_tooltip: "Toggle highlighting and place names layer\nUse the Layer selector or Shift+N hotkey to toggle names only",
            color_places: "Color places",
            color_places_tooltip: "Color the places like WMECH does",
            highlight_places: "Highlight places without name/HN",
            highlight_places_tooltip: "Highlight public places without name and private places without house number (yellow)",
            show: "Show",
            show_tooltip: "Select desired names to show",
            option_areaonly: "Area only",
            option_areapoint: "Area and Point",
            option_pointonly: "Point only",
            filter: "Filter",
            filter_tooltip: "Filter only the names containing this string (you could use regex e.g. /school/i)",
            show_locklevel: "Show lock level",
            show_locklevel_tooltip: "Display lock level after the name, like [L3] or [L4]",
            stop_over: "Stop over",
            stop_over_tooltip: "Limit displayed place names to the specified value",
            option_unlimited: "Unlimited",
            showing: "Showing",
            place_names_and: {
                one: "place name and",
                other: "place names and" },
            house_numbers:  {
                one: "house number",
                other: "house numbers" },
            translator: "translated by [Your Waze Nickname]"
        },
        "hu":
        {
            enable_script: "Szkript engedélyezése",
            enable_script_tooltip: "A színezés, kiemelés és a Helynevek réteg bekapcsolása\nHasználd a rétegválasztót vagy a Shift+N forróbillentyűt, ha csak a neveket akarod kapcsolgatni",
            color_places: "Helyek színezése",
            color_places_tooltip: "Helyek színezése, ahogyan a WMECH teszi",
            highlight_places: "Név/hsz nélküli helyek kiemelése",
            highlight_places_tooltip: "Kiemeli (sárgával) a névtelen nyilvános helyeket és a házszám nélküli magánházakat",
            show: "Mutasd",
            show_tooltip: "Válaszd ki a megmutatni kívánt neveket",
            option_areaonly: "Csak terület",
            option_areapoint: "Terület és pont",
            option_pointonly: "Csak pont",
            filter: "Szűrő",
            filter_tooltip: "Csak azokat a neveket mutassa, amik ezt a szöveget tartalmazzák (reguláris kifejezések használhatók, pl. /iskola/i)",
            show_locklevel: "Védelem mutatása",
            show_locklevel_tooltip: "Mutassa a védelmi szintet is a név után, pl. [L3] vagy [L4]",
            stop_over: "Maximum",
            stop_over_tooltip: "A képernyőn egyszerre látható név-feliratok számát korlátozza",
            option_unlimited: "Korlátlan",
            showing: "Látható",
            place_names_and: "helynév és",
            house_numbers: "házszám",
            translator: "fordította ragacs"
        },
        "cs":
        {
            enable_script: "Povolit skript",
            enable_script_tooltip: "Přepínač zvýraznění a jmen míst\nPoužijte menu Vrstvy nebo klávesovou zkratku Shift+N, aby se zobrazila jen jména míst",
            color_places: "Barevné odlišení",
            color_places_tooltip: "Barevné odlišení jako WMECH",
            highlight_places: "Odlišit nepojmenovaná místa",
            highlight_places_tooltip: "Odlišit nepojmenovaná veřejná místa a soukromá místa bez čísla domu (žlutě)",
            show: "Zobrazit",
            show_tooltip: "Zobrazit požadovaná jména",
            option_areaonly: "Jen plochy",
            option_areapoint: "Plochy a body",
            option_pointonly: "Jen body",
            filter: "Filtr",
            filter_tooltip: "Filtrovat jen jména obsahující tento řetězec (lze použít regex např. /škola/i)",
            show_locklevel: "Ukázat zámek",
            show_locklevel_tooltip: "Zobrazit zámek za jménem místa (např. [L3] nebo [L4])",
            stop_over: "Omezení",
            stop_over_tooltip: "Omezit zobrazená místa na zadanou hodnotu",
            option_unlimited: "Bez omezení",
            showing: "Zobrazení",
            place_names_and: "jména míst a",
            house_numbers: "čísla domů",
            translator: "překládal bures"
        },
        "nl" :
        {
            enable_script: "Script inschakelen",
            enable_script_tooltip: "De laag voor het weergeven en markeren van plaatsnamen beheren\nGebruik de laagselector of Shift+N om enkel de namen te beheren",
            color_places: "Voeg kleur toe aan plaatsen",
            color_places_tooltip: "Kleur de plaatsen in zoals het WMECH-script dit doet",
            highlight_places: "Markeer plaatsen zonder naam of huisnummer",
            highlight_places_tooltip: "Markeer publieke plaatsen zonder naam en private plaatsen zonder huisnummer (geel)",
            show: "Weergave",
            show_tooltip: "Selecteer welke namen er moeten weergegeven worden",
            option_areaonly: "Enkel gebieden",
            option_areapoint: "Gebieden en punten",
            option_pointonly: "Enkel punten",
            filter: "Filter",
            filter_tooltip: "Toon enkel de plaatsen met de volgende naam (je kan ook een regex gebruiken zoals /school/i)",
            show_locklevel: "Lock-level weergeven",
            show_locklevel_tooltip: "Geef het lock-level weer achter de naam als [L3] of [L4]",
            stop_over: "Beperk aantal plaatsnamen",
            stop_over_tooltip: "Beperk het aantal weergegeven plaatsnamen tot dit aantal",
            option_unlimited: "Onbeperkt",
            showing: "Huidige weergave: ",
            place_names_and: {
                one: "plaatsnaam en",
                other: "plaatsnamen en" },
            house_numbers:  {
                one: "huisnummer",
                other: "huisnummers" },
            translator: "vertaald door Glodenox"    
        },
        "fr":
        {
            enable_script: "Activer le script",
            enable_script_tooltip: "Pour activer et désactiver le calque \n Utilisez le gestionnaire de calque ou Shift+N pour les noms seulement",
            color_places: "Colorer les lieux ",
            color_places_tooltip: "Colore comme WME Color Highlight",
            highlight_places: "Surbrillance les lieux sans nom/HN",
            highlight_places_tooltip: "Surbrillance (Jaune) pour les lieux publiques sans nom & les lieux résidentiels sans numéro ",
            show: "Afficher",
            show_tooltip: "Séléctione les noms à afficher",
            option_areaonly: "Zones seulement",
            option_areapoint: "Zones & lieux",
            option_pointonly: "Lieux seulement",
            filter: "Filtrer",
            filter_tooltip: "Filtre les noms contenant ces lettres/mots (utilisation possible de regex ex : /school/i )",
            show_locklevel: "Afficher le niveau de verouillage",
            show_locklevel_tooltip: "Affiche le niveau de vérouillage en fin de nom ex : [L3] ou [L4]",
            stop_over: "Limiter à",
            stop_over_tooltip: "Limite le nombre de noms de lieux affichés",
            option_unlimited: "Illimité",
            showing: "Afficher",
            place_names_and: {
                one: "nom de lieu et",
                other: "noms des lieux et" },
            house_numbers:  {
                one: "numéro de rue",
                other: "numéros de rue" },
            translator: "adapté par no1ne"
        },
        "pl" : 
        {
            enable_script: "Włącz skrypt",
            enable_script_tooltip: "Włącz podświetlanie i warstwę nazw Miejsc\nUżyj wyboru warstw lub kombinacji Shift+N, żeby włączyć tylko nazwy",
            color_places: "Kolory miejsc",
            color_places_tooltip: "Pokoloruj miejsca tak, jak robi to WME Color Highlight",
            highlight_places: "Podświetl miejsca bez nazwy/nr adresowego",
            highlight_places_tooltip: "Podświetl miejsca publiczne bez nazwy i budynki mieszkalne bez numeru domu (żółty)",
            show: "Pokaż",
            show_tooltip: "Wybierz wybrane nazwy do pokazania",
            option_areaonly: "Tylko obszary",
            option_areapoint: "Obszary i Punkty",
            option_pointonly: "Tylko punkty",
            filter: "Filtr",
            filter_tooltip: "Filtruj tylko nazwy zawierające ten ciąg znaków (możesz użyć regex np. /szkoł[ay]/i)",
            show_locklevel: "Pokaż poziom blokady",
            show_locklevel_tooltip: "Wyświetl poziom blokady po nazwie, np. [L3] lub [L4]",
            stop_over: "Zatrzymaj po",
            stop_over_tooltip: "Ogranicz wyświetlanie nazw miejsc do określonej ilości",
            option_unlimited: "Nieograniczone",
            showing: "Pokazywanie",
            place_names_and: {
                one: "nazwa miejsca",
                other: "nazwy miejsc" },
            house_numbers: {
                one: "numer domu",
                other: "numery domów" },
            translator: "przetłumaczone przez TCholewa"
        },
        "he" : 
        {
            enable_script: "הפעל תוסף",
            enable_script_tooltip: "מציג שמות ומדגיש מקומות",
            color_places: "הדגש מקומות",
            color_places_tooltip: "מדגיש את המקומות כמו בתוסף  WME Color Highlights",
            highlight_places: "הדגש מקומות ללא שם/מספר בית",
            highlight_places_tooltip: "מדגיש מקומות ציבוריים ללא שם ומקומות מגורים ללא מספר בית (צהוב)",
            show: "הצג",
            show_tooltip: "בחר שמות להצגה",
            option_areaonly: "איזור בלבד",
            option_areapoint: "איזור ונקודות",
            option_pointonly: "נקודות בלבד",
            filter: "סנן",
            filter_tooltip: "סנן מקומות אשר מכילים את השם הבא (לדוג'- בית ספר וכיוב)",
            show_locklevel: "הצג רמת נעילה",
            show_locklevel_tooltip: "מציג את דרגת הנעילה בהמשך לשם המקום",
            stop_over: " מקס' תוצאות להצגה",
            stop_over_tooltip: "מגביל את כמות התוצאות המתאימות לערך",
            option_unlimited: "ללא הגבלה",
            showing: "מציג",
            place_names_and: {
                one: "שם המקום ו",
                other: "שמות מקומות ו" },
            house_numbers:  {
                one: "מספר בית",
                other: "מספרי בתים" },
            translator: "תורגם לעברית עי okrauss"
        },
        "es" : 
        {
            enable_script: "Activar el script",
            enable_script_tooltip: "Para activar y desactivar el resaltado de la capa de Place Names\nUtiliza el selector de capas o el atajo de teclado Shift+N para activar/desactivar solo los nombres",
            color_places: "Colorear places",
            color_places_tooltip: "Colorear los places como lo hace WMECH",
            highlight_places: "Resaltar places sin nombre o número de casa",
            highlight_places_tooltip: "Resaltar places públicos sin nombre y places privados sin número de casa (en amarillo)",
            show: "Mostrar",
            show_tooltip: "Seleccionar los nombres que se desean mostrar",
            option_areaonly: "Sólo Area",
            option_areapoint: "Area y Punto",
            option_pointonly: "Sólo Punto",
            filter: "Filtar",
            filter_tooltip: "Filtrar solo los nombres que contienen este texto (puedes utilizar regex Ej: /escuela/i)",
            show_locklevel: "Mostrar el nivel de bloqueo",
            show_locklevel_tooltip: "Mostrar el nivel de bloqueo luego del nombre, como [L3] o [L4]",
            stop_over: "Limitar a",
            stop_over_tooltip: "Limitar Place Names a el valor especificado",
            option_unlimited: "Ilimitado",
            showing: "Mostrando",
            place_names_and: {
                one: "Place Name y",
                other: "Place Names y" },
            house_numbers:  {
                one: "Número de casa",
                other: "Números de casa" },
            translator: "Traducido por ancho85"
        },
        "es-419" : 
        {
            enable_script: "Activar el script",
            enable_script_tooltip: "Para activar y desactivar el resaltado de la capa de Place Names\nUtiliza el selector de capas o el atajo de teclado Shift+N para activar/desactivar solo los nombres",
            color_places: "Colorear places",
            color_places_tooltip: "Colorear los places como lo hace WMECH",
            highlight_places: "Resaltar places sin nombre o número de casa",
            highlight_places_tooltip: "Resaltar places públicos sin nombre y places privados sin número de casa (en amarillo)",
            show: "Mostrar",
            show_tooltip: "Seleccionar los nombres que se desean mostrar",
            option_areaonly: "Sólo Area",
            option_areapoint: "Area y Punto",
            option_pointonly: "Sólo Punto",
            filter: "Filtar",
            filter_tooltip: "Filtrar solo los nombres que contienen este texto (puedes utilizar regex Ej: /escuela/i)",
            show_locklevel: "Mostrar el nivel de bloqueo",
            show_locklevel_tooltip: "Mostrar el nivel de bloqueo luego del nombre, como [L3] o [L4]",
            stop_over: "Limitar a",
            stop_over_tooltip: "Limitar Place Names a el valor especificado",
            option_unlimited: "Ilimitado",
            showing: "Mostrando",
            place_names_and: {
                one: "Place Name y",
                other: "Place Names y" },
            house_numbers:  {
                one: "Número de casa",
                other: "Números de casa" },
            translator: "Traducido por ancho85"
        },
        "pt-BR":
        {
            enable_script: "Habilitar script",
            enable_script_tooltip: "Destacar camadas e nomes de locais \nUse a marcação de camadas ou Shift+N para destacar nomes apenas",
            color_places: "Locais coloridos",
            color_places_tooltip: "Colirir os locais como WMECH faz",
            highlight_places: "Destaque locais sem nome/SN",
            highlight_places_tooltip: "Destacar locais público sem nome e locais privador sem numeração (amarelo)",
            show: "Mostrar",
            show_tooltip: "Escolha nomes desejados para mostrar",
            option_areaonly: "Apenas área",
            option_areapoint: "Área e ponto",
            option_pointonly: "Apenas ponto",
            filter: "Filtro",
            filter_tooltip: "Filtrar somente nomes que contenham esta string (você pde usar regex e.g. /school/i)",
            show_locklevel: "Mostrar nível de bloqueio",
            show_locklevel_tooltip: "Mostrar nível de bloqueio após o nome, tipo [L3] or [L4]",
            stop_over: "Limite",
            stop_over_tooltip: "Limite mostrado de nomes de lugares para o valor especificado",
            option_unlimited: "Sem limite",
            showing: "Mostrando",
            place_names_and: {
                one: "nome de local e",
                other: "nomes de locais e" },
            house_numbers:  {
                one: "numeração de casa",
                other: "numerações de casas" },
            translator: "translated by GabiruDriverX"
        }     
    };

// Using parts from highlight and route speed scripts by various authors

/* bootstrap, will call initialiseLandmarkNames() */
function bootstrapLandmarkNames()
{
    /* begin running the code! */
    setTimeout(initialiseLandmarkNames, 999);
}

function wmepn_wordWrap(str, maxWidth) {
    function testWhite(x) {
        var white = new RegExp(/^[ \t\r\n\f]$/); // We are not using \s because it matches non-breaking space too
        return white.test(x.charAt(0));
    }

    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 && str.length > maxWidth) {
            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 wmepn_resetLandmarks()
{
    var venues = Waze.model.venues;
    for (var mark in venues.objects) {
        var venue = venues.get(mark);
        var poly = wmepn_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);
            }
        }
    }
    wmepn_showLandmarkNames();
}

function wmepn_showLandmarkNames() {    
    wmepn_NameLayer.removeAllFeatures();
    if(wmepn_getId('sidepanel-landmarknames') === null) installLandmarkNamesTab();
    if(wmepn_getId('_cbLandmarkNamesEnable') === null) return;
    if (typeof Waze.model.venues == "undefined" || wmepn_getId('_cbLandmarkNamesEnable').checked === false) {
        wmepn_getId('_stLandmarkNumber').innerHTML = 0;
        wmepn_getId('_stLandmarkHNNumber').innerHTML = 0;
        return;
    }
    var venues = Waze.model.venues;
    var streets = Waze.model.streets;
    var map = Waze.map;
    var showNames = wmepn_NameLayer.getVisibility() && map.getLayersBy("uniqueName", "landmarks")[0].getVisibility();
    // if checkbox unticked, reset places to original style
    if (!showNames
        && !wmepn_getId('_cbLandmarkColors').checked
        && !wmepn_getId('_cbLandmarkHiliteNoName').checked) {
        for (var mark in venues.objects) {
            var venue = venues.get(mark);
            var poly = wmepn_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);
                }
            }
        }
        wmepn_getId('_stLandmarkNumber').innerHTML = 0;
        wmepn_getId('_stLandmarkHNNumber').innerHTML = 0;
        return;
    }

    var hiliteNoName = wmepn_getId('_cbLandmarkHiliteNoName').checked;    
    var colorLandmarks = wmepn_getId('_cbLandmarkColors').checked;
    var showPoints = (wmepn_getId('_seLandmarkPoints').value == "all" || wmepn_getId('_seLandmarkPoints').value == "point");
    var showAreas = (wmepn_getId('_seLandmarkPoints').value == "all" || wmepn_getId('_seLandmarkPoints').value == "area");
    var showLockLevel = wmepn_getId('_cbLandmarkLockLevel').checked;
    var limitNames = wmepn_getId('_seLandmarkLimit').value;
    var nameFilterArray = wmepn_getId('_inLandmarkNameFilter').value.split("/");
    var nameFilter = (nameFilterArray.length > 1 ? nameFilterArray[1] : nameFilterArray[0]);
    var nameFilterOptions = nameFilterArray[2];
    var nameFilterRegEx = (nameFilterArray.length > 1 ? new RegExp(nameFilter, nameFilterOptions) : null);
    var doFilter = function (name) {
        if(nameFilter.length === 0)
            return true; // show all when no filter entered
        if(nameFilterRegEx === null)
            return (name.indexOf(nameFilter) >= 0);
        else
            return nameFilterRegEx.test(name);
    };

    var drawnNames = 0;
    var drawnHNs = 0;
    for (var mark in venues.objects) {
        var venue = venues.get(mark);
        var poly = wmepn_getId(venue.geometry.id);
        var isPoint = venue.geometry.toString().match(/^POINT/);
        var isArea = venue.geometry.toString().match(/^POLYGON/);
        var trimmedName = venue.attributes.name.trim();
        var noTrName = (trimmedName.length == 0);
        if(showLockLevel) trimmedName +=  (noTrName ? "" : "\n") + "[L" + (venue.attributes.lockRank+1) + "]";
        var houseNumber = venue.attributes.houseNumber;
        if (poly !== null) {
            var venueStreet = streets.get(venue.attributes.streetID);
            var haveNoName = (venue.attributes.residential ? (houseNumber === undefined || houseNumber.length == 0) : noTrName);

            if(showNames && (showAreas || showPoints) && (limitNames == 0 || drawnNames < limitNames))
            {            
                var wrappedText = wmepn_wordWrap(trimmedName, 30);
                var filterMatched = (!noTrName && doFilter(trimmedName));
                if(showAreas && isArea && filterMatched)
                {
                    // Add label texts
                    var labelFeatures = [];
                    var bounds = venue.geometry.bounds;
                    var pt;
                    //if(bounds.getWidth() * bounds.getHeight() * .3 > venue.geometry.getArea() && venue.attributes.entryExitPoints.length > 0)
                    //	pt = venue.attributes.entryExitPoints[0].point;
                    //else	
                    pt = venue.geometry.getCentroid();
                    var textFeature = new OpenLayers.Feature.Vector( pt, {labelText: wrappedText, fontColor: '#F0F0F0', pointRadius: 0 } );
                    labelFeatures.push(textFeature);
                    wmepn_NameLayer.addFeatures(labelFeatures);
                    drawnNames++;
                }
                if(showPoints && isPoint && (filterMatched || (houseNumber !== undefined && houseNumber.length > 0)))
                {
                    // Add label texts
                    var labelFeatures = [];        
                    var pt = new OpenLayers.Geometry.Point(venue.geometry.x, venue.geometry.y);
                    var isHouseNumber = !filterMatched;
                    if(venue.attributes.residential)
                    {
                        // This will add house numbers to the hidden names to house numbers of residential places (user request)
                        wrappedText = houseNumber + ' - (' + wrappedText + ')';
                    }
                    var textFeature = new OpenLayers.Feature.Vector( pt, {labelText: (isHouseNumber ? houseNumber : wrappedText), fontColor: '#F0F0F0', pointRadius: 0, yOffset: -15, style: (isHouseNumber ? "italic" : "normal") } );
                    labelFeatures.push(textFeature);
                    wmepn_NameLayer.addFeatures(labelFeatures);
                    if(isHouseNumber) drawnHNs++;
                    else drawnNames++;
                }
            }

            wmepn_getId('_stLandmarkNumber').innerHTML = drawnNames;
            wmepn_getId('_stLandmarkHNNumber').innerHTML = drawnHNs;

            // 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;
                var colored = false;

                if(colorLandmarks)
                {
                    // gas station = orange
                    if (categories.indexOf("GAS_STATION") > -1) {
                        poly.setAttribute("fill","#f90");
                        poly.setAttribute("stroke","#f90");
                        colored = true;
                    }

                    // 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");
                        colored = true;
                    }

                    // 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");
                        colored = true;
                    }
                }

                poly.setAttribute("stroke-opacity",0.97);

                // highlight places which have no name and not colored before
                if (hiliteNoName && haveNoName && colored === false) {
                    poly.setAttribute("fill","#ff8");
                    poly.setAttribute("stroke","#cc0");
                    colored = true;
                }
                // if was yellow and now not yellow, reset
                else if (poly.getAttribute("fill") == "#ff8" && (!hiliteNoName || !haveNoName)) {
                    poly.setAttribute("fill","#d191d6");
                    poly.setAttribute("stroke","#d191d6");
                    poly.setAttribute("stroke-opacity",1);
                }        
            }
        }
    }
    wmepn_getId('_stLandmarkNumber').innerHTML = '<i>' + drawnNames + '</i> ' + I18n.t("wmepn.place_names_and", {count: drawnNames});
    wmepn_getId('_stLandmarkHNNumber').innerHTML = '<i>' + drawnHNs + '</i> ' + I18n.t("wmepn.house_numbers", {count: drawnHNs});
    //map.getLayersBy("name", "Place Names")[0].setZIndex(730);
}

wmepn_NameLayer = undefined;

function wmepn_toggleOptions () {
    return false;
}

/* helper function */
function wmepn_getId(node) {
    return document.getElementById(node);
}

function installLandmarkNamesTab()
{
    if(wmepn_getId('sidepanel-landmarknames') !== null || wmepn_getId('user-info') === null) return;
    
    // helper fn
    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;
    }

    // Some internationalization
    I18n.translations[I18n.locale].wmepn = wmepn_translations[I18n.locale];
    if(wmepn_translations[I18n.locale] === undefined) I18n.translations[I18n.locale].wmepn = wmepn_translations[I18n.defaultLocale];
    I18n.translations[I18n.locale].layers.name.__DrawPlaceNames = 'Place Names';

    // add new box to left of the map
    var addon = document.createElement('section');
    var translator="";
    addon.id = "landmarkname-addon";

    if(I18n.defaultLocale != I18n.locale)
        translator  = 'title="'+I18n.t("wmepn.translator")+'"';

    //if (navigator.userAgent.match(/Chrome/)) { }
    addon.innerHTML  = '<b>'
        + '<a href="https://www.waze.com/forum/viewtopic.php?f=819&t=116843" target="_blank" ' + translator + '>WME PlaceNames</a></b> &nbsp; v' + GM_info.script.version;
    if(wmepn_translations[I18n.locale] === undefined)
        addon.innerHTML  += ' <small>[<a href="https://www.waze.com/forum/viewtopic.php?f=819&t=116843&p=1302802#p1302802" target="_blank">translate me!</a>]</small>';


    // highlight landmarks
    section = document.createElement('p');
    section.style.padding = "8px 16px";
    //section.style.textIndent = "-16px";
    section.id = "nameLandmarks";
    section.innerHTML  = '<div title="'+I18n.t("wmepn.enable_script_tooltip")+'"><input type="checkbox" id="_cbLandmarkNamesEnable" /> <b>'+I18n.t("wmepn.enable_script")+'</b></div>'
        +  '<div title="'+I18n.t("wmepn.color_places_tooltip")+'"><input type="checkbox" id="_cbLandmarkColors" /> <b>'+I18n.t("wmepn.color_places")+'</b></div>'
        +  '<div title="'+I18n.t("wmepn.highlight_places_tooltip")+'"><input type="checkbox" id="_cbLandmarkHiliteNoName"/> <b>'+I18n.t("wmepn.highlight_places")+'</b></div>'
        +  '<div title="'+I18n.t("wmepn.show_tooltip")+'"><b>'+I18n.t("wmepn.show")+'</b> <select id="_seLandmarkPoints">'
        + '<option value="area">'+I18n.t("wmepn.option_areaonly")+'</option>'
        + '<option value="all">'+I18n.t("wmepn.option_areapoint")+'</option>'
        + '<option value="point">'+I18n.t("wmepn.option_pointonly")+'</option></select></div>'
        +  '<div title="'+I18n.t("wmepn.filter_tooltip")+'"><b>'+I18n.t("wmepn.filter")+':</b><input type="text" id="_inLandmarkNameFilter"/></div>'
        +  '<div title="'+I18n.t("wmepn.show_locklevel_tooltip")+'"><input type="checkbox" id="_cbLandmarkLockLevel" /> <b>'+I18n.t("wmepn.show_locklevel")+'</b></div>'
        +  '<div title="'+I18n.t("wmepn.stop_over_tooltip")+'"><b>'+I18n.t("wmepn.stop_over")+'</b> <select id="_seLandmarkLimit">'
        + '<option value="0">'+I18n.t("wmepn.option_unlimited")+'</option>'
        + '<option value="500">500</option>'
        + '<option value="200">200</option>'
        + '<option value="100">100</option>'
        + '<option value="50">50</option>'
        + '<option value="25">25</option>'
        + '<option value="10">10</option>'
        +'</select></div>'
        +   '<div><small>'+I18n.t("wmepn.showing")+' <span id="_stLandmarkNumber"></span> <span id="_stLandmarkHNNumber"></span></small></div>';
    addon.appendChild(section);

    var userTabs = wmepn_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:
    wmepn_getId('_cbLandmarkColors').onclick = wmepn_resetLandmarks;
    wmepn_getId('_cbLandmarkHiliteNoName').onclick = wmepn_resetLandmarks;
    wmepn_getId('_seLandmarkPoints').onchange = wmepn_resetLandmarks;
    wmepn_getId('_cbLandmarkNamesEnable').onclick = wmepn_resetLandmarks;
    wmepn_getId('_inLandmarkNameFilter').oninput = wmepn_showLandmarkNames;
    wmepn_getId('_cbLandmarkLockLevel').onclick = wmepn_showLandmarkNames;
    wmepn_getId('_seLandmarkLimit').onchange = wmepn_showLandmarkNames;
    
    // restore saved settings
    if (localStorage.WMELandmarkNamesScript) {
        console.log("WME LandmarkNames: loading options");
        options = JSON.parse(localStorage.WMELandmarkNamesScript);

        wmepn_getId('_cbLandmarkColors').checked   	    = options[1];
        wmepn_getId('_cbLandmarkHiliteNoName').checked  = options[2];
        wmepn_getId('_seLandmarkPoints').value    		= options[3];
        wmepn_NameLayer.setVisibility(options[4]);
        if(options[5] !== undefined)
            wmepn_getId('_cbLandmarkNamesEnable').checked   = options[5];
        else wmepn_NameLayer.setVisibility(true);
        if(options[6] !== undefined)
            wmepn_getId('_inLandmarkNameFilter').value		= options[6];
        if(options[7] !== undefined)
            wmepn_getId('_cbLandmarkLockLevel').checked     = options[7];
        if(options[8] !== undefined)
            wmepn_getId('_seLandmarkLimit').value     = options[8];
        else
            wmepn_getId('_seLandmarkLimit').value     = 100;
    } else {
        wmepn_getId('_cbLandmarkColors').checked = true;
        wmepn_getId('_cbLandmarkHiliteNoName').checked = true;
        wmepn_getId('_seLandmarkPoints').value = "area";
        wmepn_NameLayer.setVisibility(true);    
        wmepn_getId('_cbLandmarkNamesEnable').checked = true;
        wmepn_getId('_cbLandmarkLockLevel').checked = false;
        wmepn_getId('_seLandmarkLimit').value = 100;
    }
    var layerItem = '<li><div class="controls-container toggler"><input class="layer-switcher-item_placenames toggle" id="layer-switcher-item_placenames" type="checkbox"><label for="layer-switcher-item_placenames"><span class="label-text">PlaceNames</span></label></div></li>';
    $("#layer-switcher-group_places").parent().parent().children("ul.children").append(layerItem);
    $("#layer-switcher-item_placenames").click(function() { wmepn_NameLayer.setVisibility(!wmepn_NameLayer.getVisibility()); });
    $("#layer-switcher-item_placenames").prop("checked", wmepn_NameLayer.getVisibility());

    if (typeof Waze.model.venues == "undefined") {
        wmepn_getId('_cbLandmarkColors').checked = false;
        wmepn_getId('_cbLandmarkHiliteNoName').checked = false;
        wmepn_getId('_cbLandmarkColors').disabled = true;
        wmepn_getId('_cbLandmarkHiliteNoName').disabled = true;
        wmepn_getId('_seLandmarkPoints').disabled = true;      
        wmepn_getId('_cbLandmarkLockLevel').disabled = true;
        wmepn_getId('_seLandmarkLimit').disabled = true;
    }    
}


/* =========================================================================== */

function initialiseLandmarkNames()
{
    // global variables
    wmepn_betaMode = location.hostname.match(/beta.waze.com/);

    var map = Waze.map;
    // Create PlaceName layer
    var rlayers = map.getLayersBy("uniqueName","__DrawPlaceNames");
    if(rlayers.length === 0) {
        var lname = "Place Names";
        var style = new OpenLayers.Style({
            strokeDashstyle: 'solid',
            strokeColor : "${strokeColor}",
            strokeOpacity: 1.0,
            strokeWidth: "${strokeWidth}",
            fillColor: '#0040FF',
            fillOpacity: 1.0,
            pointRadius: "${pointRadius}",
            label : "${labelText}",
            fontFamily: "Tahoma, Arial, Verdana",
            labelOutlineColor: '#FFEEEE',
            labelOutlineWidth: 2,
            labelAlign: 'cm',
            fontColor: "#301130",
            fontOpacity: 1.0,
            fontSize: "11px",
            display: 'block',
            labelYOffset: "${yOffset}",
            fontStyle: "${style}"
        });
        var nameLayer = new OpenLayers.Layer.Vector(lname, {
            displayInLayerSwitcher: true,
            uniqueName: "__DrawPlaceNames",
            shortcutKey: "S+n",
            accelerator: "toggle" + lname.replace(/\s+/g,''),
            styleMap: new OpenLayers.StyleMap(style)
        });
        nameLayer.setVisibility(true);
        //drc_mapLayer1.moveLayerToTop();
        map.addLayer(nameLayer);
        //var zLandmarks = map.getLayersBy("uniqueName", "landmarks")[0].getZIndex();
        //var zPlaceNames = drc_mapLayer1.getZIndex();   
        //map.getLayersBy("uniqueName", "landmarks")[0].setZIndex(zPlaceNames);
        //drc_mapLayer1.setZIndex(zLandmarks);
        wmepn_NameLayer = nameLayer;
    }
    else wmepn_NameLayer = rlayers[0];

    installLandmarkNamesTab();
    
    // overload the WME exit function
    wmepn_saveLandmarkNamesOptions = function() {
        if (localStorage && wmepn_getId('_cbLandmarkColors') !== null) {
            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] = wmepn_getId('_cbLandmarkColors').checked;
            options[2] = wmepn_getId('_cbLandmarkHiliteNoName').checked;
            options[3] = wmepn_getId('_seLandmarkPoints').value;
            options[4] = wmepn_NameLayer.getVisibility();
            options[5] = wmepn_getId('_cbLandmarkNamesEnable').checked;
            options[6] = wmepn_getId('_inLandmarkNameFilter').value;
            options[7] = wmepn_getId('_cbLandmarkLockLevel').checked;
            options[8] = wmepn_getId('_seLandmarkLimit').value;

            localStorage.WMELandmarkNamesScript = JSON.stringify(options);
        }
    };
    window.addEventListener("beforeunload", wmepn_saveLandmarkNamesOptions, false);
    //window.setInterval(wmepn_saveLandmarkNamesOptions, 10000);

    // begin periodic updates
    //window.setInterval(wmepn_showLandmarkNames,500);

    // trigger code when page is fully loaded, to catch any missing bits
    window.addEventListener("load", function(e) {
        var mapProblems = wmepn_getId('map-problems-explanation');
        if (mapProblems !== null) mapProblems.style.display = "none";
    });

    // register some events...
    map.events.register("zoomend", null, wmepn_showLandmarkNames);
    map.events.register("changelayer", null, wmepn_showLandmarkNames);
    map.events.register("mouseout", null, wmepn_showLandmarkNames);
    Waze.selectionManager.events.register("selectionchanged", null, wmepn_showLandmarkNames);
}

/* engage! =================================================================== */
bootstrapLandmarkNames();

/* end ======================================================================= */