WME Color Errors

Adds colours to show errors

目前为 2016-07-07 提交的版本。查看 最新版本

// ==UserScript==
// @name             WME Color Errors
// @name:fr          WME Color Errors
// @version          0.06
// @description      Adds colours to show errors
// @description:fr   Colorisation pour afficher les erreurs
// @include          https://www.waze.com/editor/*
// @include          https://www.waze.com/*/editor/*
// @include          https://editor-beta.waze.com/*
// @exclude          https://www.waze.com/user/*
// @exclude          https://www.waze.com/*/user/*
// @namespace        https://greasyfork.org/fr/scripts/21186-wme-color-errors
// @author	         Sebiseba
// @copyright        Sebiseba 2014-2016
// @grant            none
// ==/UserScript==

var debug=true;
var WMECErrors={};
var ColorErrors_mapLayer=[];

// *********************
// ** HELPER FUNCTION **
// *********************

function getId(node) {
    return document.getElementById(node);
}
function getElementsByClassName(classname, node) {
    node || (node=document.getElementsByTagName("body")[0]);
    for (var a=[], re=new RegExp("\\b" + classname + "\\b"), els=
         node.getElementsByTagName("*"), i=
         0, j=
         els.length;i < j;i++) {
        re.test(els[i].className) && a.push(els[i]);
    }
    return a;
}
function IsJsonString(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}

// *************
// **  INIT   **
// *************
function CErrors_bootstrap() {
    if (typeof unsafeWindow === "undefined") {
        unsafeWindow   =( function () {
            var dummyElem=document.createElement('p');
            dummyElem.setAttribute('onclick', 'return window;');
            return dummyElem.onclick();
        }) ();
    }
    console.log("starting WME Color Errors", GM_info.script.version);
    CErrors_init();
}

function CErrors_init(){
    // Waze object needed
    CErrWaze=unsafeWindow.Waze;    if(typeof(CErrWaze) === 'undefined'){ if (debug) { console.error("WME ColorErrors - CErrWaze : NOK"); } window.setTimeout(CErrors_init, 500); return; }
    CErrorsMap=
        CErrWaze.map;       if(typeof(CErrorsMap) == 'undefined'){ if (debug) { console.error("WME ColorErrors - CErrorsmap : NOK"); } window.setTimeout(CErrors_init, 500); return; }
    CErrorsModel=CErrWaze.model;   if(typeof(CErrorsModel) == 'undefined'){ if (debug) { console.error("WME ColorErrors - CErrorsmodel : NOK"); } window.setTimeout(CErrors_init, 500); return; }
    CErrorsI18n=
        unsafeWindow.I18n; if(typeof (CErrorsI18n) == 'undefined') { if (debug) { console.error('WME ColorErrors - CErrorsI18n : NOK'); } setTimeout(CErrors_init, 500); return; }
    // OpenLayers
    CErrorsOpenLayers=unsafeWindow.OpenLayers; if(typeof(CErrorsOpenLayers) === 'undefined'){ if (debug) { console.error("WME ColorErrors - OpenLayers : NOK"); } window.setTimeout(CErrors_init, 500); return; }
    // Waze GUI needed
    CErrorshandle=
        getId("user-info"); if(typeof(CErrorshandle) == 'undefined'){ window.setTimeout(CErrors_init, 500); return; }
    CErrorshandleClass=
        getElementsByClassName("nav-tabs", CErrorshandle)[0]; if(typeof(CErrorshandleClass) === 'undefined'){ window.setTimeout(CErrors_init, 500); return; }
    CErrorshandleClass2=
        getElementsByClassName("tab-content", CErrorshandle)[0]; if(typeof(CErrorshandleClass2) === 'undefined'){ window.setTimeout(CErrors_init, 500); return; }

    // Verify localStorage. Init if empty or not correct
    if (typeof(localStorage.WMEColorErrors) === "undefined" || localStorage.WMEColorErrors.lenght===null || !IsJsonString(localStorage.WMEColorErrors)) {
        WMECErrors.seg_Bad=false; // Bad Segments (group)
        WMECErrors.seg_Priv=true; // Private with bad name
        WMECErrors.seg_Park=true; // Parking with name (but Place / Square)
        WMECErrors.seg_Rail=true; // Railroad with bad name
        WMECErrors.seg_HW_name=true; //Highways with bad name
        WMECErrors.seg_Ramp_name=true; // Ramp with 3 directions or more
        WMECErrors.seg_Dir_name=true; // Directions but not Ramp/Freeway
        WMECErrors.seg_RShield=true; // Wrong prefix
        WMECErrors.seg_DleSpace=true; // Double space in name
        // POI
        WMECErrors.poi_Bad=false; // Bad POI (group)
        WMECErrors.poi_Park_name=true; // Parking with [P]
        WMECErrors.poi_Address=true; // Dxxx/Nxxx in or no address
        WMECErrors.poi_Entry=true; // Entry Point not defined
        WMECErrors.poi_LandM=true; // Landmark with address (street |& city)
        WMECErrors.poi_DleSpace=true; // Double space in name
        // Low errors
        WMECErrors.poi_Resid=true; // Maybe a residential
        WMECErrors.poi_Google=true; // No link with Google
        localStorage.setItem('WMEColorErrors', JSON.stringify(WMECErrors));
    }

    // WME Layers check
    var layers=CErrorsMap.getLayersBy("uniqueName","__WME_Color_Errors");
    if(layers.length === 0) {
        var ColorErrors_style=new CErrorsOpenLayers.Style({
            pointRadius: 2,
            fontWeight: "normal",
            label : "${labelText}",
            fontFamily: "Tahoma, Courier New",
            labelOutlineColor: "#FFFFFF",
            labelOutlineWidth: 2,
            fontColor: '#000000',
            fontSize: "10px"
        });

        ColorErrors_mapLayer=new CErrorsOpenLayers.Layer.Vector("Color Errors", {
            displayInLayerSwitcher: false,
            uniqueName: "__WME_Color_Errors",
            styleMap: new CErrorsOpenLayers.StyleMap(ColorErrors_style)
        });

        I18n.translations.en.layers.name["__WME_Color_Errors"]="Color Errors";
        CErrorsMap.addLayer(ColorErrors_mapLayer);
        ColorErrors_mapLayer.setVisibility(true);

    }
    CErrors_Mainhtml();
}

// *************
// **  HTML   **
// *************

function CErrors_Mainhtml() {
    if (CErrorsI18n.locale == 'fr') {
        CErrSeg=new Array('Contrôle des segments',
                          'Mauvais segments',
                          'Voie privée avec mauvais nom',
                          'Parking avec un nom (sauf Place & Square)',
                          'Mauvais nom de voie ferrée',
                          'Types Routes avec mauvais nom',
                          'Bretelle avec plusieurs directions',
                          'Direction (sauf bretelle et Autoroute)',
                          'Mauvais préfixe (RoadShield)',
                          'Double espace dans le nom'
                         );
        CErrPoi=new Array('Contrôle des places',
                          'Mauvaise places',
                          'Parking nommé [P] ou rien',
                          'Pas d\'adresse ou contenant Dxxx/Nxxx',
                          'Point d\'entré non défini',
                          'Site naturel avec adresse',
                          'Double espace dans le nom',
                          'Sûrement une place résidentielle',
                          'Pas de lien avec Google'
                         );
    }
    else {
        CErrSeg=new Array('Segments Checking',
                          'Bad Segments',
                          'Private with bad name',
                          'Parking with name (But Place / Square)',
                          'Railroad with bad name',
                          'Highways with bad name',
                          'Ramp with several directions',
                          'Direction (but Ramp/Freeway)',
                          'Wrong prefix (RoadShield)',
                          'Double spacing in name'
                         );
        CErrPoi=new Array('Places Checking',
                          'Bad Places',
                          'Parking named [P] or null',
                          'No address or Dxxx/Nxxx within',
                          'Entry Point not defined',
                          'Natural features with address',
                          'Double spacing in name',
                          'Maybe a residential',
                          'No link with Google'
                         );
    }

    //Create content in CErrors's tab
    var CEnewtab=
        document.createElement('li');
    CEnewtab.innerHTML="<a href='#sidepanel-ColorErrors' data-toggle='tab'><span class='fa fa-eye' title='Color Errors'></span></a>";
    CErrorshandleClass.appendChild(CEnewtab);

    var WMECErrors=JSON.parse(localStorage.getItem('WMEColorErrors'));
    var CEaddon=document.createElement('section');
    CEaddon.id="sidepanel-ColorErrors";
    CEaddon.innerHTML="<div style='float:left; margin-left:5px;'><b><a href='https://greasyfork.org/scripts/xxx-wme-color-errors' target='_blank'><u>WME Color Errors</u></a></b> v"+ GM_info.script.version +"</div>"
        + '<br><br><div class="waze-icon-road" style="float:left;"></div><h4 style="float:left;margin-left:3px;">'+CErrSeg[0]+'</h4><div style="clear:both;margin-left:5px;">'
        + '<input type="checkbox" id="_seg_Bad"      '+(WMECErrors.seg_Bad       ? ' checked' : '')+'/> '+CErrSeg[1]+'<br><div id="BadSeg" style="margin-left:10px;">'
        + '<input type="checkbox" class="_seg" id="_seg_Priv"     '+(WMECErrors.seg_Priv      ? ' checked' : '')+(WMECErrors.seg_Bad ? '' : ' disabled')+'/> '+CErrSeg[2]+'<br>'
        + '<input type="checkbox" class="_seg" id="_seg_Park"     '+(WMECErrors.seg_Park      ? ' checked' : '')+(WMECErrors.seg_Bad ? '' : ' disabled')+'/> '+CErrSeg[3]+'<br>'
        + '<input type="checkbox" class="_seg" id="_seg_Rail"     '+(WMECErrors.seg_Rail      ? ' checked' : '')+(WMECErrors.seg_Bad ? '' : ' disabled')+'/> '+CErrSeg[4]+'<br>'
        + '<input type="checkbox" class="_seg" id="_seg_HW_name"  '+(WMECErrors.seg_HW_name   ? ' checked' : '')+(WMECErrors.seg_Bad ? '' : ' disabled')+'/> '+CErrSeg[5]+'<br>'
        + '<input type="checkbox" class="_seg" id="_seg_Dir_name" '+(WMECErrors.seg_Dir_name  ? ' checked' : '')+(WMECErrors.seg_Bad ? '' : ' disabled')+'/> '+CErrSeg[6]+'<br>'
        + '<input type="checkbox" class="_seg" id="_seg_Ramp_name"'+(WMECErrors.seg_Ramp_name ? ' checked' : '')+(WMECErrors.seg_Bad ? '' : ' disabled')+'/> '+CErrSeg[7]+'<br>'
        + '<input type="checkbox" class="_seg" id="_seg_RShield"  '+(WMECErrors.seg_RShield   ? ' checked' : '')+(WMECErrors.seg_Bad ? '' : ' disabled')+'/> '+CErrSeg[8]+'<br>'
        + '<input type="checkbox" class="_seg" id="_seg_DleSpace" '+(WMECErrors.seg_DleSpace  ? ' checked' : '')+(WMECErrors.seg_Bad ? '' : ' disabled')+'/> '+CErrSeg[9]+'<br></div></div>'
        + '<br><div class="waze-icon-place" style="float:left;"></div><h4 style="float:left;margin-left:3px;">'+CErrPoi[0]+'</h4><div style="clear:both;margin-left:5px;">'
        + '<input type="checkbox" id="_poi_Bad"      '+(WMECErrors.poi_Bad       ? ' checked' : '')+'/> '+CErrPoi[1]+'<br><div id="BadPoi" style="margin-left:10px;">'
        + '<input type="checkbox" class="_poi" id="_poi_Park_name"'+(WMECErrors.poi_Park_name ? ' checked' : '')+(WMECErrors.poi_Bad ? '' : ' disabled')+'/> '+CErrPoi[2]+'<br>'
        + '<input type="checkbox" class="_poi" id="_poi_Address"  '+(WMECErrors.poi_Address   ? ' checked' : '')+(WMECErrors.poi_Bad ? '' : ' disabled')+'/> '+CErrPoi[3]+'<br>'
        + '<input type="checkbox" class="_poi" id="_poi_Entry"    '+(WMECErrors.poi_Entry     ? ' checked' : '')+(WMECErrors.poi_Bad ? '' : ' disabled')+'/> '+CErrPoi[4]+'<br>'
        + '<input type="checkbox" class="_poi" id="_poi_LandM"    '+(WMECErrors.poi_LandM     ? ' checked' : '')+(WMECErrors.poi_Bad ? '' : ' disabled')+'/> '+CErrPoi[5]+'<br>'
        + '<input type="checkbox" class="_poi" id="_poi_DleSpace" '+(WMECErrors.poi_DleSpace  ? ' checked' : '')+(WMECErrors.poi_Bad ? '' : ' disabled')+'/> '+CErrPoi[6]+'<br>'
        + '<input type="checkbox" class="_poi" id="_poi_Resid"    '+(WMECErrors.poi_Resid     ? ' checked' : '')+(WMECErrors.poi_Bad ? '' : ' disabled')+'/> '+CErrPoi[7]+'<br>'
        + '<input type="checkbox" class="_poi" id="_poi_Google"   '+(WMECErrors.poi_Google    ? ' checked' : '')+(WMECErrors.poi_Bad ? '' : ' disabled')+'/> '+CErrPoi[8]+'<br></div></div>'
    ;
    CEaddon.className='tab-pane';
    CErrorshandleClass2.appendChild(CEaddon);

    getId('_seg_Bad').onclick=(function(){
        var ls=JSON.parse(localStorage.WMEColorErrors);
        if (getId('_seg_Bad').checked === true) {
            for (var i=0; getElementsByClassName('_seg', BadSeg) [i]; i++) getElementsByClassName('_seg', BadSeg) [i].disabled=false;
            ls.seg_Bad=true;
        }
        else {
            for (var i=0; getElementsByClassName('_seg', BadSeg) [i]; i++) getElementsByClassName('_seg', BadSeg) [i].disabled=true;
            ls.seg_Bad=false;
        }
        localStorage.setItem('WMEColorErrors', JSON.stringify(ls));
        CErrColor();
    });
    getId('_poi_Bad').onclick=(function(){
        var ls=JSON.parse(localStorage.WMEColorErrors);
        if (getId('_poi_Bad').checked === true) {
            for (var i=0; getElementsByClassName('_poi', BadPoi) [i]; i++) getElementsByClassName('_poi', BadPoi) [i].disabled=false;
            ls.poi_Bad=true;
        }
        else {
            for (var i=0; getElementsByClassName('_poi', BadPoi) [i]; i++) getElementsByClassName('_poi', BadPoi) [i].disabled=true;
            ls.poi_Bad=false;
        }
        localStorage.setItem('WMEColorErrors', JSON.stringify(ls));
        CErrColor();
    });
    getId('_seg_Priv').onclick=(function(){      var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_seg_Priv').checked === true) ? ls.seg_Priv=true : ls.seg_Priv=false;                localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_seg_Park').onclick=(function(){      var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_seg_Park').checked === true) ? ls.seg_Park=true : ls.seg_Park=false;                localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_seg_Rail').onclick=(function(){      var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_seg_Rail').checked === true) ? ls.seg_Rail=true : ls.seg_Rail=false;                localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_seg_HW_name').onclick=(function(){   var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_seg_HW_name').checked === true) ? ls.seg_HW_name=true : ls.seg_HW_name=false;       localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_seg_Dir_name').onclick=(function(){  var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_seg_Dir_name').checked === true) ? ls.seg_Dir_name=true : ls.seg_Dir_name=false;    localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_seg_Ramp_name').onclick=(function(){ var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_seg_Ramp_name').checked === true) ? ls.seg_Ramp_name=true : ls.seg_Ramp_name=false; localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_seg_RShield').onclick=(function(){   var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_seg_RShield').checked === true) ? ls.seg_RShield=true : ls.seg_RShield=false;       localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_seg_DleSpace').onclick=(function(){  var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_seg_DleSpace').checked === true) ? ls.seg_DleSpace=true : ls.seg_DleSpace=false;    localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_poi_Park_name').onclick=(function(){ var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_poi_Park_name').checked === true) ? ls.poi_Park_name=true : ls.poi_Park_name=false; localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_poi_Address').onclick=(function(){   var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_poi_Address').checked === true) ? ls.poi_Address=true : ls.poi_Address=false;       localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_poi_Entry').onclick=(function(){     var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_poi_Entry').checked === true) ? ls.poi_Entry=true : ls.poi_Entry=false;             localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_poi_LandM').onclick=(function(){     var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_poi_LandM').checked === true) ? ls.poi_LandM=true : ls.poi_LandM=false;             localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_poi_DleSpace').onclick=(function(){  var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_poi_DleSpace').checked === true) ? ls.poi_DleSpace=true : ls.poi_DleSpace=false;    localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_poi_Resid').onclick=(function(){     var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_poi_Resid').checked === true) ? ls.poi_Resid=true : ls.poi_Resid=false;             localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });
    getId('_poi_Google').onclick=(function(){    var ls=JSON.parse(localStorage.WMEColorErrors); (getId('_poi_Google').checked === true) ? ls.poi_Google=true : ls.poi_Google=false;          localStorage.setItem('WMEColorErrors', JSON.stringify(ls)); CErrColor(); });

    CErrWaze.selectionManager.events.register("selectionchanged", null, CErrColor);
    CErrorsModel.actionManager.events.register("afterclearactions", null, CErrColor);
    CErrorsModel.actionManager.events.register("afterundoaction", null, CErrColor);
    CErrorsMap.events.register("zoomend", null, CErrColor);
    CErrorsMap.events.register("moveend", null, CErrColor);
    CErrColor();
}

function CErrColor(){
    var lineFeature=[], ls=JSON.parse(localStorage.WMEColorErrors);

    // Initialize layer
    try { ColorErrors_mapLayer.destroyFeatures(); }
    catch(err){ log('err destroyFeatures: ',err); }

    //Segments Checking
    if (ls.seg_Bad) {
        for (var seg in CErrorsModel.segments.objects) {
            // Get values
            var segment=CErrorsModel.segments.get(seg);
            var attributes=segment.attributes;
            var line=getId(segment.geometry.id);
            if (typeof (segment)==='undefined' || line === null || segment.state == "Update" || segment.selected == true) continue;
            var sid=attributes.primaryStreetID;
            var street=CErrorsModel.streets.get(sid);
            var name=street.name;
            var roadType=attributes.roadType;
            if (attributes.primaryStreetID === null || attributes.primaryStreetID === undefined) continue;
            if (Waze.model.streets.get(attributes.primaryStreetID) === null || Waze.model.streets.get(attributes.primaryStreetID) === undefined) continue;
            var newWidth="", newColor="", newOpacity="0", gline="";

            if (street.name) {
                if (ls.seg_Priv) { // Private with bad name
                    if (attributes.roadType===17 && /^(Le |La |Les |Allée|Avenue|Boulevard|Chemin|Cité|Clos|Cours|Domaine|Hameau|Impasse|Lotissement|Parc|Passage|Place|Promenade|Quai|Résidence|Rue|Route|Sente|Sentier|Square|Villa|Voie)/.test(street.name)===false) {
                        newColor="#ff7700"; newWidth=3; newOpacity=0.95; gline=segment.geometry.getVertices();
                    }
                }
                if (ls.seg_Park) { // Parking with name (But Place / Square)
                    if (attributes.roadType===20 && /^(Place|Square)/.test(street.name)===false) {
                        newColor="#ff0000"; newWidth=3; newOpacity=0.95; gline=segment.geometry.getVertices();
                    }
                }
                if (ls.seg_Rail) { // Railroad with bad name
                    if (attributes.roadType===18 && /^(Voie Ferrée$|Metro|Tramway)/.test(street.name)===false) {
                        newColor="#ff0000"; newWidth=3; newOpacity=0.95; gline=segment.geometry.getVertices();
                    }
                }
                if (ls.seg_HW_name) { // Highways with bad name
                    if (/^(3|4|6)$/.test(attributes.roadType) && (/:/.test(street.name)===true && /^[A|C|D|N|M|R][0-9]+[a-z]?[0-9]?/.test(street.name)===false) && /^>/.test(street.name)===false && /^[Sortie ]+[0-9]+/.test(street.name)===false && /^(Rocade|Périphérique)/.test(street.name)===false) {
                        newColor="#ff0000"; newWidth=3; newOpacity=0.95; gline=segment.geometry.getVertices();
                    }
                }
                if (ls.seg_Ramp_name) {
                    if (/^(3|4)$/.test(attributes.roadType) && /\/.*\//.test(street.name)) { // Ramp with 3 directions or more
                        newColor="#ff0000"; newWidth=3; newOpacity=0.95; gline=segment.geometry.getVertices();
                    }
                    else if (/^(3|4)$/.test(attributes.roadType) && /\//.test(street.name)) {  // Ramp with 2 directions
                        newColor="#ff7700"; newWidth=3; newOpacity=0.95; gline=segment.geometry.getVertices();
                    }
                }
                if (ls.seg_Dir_name) { // Directions but not Ramp/Freeway
                    if (/^[^3|4]$/.test(attributes.roadType) && /[:|>]/.test(street.name)) {
                        newColor="#ff0000"; newWidth=3; newOpacity=0.95; gline=segment.geometry.getVertices();
                    }
                }
                if (ls.seg_RShield) { // Wrong prefix (RoadShield)
                    var trs=street.name.split(" - ");
                    if (attributes.roadType!=19 && /^[A|C|D|N|M|R][0-9]+[a-z]?[0-9]?$/.test(trs[0].replace(".",""))===false &&  / - /.test(street.name)===true) {
                        newColor="#ff0000"; newWidth=3; newOpacity=0.95; gline=segment.geometry.getVertices();
                    }
                }
                if (ls.seg_DleSpace) { // Double spacing in name
                    if (/  /.test(street.name)===true) {
                        newColor="#ff0000"; newWidth=3; newOpacity=0.95; gline=segment.geometry.getVertices();
                    }
                }
            }
            // Highlight if error
            if (gline!="") {
                var style={
                    strokeWidth: newWidth,
                    strokeColor: newColor,
                    strokeOpacity: newOpacity
                };
                var points=[];
                for (var i=0; i<gline.length; i++) { points.push(new CErrorsOpenLayers.Geometry.Point(gline[i].x, gline[i].y)); }
                var newline=new CErrorsOpenLayers.Geometry.LineString(points);
                lineFeature.push(new CErrorsOpenLayers.Feature.Vector(newline, null, style));
            }
        }
    }

    //Places Checking
    if (ls.poi_Bad) {
        for (var poi in CErrorsModel.venues.objects) {
            // Get values
            var venue=CErrorsModel.venues.get(poi);
            var pattributes=venue.attributes;
            var poly=getId(venue.geometry.id);
            if (typeof (venue)==='undefined' || poly === null || poi.state=="Update" || venue.selected) continue;
            var categories=pattributes.categories;
            var pname=pattributes.name;
            var venueStreet=CErrorsModel.streets.get(venue.attributes.streetID);
            if (venueStreet) { var venueCity = Waze.model.cities.get(venueStreet.cityID); }
            var newWidth="", newColor="", newOpacity="0", gpoly="";

            if (ls.poi_Resid) { // maybe a residential POI
                if ((/^[0-9][ ]?[a-zA-Z]/.test(pname)===true || /^(Allée|Avenue|Boulevard|Chemin|Cité|Clos|Cours|Domaine|Hameau|Impasse|Lotissement|Parc|Passage|Place|Promenade|Quai|Résidence|Rue|Route|Sente|Sentier|Square|Villa|Voie)/.test(pname)===true) && venue.attributes.residential===false) {
                    newColor="#ff7700"; newWidth=15; newOpacity=0.95; gline=venue.geometry.getVertices();
                }
            }
            if (ls.poi_Google) { //POI without Google link
                if (pattributes.externalProviderIDs.length===0 && pattributes.residential===false) {
                    newColor="#ff7700"; newWidth=15; newOpacity=0.95; gline=venue.geometry.getVertices();
                }
            }
            if (ls.poi_Park_name && categories.indexOf("PARKING_LOT") > -1  && pattributes.residential===false) { // Parking named [P] or null
                if (pname.indexOf("[P]") > -1) {
                    newColor="#ff0000"; newWidth=15; newOpacity=0.5; gpoly=venue.geometry.getVertices();
                }
                else if (pname==="") {
                    newColor="#ff7700"; newWidth=15; newOpacity=0.5; gpoly=venue.geometry.getVertices();
                }
            }
            if (ls.poi_Address) { // POI with bad address (Nxxx/Dxxx) or without address
                if (typeof (venueStreet)!='undefined' && (/^[A|D|N|M|R][0-9]+/.test(venueStreet.name) || typeof (venueStreet.name)==='undefined')) {
                    newColor="#ff0000"; newWidth=15; newOpacity=0.5; gpoly=venue.geometry.getVertices();
                }
            }
            if (ls.poi_Entry) { // POI with default entryExitPoints
                if (/(RIVER_STREAM|CANAL|SEA_LAKE_POOL|SWAMP_MARSH|ISLAND|FOREST_GROVE|BRIDGE|SWAMP_MARSH|PARK|JUNCTION_INTERCHANGE)/.test(categories)===false && pattributes.entryExitPoints.length===0 && venue.isPoint()===false) {
                    newColor="#ff0000"; newWidth=15; newOpacity=0.5; gpoly=venue.geometry.getVertices();
                }
            }
            if (ls.poi_LandM) { // Landmark with road name or city name
                if (/(RIVER_STREAM|CANAL|SEA_LAKE_POOL|SWAMP_MARSH|ISLAND|FOREST_GROVE|BRIDGE|SWAMP_MARSH)/.test(categories) && ((venueStreet && venueStreet.name) || (venueCity && venueCity.name))) {
                    newColor="#ff0000"; newWidth=15; newOpacity=0.5; gpoly=venue.geometry.getVertices();
                }
            }
            if (ls.poi_DleSpace) { // Double spacing in name
                if (typeof (venueStreet)!='undefined' && (/  /.test(venueStreet.name)===true || /  /.test(pname)===true)) {
                    newColor="#ff0000"; newWidth=15; newOpacity=0.5; gpoly=venue.geometry.getVertices();
                }
            }
            // Highlight if error
            if (gpoly!="") {
                var style={
                    strokeWidth: newWidth,
                    strokeColor: newColor,
                    strokeOpacity: newOpacity,
                    fillOpacity: 0
                };
                var points=[];
                for (var i=0; i<gpoly.length; i++) { points.push(new CErrorsOpenLayers.Geometry.Point(gpoly[i].x, gpoly[i].y)); }
                var newpoly=new CErrorsOpenLayers.Geometry.LinearRing(points);
                lineFeature.push(new CErrorsOpenLayers.Feature.Vector(newpoly, null, style));
            }
        }
    }

    // Display highlighted features
    try{ ColorErrors_mapLayer.addFeatures(lineFeature); }
    catch(err){ log('err addFeatures: ',err); }
}
CErrors_bootstrap();