WME Draw Borders France

Affiche les limites des villes et départements français

// ==UserScript==
// @name         WME Draw Borders France
// @version      2025.01.20.001
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAABCJJREFUWIWtl09oHFUcx7/fN7vJ1jSlrUp2c2oCPRjddGcGoV5sqBSk0IKCh4JF0RwC2grVIP6B1pOIIJWIlygIWkEsUvVYWrGnXmYmzcqqKK0HkdWW7aFKd5PZ9/WQ3WWzyW4nyf5gYd7v/d77fub33vzePiKheZ53GsCJRnMuDMN3ko7tZU6SINd1jxtjPiR5X+M3lc1mr5fL5cWtApgkQSQPreN70ff93FYBEmUgm80WSB7oANgj6ZVcLrc/l8vFQ0NDv1cqlfpGAVJJgkjebm9LugbgNwBHSB4GcHjHjh0V3/e/qtfr3xhjTgI4BOCGpBNRFF3qOve9xPP5/Hg6nb4GYIjkrKQoDMMrAOKJiYndmUzmGIDnAfgk18wn6Q7J8SAIbm0GgJ7nXSY5Za09F0XRs90CJycnH3Ec5zmSp0iu2lvW2qNRFH2/3riem9B13ZdITkkq12q1k71iFxcXf4qiaBbAr+1+SarX6ze6jesKkM/nx0m+K0nW2plSqVTpBdAmeELSnTbXv3Ec/7VRAKbT6U9Jbpf05cLCwrdJxAEgiqJLJMettUcl/UhyOJPJvN8tft094Lruy8aYOUnlarX6cNK377RCobDXGLMIYFDSVBRFVzpj1tSBfD4/7jjOeQBpa+3xYrG4sBlxACiXy5XR0VFD8iCA/bt27Zq/efPmqlrRWgLP8057nndrYGDgl82kvpvdvXv3PUk/k3xo27Ztr3f2G2Cl1pM8Q/J+AOlG3+WtigNAqVRakjQjyUp6s1Ao7F0D0KXWT/UDAAAaa/8ZyYwxZt513SO+7z/QApC05jtdz7cVq1ars42qeMAY852k667rPmEAII7js5Jam03SQhzHZ/sJkEqlRgFsb7ZJDpOcMwBQLBZvA3gVAKy1V8MwfLTh65s5jjO2zlkx1voKrLUjDbI/AMT9FAeApaWlBUnqcF9sHcckswAg6e9+iwPA4ODgGZKUVG2Kx3E83Q4wAgDGmHK/xX3fnwbwgqT/SD4WBEGx2dcCkDRCEtbavmbA8zxf0tyKhGbCMCy297f2QDMD/VyCiYmJ3QDOk8xI+jiKoi86Y9YAGGP6BWAymcw5knustVdrtdqpdYOaD5KyALC8vNwXANd1T5N8UtI/cRw/UyqVlnoBkOSDkjQwMLBlgEKhcJjk25JiAMeKxeKf3WJTAJDP58ewcghVgiBY3qRuyvO8xyXtJDnf+F/4VhAEPQ81ep53EMAFksOSRPKDIAhe24jyvn37djqO8wPJQpv7QhAETwPoLD6rqQF8RHIYWFkHSadc1x0HkDgTJMc6xGGtXbyXeBNgrGMyknwqqXgvqCRxKQAXARxpOhpH5gw2kAFrrWuMeaPdJ+liIoA4jqdTqdQnaLtKhWHY9SrVxb72PK+Gtut7FEWfJxn4P1GVx29d/9ycAAAAAElFTkSuQmCC
// @description  Affiche les limites des villes et départements français
// @author       Sebiseba & Electrochock1974
// @copyright    Sebiseba 2017-2024 (Inspired by Draw Border - ©giovanni-cortinovis)
// @include      https://www.waze.com/*/editor*
// @include      https://beta.waze.com/*/editor*
// @match        https://www.waze.com/*/editor*
// @match        https://beta.waze.com/*/editor*
// @exclude      https://www.waze.com/*/user*
// @grant        GM_xmlhttpRequest
// @connect      api.wazefrance.com
// @connect      radars.securite-routiere.gouv.fr
// @require      https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
// @namespace Sebiseba
// ==/UserScript==

(function() {
    var DBFhandleClass, DBFhandleClass2, CitiesOld = [], StatesOld = [], StatesPROld = [], Cty_Layer = [], Dpt_Layer = [], PR_Layer = [], Cam_Layer = [], Ban_Layer = [], Equip_Layer = [], Etabl_Layer = [], debug = '';
    var icon_DrB = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAABCJJREFUWIWtl09oHFUcx7/fN7vJ1jSlrUp2c2oCPRjddGcGoV5sqBSk0IKCh4JF0RwC2grVIP6B1pOIIJWIlygIWkEsUvVYWrGnXmYmzcqqKK0HkdWW7aFKd5PZ9/WQ3WWzyW4nyf5gYd7v/d77fub33vzePiKheZ53GsCJRnMuDMN3ko7tZU6SINd1jxtjPiR5X+M3lc1mr5fL5cWtApgkQSQPreN70ff93FYBEmUgm80WSB7oANgj6ZVcLrc/l8vFQ0NDv1cqlfpGAVJJgkjebm9LugbgNwBHSB4GcHjHjh0V3/e/qtfr3xhjTgI4BOCGpBNRFF3qOve9xPP5/Hg6nb4GYIjkrKQoDMMrAOKJiYndmUzmGIDnAfgk18wn6Q7J8SAIbm0GgJ7nXSY5Za09F0XRs90CJycnH3Ec5zmSp0iu2lvW2qNRFH2/3riem9B13ZdITkkq12q1k71iFxcXf4qiaBbAr+1+SarX6ze6jesKkM/nx0m+K0nW2plSqVTpBdAmeELSnTbXv3Ec/7VRAKbT6U9Jbpf05cLCwrdJxAEgiqJLJMettUcl/UhyOJPJvN8tft094Lruy8aYOUnlarX6cNK377RCobDXGLMIYFDSVBRFVzpj1tSBfD4/7jjOeQBpa+3xYrG4sBlxACiXy5XR0VFD8iCA/bt27Zq/efPmqlrRWgLP8057nndrYGDgl82kvpvdvXv3PUk/k3xo27Ztr3f2G2Cl1pM8Q/J+AOlG3+WtigNAqVRakjQjyUp6s1Ao7F0D0KXWT/UDAAAaa/8ZyYwxZt513SO+7z/QApC05jtdz7cVq1ars42qeMAY852k667rPmEAII7js5Jam03SQhzHZ/sJkEqlRgFsb7ZJDpOcMwBQLBZvA3gVAKy1V8MwfLTh65s5jjO2zlkx1voKrLUjDbI/AMT9FAeApaWlBUnqcF9sHcckswAg6e9+iwPA4ODgGZKUVG2Kx3E83Q4wAgDGmHK/xX3fnwbwgqT/SD4WBEGx2dcCkDRCEtbavmbA8zxf0tyKhGbCMCy297f2QDMD/VyCiYmJ3QDOk8xI+jiKoi86Y9YAGGP6BWAymcw5knustVdrtdqpdYOaD5KyALC8vNwXANd1T5N8UtI/cRw/UyqVlnoBkOSDkjQwMLBlgEKhcJjk25JiAMeKxeKf3WJTAJDP58ewcghVgiBY3qRuyvO8xyXtJDnf+F/4VhAEPQ81ep53EMAFksOSRPKDIAhe24jyvn37djqO8wPJQpv7QhAETwPoLD6rqQF8RHIYWFkHSadc1x0HkDgTJMc6xGGtXbyXeBNgrGMyknwqqXgvqCRxKQAXARxpOhpH5gw2kAFrrWuMeaPdJ+liIoA4jqdTqdQnaLtKhWHY9SrVxb72PK+Gtut7FEWfJxn4P1GVx29d/9ycAAAAAElFTkSuQmCC";
    console.log('WME Draw Borders France : ' + GM_info.script.version + ' starting');

    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;
    }
    function deltaDate(adresseDate) {
        let diffTime = Math.abs(new Date().valueOf() - new Date(adresseDate).valueOf());
        let days = diffTime / (24*60*60*1000);
        let hours = (days % 1) * 24;
        let minutes = (hours % 1) * 60;
        [days, hours, minutes] = [Math.floor(days), Math.floor(hours), Math.floor(minutes)]
        var delta = days + 'j ' + hours + 'h '+ minutes + 'm';
        return delta;
    }
    function addScriptsMenu() {
        if (typeof getElementsByClassName('collapsible-GROUP__SCRIPTS', getId('layer-switcher-region')) [0] != 'object') {
            if ('undefined' === typeof localStorage.posScriptMenu) { localStorage.setItem('posScriptMenu', '["top"]'); }

            var menuParent = getElementsByClassName('togglers', getId('layer-switcher-region')) [0];

            var scriptMenu = document.createElement('li');
            scriptMenu.className="group";

            var scriptMenuContent = document.createElement('div');
            scriptMenuContent.className='layer-switcher-toggler-tree-category';
            scriptMenuContent.innerHTML='<wz-button id="developScript" color="clear-icon" size="xs"><i class="toggle-category w-icon w-icon-caret-down"></i></wz-button>'+
                '<wz-toggle-switch disabled="false" checked id="layer-switcher-group__scripts" class="layer-switcher-group__scripts" tabindex="0" name="" value=""></wz-toggle-switch>'+
                '<label class="label-text" for="layer-switcher-group__scripts">Scripts</label>';
            scriptMenu.appendChild(scriptMenuContent);
            var groupScripts = document.createElement('ul');
            groupScripts.className="collapsible-GROUP__SCRIPTS";
            scriptMenu.appendChild(groupScripts);

            if (JSON.parse(localStorage.posScriptMenu)[0] == 'top') { menuParent.insertBefore(scriptMenu, menuParent.firstChild); }
            else { menuParent.appendChild(scriptMenu); }

            getId('developScript').addEventListener('click', function(e) {
                if (groupScripts.className == 'collapsible-GROUP__SCRIPTS') {
                    groupScripts.className='collapsible-GROUP__SCRIPTS collapse-layer-switcher-group';
                    this.innerHTML='<i class="toggle-category w-icon w-icon-caret-down upside-down"></i>';
                } else {
                    groupScripts.className='collapsible-GROUP__SCRIPTS';
                    this.innerHTML='<i class="toggle-category w-icon w-icon-caret-down"></i>';
                }
            });
            getId('layer-switcher-group__scripts').addEventListener('click', function(e) {
                if (groupScripts.className == 'collapsible-GROUP__SCRIPTS') {
                    groupScripts.className='collapsible-GROUP__SCRIPTS collapse-layer-switcher-group';
                    getId('developScript').innerHTML='<i class="toggle-category w-icon w-icon-caret-down upside-down"></i>';
                } else {
                    groupScripts.className='collapsible-GROUP__SCRIPTS';
                    getId('developScript').innerHTML='<i class="toggle-category w-icon w-icon-caret-down"></i>';
                }
            });
            var lng = I18n.locale;
            if (lng == 'fr') { var title="Position menu des scripts", top="En haut", bottom="En bas"; }
            else if (lng == 'es') { var title="Posición del menú de script", top="En alto", bottom="Abajo"; }
            else { var title="Scripts menu position", top="On top", bottom="On bottom"; }

            var optionPosMenu=document.createElement('div');
            optionPosMenu.className='settings__form-group';
            optionPosMenu.innerHTML='<wz-label html-for="">'+title+'</wz-label><span style="padding-right:15px;">'+bottom+' </span><wz-toggle-switch name="posScriptMenu" id="posScriptMenu" checked='+(JSON.parse(localStorage.posScriptMenu)[0] == 'top' ? "true":"false")+' class="alert-settings-visibility-toggle" tabindex="0" value=""> '+top+'<input type="checkbox" name="posScriptMenu" value="" style="display: none; visibility: hidden;"></wz-toggle-switch>';
            getElementsByClassName('settings__form', getId('sidepanel-prefs')) [0].appendChild(optionPosMenu);
            getId('posScriptMenu').addEventListener('click', function(e) {
                menuParent.removeChild(scriptMenu);
                if (getId('posScriptMenu').checked == true) {
                    menuParent.insertBefore(scriptMenu, menuParent.firstChild);
                    localStorage.setItem('posScriptMenu', JSON.stringify(["top"]));
                } else {
                    menuParent.appendChild(scriptMenu);
                    localStorage.setItem('posScriptMenu', JSON.stringify(["bottom"]));
                }
            })
            if ('undefined' === typeof localStorage.posScriptMenu || !isJsonString(localStorage.posScriptMenu)) { localStorage.setItem('posScriptMenu', '[]'); }
        }
    }
    function addTooltipToCheckbox(checkboxId, tooltipText) {
        var checkbox = document.getElementById(checkboxId);
        if (checkbox) {
            // Création du conteneur div qui utilisera Flexbox pour aligner le texte et l'icône
            var container = document.createElement('div');
            container.style.display = 'flex';
            container.style.alignItems = 'center';
            container.style.justifyContent = 'space-between';

            // Assurez-vous que le texte actuel est enveloppé dans un élément, par exemple un span
            var textSpan = document.createElement('span');
            textSpan.textContent = checkbox.textContent;
            checkbox.textContent = ''; // Enlever le texte actuel du checkbox

            // Création du tooltip avec l'icône d'information
            var tooltipContainer = document.createElement('wz-rich-tooltip');
            tooltipContainer.className = "sc-wz-rich-tooltip-h sc-wz-rich-tooltip-s";
            tooltipContainer.setAttribute("hide-delay-ms", "200");

            var tooltip = document.createElement('wz-tooltip');
            tooltip.className = "sc-wz-rich-tooltip sc-wz-rich-tooltip-s";

            var tooltipSource = document.createElement('wz-tooltip-source');
            tooltipSource.className = "sc-wz-tooltip-source-h sc-wz-tooltip-source-s";

            var tooltipTarget = document.createElement('wz-tooltip-target');
            tooltipTarget.className = "sc-wz-tooltip-target-h sc-wz-tooltip-target-s";

            var infoIcon = document.createElement('i');
            infoIcon.className = "w-icon w-icon-info layer-selector-info-icon";
            infoIcon.title = tooltipText;

            tooltipTarget.appendChild(infoIcon);
            tooltipSource.appendChild(tooltipTarget);
            tooltip.appendChild(tooltipSource);
            tooltipContainer.appendChild(tooltip);

            // Ajout du texte et du tooltip au conteneur
            container.appendChild(textSpan); // Ajoutez le texte en premier
            container.appendChild(tooltipContainer); // Ensuite, ajoutez l'icône d'information

            // Ajout du conteneur dans le checkbox
            checkbox.appendChild(container);
        }
    }

    function DBFstep1() {
        if (typeof (W.map) == 'undefined') { window.setTimeout(DBFstep1, 500); return; }
        if (typeof (W.model) === 'undefined') { window.setTimeout(DBFstep1, 500); return; }
        if (typeof (OpenLayers) === 'undefined') { window.setTimeout(DBFstep1, 500); return; }
        if (document.querySelector('.togglers') === null) { window.setTimeout(DBFstep1, 500); return; }
        DBFhandle=getId("user-info"); if(typeof(DBFhandle) == 'undefined'){ window.setTimeout(DBFstep1, 500); return; }
        DBFhandleClass=getElementsByClassName("nav-tabs", DBFhandle)[0]; if(typeof(DBFhandleClass) === 'undefined'){ window.setTimeout(DBFstep1, 500); return; }
        DBFhandleClass2=getElementsByClassName("tab-content", DBFhandle)[0]; if(typeof(DBFhandleClass2) === 'undefined'){ window.setTimeout(DBFstep1, 500); return; }
        window.setTimeout(DBFstep2, 500);
    }
    function DBFstep2() {
        if ('undefined' === typeof localStorage.speedCamList || !isJsonString(localStorage.speedCamList)) { localStorage.setItem('speedCamList', '[]'); }
        if ('undefined' === typeof localStorage.DBFsettings || !isJsonString(localStorage.DBFsettings)) { localStorage.setItem('DBFsettings', '{"optionDBF0":false,"optionDBF1":true,"optionDBF2":false,"optionDBF3":false,"optionDBF4":true,"optionDBF5":false,"optionDBF6":false}'); }

        // WME Layers check
        addScriptsMenu();
        WazeWrap.Interface.AddLayerCheckbox("_scripts", "Limites Villes", false, LayerVilToggled);
        checklayer("__WME_Draw_Border_Cty");
        WazeWrap.Interface.AddLayerCheckbox("_scripts", "Limites Départements", false, LayerDepToggled);
        checklayer("__WME_Draw_Border_Dpt");
        WazeWrap.Interface.AddLayerCheckbox("_scripts", "Points Routiers", false, LayerPRToggled);
        checklayer("__WME_Draw_Border_PR");
        WazeWrap.Interface.AddLayerCheckbox("_scripts", "Radars", false, LayerCamToggled);
        checklayer("__WME_Draw_Border_Cam");
        WazeWrap.Interface.AddLayerCheckbox("_scripts", "Infos BAN ", false, LayerBanToggled);
        checklayer("__WME_Draw_Border_Ban");
        addTooltipToCheckbox("layer-switcher-item_infos_ban", "Affiche les adresses tirées de la BAN à partir du zoom 19.");
        WazeWrap.Interface.AddLayerCheckbox("_scripts", "Equipements", false, LayerEquipToggled);
        checklayer("__WME_Draw_Border_Equip");
        WazeWrap.Interface.AddLayerCheckbox("_scripts", "Etablissements", false, LayerEtablToggled);
        checklayer("__WME_Draw_Border_Etabl");

        W.map.events.register("moveend", null, show_border);
        W.map.events.register('zoomend', null, show_border);
        W.map.events.register('moveend', null, show_border);
        W.map.events.register('mergeend', null, show_border);

        W.map.events.register("moveend", null, load_ban);
        W.map.events.register('zoomend', null, load_ban);
        W.map.events.register('moveend', null, load_ban);
        W.map.events.register('mergeend', null, load_ban);
        W.selectionManager.events.register('selectionchanged', null, load_ban);
        W.model.actionManager.events.register("afterclearactions", null, load_ban);
        W.model.actionManager.events.register("afterundoaction", null, load_ban);

        getId('layer-switcher-item_infos_ban_').addEventListener('click', function(e) {
            if ($('#layer-switcher-item_infos_ban_').prop('checked')===true && $('#layer-switcher-item_house_numbers').prop('checked')===false) { $('#layer-switcher-item_house_numbers').click(); }
            if (Ban_Layer.visibility === true) { getId('layerBanVisib').style.backgroundColor='#bbffcc'; }
            else { getId('layerBanVisib').style.backgroundColor='#fac3c3'; }
            load_ban();
        });
        insertScriptHTML();
        load_radar(); // Just one time on launch
    }
    function insertScriptHTML() {
        var Scss = document.createElement('style');
        Scss.type = 'text/css';
        var css = '.DBFlegend {float:left; clear:both; margin: 0 8px 10px 0;}'
        +'.infoState {float:left; height:24px; border:1px solid #d5d7db; border-radius:12px; font-size:12px; font-weight:600; margin:0 8px 10px; padding-left:11px; padding-top:2px; cursor:pointer;}'

        Scss.innerHTML = css;
        document.body.appendChild(Scss);

        //Create content in CErrors's tab
        var DBFnewtab=document.createElement('li');
        DBFnewtab.innerHTML="<a href='#sidepanel-DrawBordersFR' data-toggle='tab'><img src="+icon_DrB+" style='height:16px;'></a>"; //<span class='fa fa-globe' title='Draw Borders FR'></span>
        DBFhandleClass.appendChild(DBFnewtab);

        var DBFcontent='<div style="float:left; margin-left:5px;padding-bottom:10px;"><b><a href="https://greasyfork.org/fr/scripts/8138-wme-draw-borders-france" target="_blank"><u>WME Draw Borders France</u></a></b> v'+ GM_info.script.version +'</div>'

        +'<wz-label html-for="">Infos BAN</wz-label>'
        +'<div id="layerBanVisib" class="infoState" style="width:100px;">Calque BAN</div>'
        +'<div id="layerHNVisib" class="infoState" style="width:90px;">Calque HN</div>'
        +'<div id="zoomBanValue" class="infoState" style="width:80px;"></div>'
        +'<div id="loadBanData" class="infoState" style="width:36px; float:right; margin-right:10px;"><i class="fa fa-refresh" aria-hidden="true"></i></div>'
        +'<div style="float:left; display:inline-block; margin-bottom:22px; font-size:11px;">Nombre de numéros BAN Chargés : </div><div id="banQty" style="float:left; margin-left:5px;">0</div>'

        +'<wz-label html-for="">Limites, PR, Radars, Equipements</wz-label>'
        +'<div id="zoomMiscValue" class="infoState" style="width:80px;"></div>'
        +'<div id="loadMiscData" class="infoState" style="width:36px; float:right; margin-right:10px;"><i class="fa fa-refresh" aria-hidden="true"></i></div>'

        +'<wz-label html-for="" style="margin-top:15px;">Légende</wz-label>'
        +'<div class="DBFlegend" style="color:#ff0000; font-size:11px; font-family:Webdings;">n</div><div style="float:left;"> Non certifié</div>'
        +'<div class="DBFlegend" style="color:#00dd00; font-size:11px; font-family:Webdings;">n</div><div style="float:left;"> Certifié</div>'
        +'<div class="DBFlegend" style="color:#ff8000;">Non présent sur WME</div>'
        +'<div class="DBFlegend" style="color:#44aadd;">Présent sur WME</div>'
        +'<wz-label html-for="" style="margin-top:15px;">Options</wz-label><div class="settings__form-group">'
        +'<wz-checkbox name="optionDBF0" checked="false" id="optionDBF0" value="on">Afficher uniquement les n° non renseignés dans WME<input type="checkbox" name="optionDBF0" value="on" style="display: none; visibility: hidden;"></wz-checkbox>'
        +'<wz-checkbox name="optionDBF1" checked="false" id="optionDBF1" value="on">Afficher uniquement les données certifiées<input type="checkbox" name="optionDBF1" value="on" style="display: none; visibility: hidden;"></wz-checkbox>'
        +'<wz-checkbox name="optionDBF2" checked="false" id="optionDBF2" value="on">Afficher les anciens noms de communes<input type="checkbox" name="optionDBF2" value="on" style="display: none; visibility: hidden;"></wz-checkbox>'
        +'<wz-checkbox name="optionDBF6" checked="false" id="optionDBF6" value="on">Masquer le nom de la commune<input type="checkbox" name="optionDBF2" value="on" style="display: none; visibility: hidden;"></wz-checkbox>'
        +'<wz-checkbox name="optionDBF8" checked="false" id="optionDBF8" value="on">Afficher uniquement les n° de rue<input type="checkbox" name="optionDBF8" value="on" style="display: none; visibility: hidden;"></wz-checkbox></div>'
        +'<wz-checkbox name="optionDBF3" checked="false" id="optionDBF3" value="on">Afficher l\'ancienneté des données<input type="checkbox" name="optionDBF6" value="on" style="display: none; visibility: hidden;"></wz-checkbox>'
        +'<wz-checkbox name="optionDBF4" checked="false" id="optionDBF4" value="on">Déplacement de la carte initialise les données<input type="checkbox" name="optionDBF4" value="on" style="display: none; visibility: hidden;"></wz-checkbox></div>'

        +'<wz-label html-for="" style="margin-top:15px;">Filtres</wz-label><div class="settings__form-group">'
        +'<wz-checkbox name="optionDBF7" checked="false" id="optionDBF7" value="on">Afficher uniquement les lieux-dits<input type="checkbox" name="optionDBF7" value="on" style="display: none; visibility: hidden;"></wz-checkbox></div>'
        +'<wz-checkbox name="optionDBF9" checked="false" id="optionDBF9" value="on">Supprimer lieu-dit dans le nom de rue<input type="checkbox" name="optionDBF9" value="on" style="display: none; visibility: hidden;"></wz-checkbox></div>'
        +'<wz-checkbox name="optionDBF5" checked="false" id="optionDBF5" value="on">Afficher uniquement les infos d\'une rue<input type="checkbox" name="optionDBF5" value="on" style="display: none; visibility: hidden;"></wz-checkbox></div>'

        +'<wz-label html-for="" style="margin-top:15px;">Rue sélectionnée</wz-label>'
        +'<wz-body2 class="alert-settings-period-label" id="selectedRoad"></wz-body2>'

        +'<div class="region-switcher" style="margin-top:15px;"><wz-select id="DBFselectRoad" name="selectRue" label="Rues disponibles" value=""><wz-option value="">---</wz-option><input name="selectRue" style="display: none; visibility: hidden;"></wz-select></div>';
        var DBFaddon=document.createElement('section');
        DBFaddon.id="sidepanel-DrawBordersFR";
        DBFaddon.innerHTML=DBFcontent;
        DBFaddon.className='tab-pane';
        DBFhandleClass2.appendChild(DBFaddon);

        var settings = JSON.parse(localStorage.DBFsettings);
        (settings.optionDBF0 === true ? getId('optionDBF0').checked='checked' : getId('optionDBF0').checked='false');
        (settings.optionDBF1 === true ? getId('optionDBF1').checked='checked' : getId('optionDBF1').checked='false');
        (settings.optionDBF2 === true ? getId('optionDBF2').checked='checked' : getId('optionDBF2').checked='false');
        (settings.optionDBF3 === true ? getId('optionDBF3').checked='checked' : getId('optionDBF3').checked='false');
        (settings.optionDBF4 === true ? getId('optionDBF4').checked='checked' : getId('optionDBF4').checked='false');
        (settings.optionDBF5 === true ? getId('optionDBF5').checked='checked' : getId('optionDBF5').checked='false');
        (settings.optionDBF6 === true ? getId('optionDBF6').checked='checked' : getId('optionDBF6').checked='false');
        (settings.optionDBF7 === true ? getId('optionDBF7').checked='checked' : getId('optionDBF7').checked='false');
        (settings.optionDBF8 === true ? getId('optionDBF8').checked='checked' : getId('optionDBF8').checked='false');
        (settings.optionDBF9 === true ? getId('optionDBF9').checked='checked' : getId('optionDBF9').checked='false');

        getId('optionDBF0').addEventListener('click', function(e) {
            var a=JSON.parse(localStorage.DBFsettings);
            (getId('optionDBF0').checked ? a.optionDBF0=true : a.optionDBF0=false)
            localStorage.setItem('DBFsettings', JSON.stringify(a));
            load_ban();
        });
        getId('optionDBF1').addEventListener('click', function(e) {
            var a=JSON.parse(localStorage.DBFsettings);
            (getId('optionDBF1').checked ? a.optionDBF1=true : a.optionDBF1=false)
            localStorage.setItem('DBFsettings', JSON.stringify(a));
            load_ban();
        });
        getId('optionDBF2').addEventListener('click', function(e) {
            var a=JSON.parse(localStorage.DBFsettings);
            (getId('optionDBF2').checked ? a.optionDBF2=true : a.optionDBF2=false)
            localStorage.setItem('DBFsettings', JSON.stringify(a));
            load_ban();
        });
        getId('optionDBF3').addEventListener('click', function(e) {
            var a=JSON.parse(localStorage.DBFsettings);
            (getId('optionDBF3').checked ? a.optionDBF3=true : a.optionDBF3=false)
            localStorage.setItem('DBFsettings', JSON.stringify(a));
            load_ban();
        });
        getId('optionDBF4').addEventListener('click', function(e) {
            var a=JSON.parse(localStorage.DBFsettings);
            (getId('optionDBF4').checked ? a.optionDBF4=true : a.optionDBF4=false)
            localStorage.setItem('DBFsettings', JSON.stringify(a));
            load_ban();
        });
        getId('optionDBF5').addEventListener('click', function(e) {
            var a=JSON.parse(localStorage.DBFsettings);
            (getId('optionDBF5').checked ? a.optionDBF5=true : a.optionDBF5=false)
            localStorage.setItem('DBFsettings', JSON.stringify(a));
            load_ban();
        });
        getId('optionDBF6').addEventListener('click', function(e) {
            var a=JSON.parse(localStorage.DBFsettings);
            (getId('optionDBF6').checked ? a.optionDBF6=true : a.optionDBF6=false)
            localStorage.setItem('DBFsettings', JSON.stringify(a));
            load_ban();
        });
        getId('optionDBF7').addEventListener('click', function(e) {
            var a=JSON.parse(localStorage.DBFsettings);
            if (getId('optionDBF7').checked) { a.optionDBF7=true; a.optionDBF8=false; getId('optionDBF8').checked="false"; } else { a.optionDBF7=false; }
            localStorage.setItem('DBFsettings', JSON.stringify(a));
            load_ban();
        });
        getId('optionDBF8').addEventListener('click', function(e) {
            var a=JSON.parse(localStorage.DBFsettings);
            if (getId('optionDBF8').checked) { a.optionDBF8=true; a.optionDBF7=false; getId('optionDBF7').checked="false"; } else { a.optionDBF8=false; }
            localStorage.setItem('DBFsettings', JSON.stringify(a));
            load_ban();
        });
        getId('optionDBF9').addEventListener('click', function(e) {
            var a=JSON.parse(localStorage.DBFsettings);
            (getId('optionDBF9').checked ? a.optionDBF9=true : a.optionDBF9=false)
            localStorage.setItem('DBFsettings', JSON.stringify(a));
            load_ban();
        });
        getId('layerBanVisib').addEventListener('click', function(e) {
            getId('layer-switcher-item_infos_ban_').click();
            if (Ban_Layer.visibility === true) { getId('layerBanVisib').style.backgroundColor='#bbffcc'; }
            else { getId('layerBanVisib').style.backgroundColor='#fac3c3'; }
            load_ban();
        });
        getId('layerHNVisib').addEventListener('click', function(e) {
            getId('layer-switcher-item_house_numbers').click();
            if ($('#layer-switcher-item_house_numbers').prop('checked') === true) { getId('layerHNVisib').style.backgroundColor='#bbffcc'; }
            else { getId('layerHNVisib').style.backgroundColor='#fac3c3'; }
            load_ban();
        });
        getId('zoomBanValue').addEventListener('click', function(e) {
            W.map.getOLMap().zoomTo("19");
            if (W.map.getZoom() < 19) { getId('zoomBanValue').style.backgroundColor='#fac3c3'; }
            else { getId('zoomBanValue').style.backgroundColor='#bbffcc'; }
            load_ban();
        });
        getId('DBFselectRoad').addEventListener('change', function(e) { load_ban(); });

        getId('zoomBanValue').innerHTML="Zoom: " + W.map.getZoom();
        if (W.map.getZoom() < 19) { getId('zoomBanValue').style.backgroundColor='#fac3c3'; }
        else { getId('zoomBanValue').style.backgroundColor='#bbffcc'; }

        getId('zoomMiscValue').innerHTML="Zoom: " + W.map.getZoom();
        if (W.map.getZoom() < 13) { getId('zoomMiscValue').style.backgroundColor='#fac3c3'; }
        else { getId('zoomMiscValue').style.backgroundColor='#bbffcc'; }

        if (Ban_Layer.visibility === true) { getId('layerBanVisib').style.backgroundColor='#bbffcc'; }
        else { getId('layerBanVisib').style.backgroundColor='#fac3c3'; }

        if ($('#layer-switcher-item_house_numbers').prop('checked') === true) { getId('layerHNVisib').style.backgroundColor='#bbffcc'; }
        else { getId('layerHNVisib').style.backgroundColor='#fac3c3'; }
    }

    function LayerVilToggled(checked) { Cty_Layer.setVisibility(checked); }
    function LayerDepToggled(checked) { Dpt_Layer.setVisibility(checked); }
    function LayerPRToggled(checked) { PR_Layer.setVisibility(checked); }
    function LayerCamToggled(checked) { Cam_Layer.setVisibility(checked); }
    function LayerBanToggled(checked) { Ban_Layer.setVisibility(checked); }
    function LayerEquipToggled(checked) { Equip_Layer.setVisibility(checked); }
    function LayerEtablToggled(checked) { Etabl_Layer.setVisibility(checked); }

    function show_border() {

        getId('zoomMiscValue').innerHTML="Zoom: " + W.map.getZoom();
        if (W.map.getZoom() < 13) { getId('zoomMiscValue').style.backgroundColor='#fac3c3'; return; }
        else { getId('zoomMiscValue').style.backgroundColor='#bbffcc'; }

        var Cty_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_Cty"; });
        var Dpt_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_Dpt"; });
        var PR_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_PR"; });
        var Cam_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_Cam"; });
        var Equip_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_Equip"; });
        var Etabl_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_Etabl"; });

        //On récupère les infos de la carte et vérification de la présence de toutes les données nécessaires
        let lonlat = new OpenLayers.LonLat(W.map.getProjectedCenter().lon, W.map.getProjectedCenter().lat);
        lonlat.transform(W.Config.map.projection.local, W.Config.map.projection.remote);
        let pt = new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat);
        var clat = pt.y;
        var clon = pt.x;
        var zoomLevel = W.map.getZoom();
        if (!clat || !clon || !zoomLevel) {
            console.error("Latitude, longitude ou zoomLevel manquant dans l'URL");
            return;
        }

        //Cty_Layer.visibility - Limites villes
        if (Cty_Layer.visibility === true) {
            if (W.model.cities.objects.length === 0) return;

            // collect list if unique cities from the segments
            var Cities = [], temp_city = "";
            for (var cid in W.model.cities.objects) {
                var city = W.model.cities.getObjectById(cid).attributes.name;
                var state = W.model.states.getObjectById(W.model.cities.getObjectById(cid).attributes.stateID).attributes.name;
                if (city && state) {
                    city = city.toLowerCase(); state = state.toLowerCase();
                    city = city.replace(/[èéêë]/g, "e").replace(/ç/g, 'c').replace(/[àâ]/g, 'a').replace(/[îï]/g, 'i').replace(/[ôö]/g, 'o').replace(/œ/g, 'oe').replace(/\'/g, '_');
                    state = state.replace(/[èé]/g, "e").replace(/ô/g, 'o').replace(/\'/g, '_');
                    if (city.indexOf("(") != "-1") { city = city.substring(city.indexOf(" ("), city.substr(city.length - 1)); } // Commune de...
                    if (city) {
                        Cities.push({ name: city, state: state });
                        if (debug) { console.log(city, state); temp_city = temp_city + city + ", "; }
                    }
                }
            }
            if (debug) { console.log("Villes demandées : ", temp_city); }
            //Get Data
            try {
                if (JSON.stringify(CitiesOld) != JSON.stringify(Cities)) {
                    getId('loadMiscData').style.backgroundColor = '#bbffcc';
                    if (debug) { console.log("XHR SEND ",Cities); }
                    var datas = JSON.stringify(Cities);

                    GM_xmlhttpRequest({
                        method: 'POST',
                        headers:{ "Content-Type": "application/JSON" },
                        url: 'https://api.wazefrance.com/communes',
                        data: datas,
                        onload: function(response) {
                            if (response.status == '200') {
                                var data = JSON.parse(response.responseText);
                                var temp_city = "", c = 0;
                                if (data.length > 0) {
                                    for (var i = 0; i < data.length; i++) {
                                        Cty_Borders_DrawBorder(data[i].name, data[i].coord); c++;
                                        if (debug) { temp_city = temp_city + data[i].name + ", "; }
                                    }
                                }
                                if (debug) { console.log("WME Draw Borders France: " + c + " villes reçues ", temp_city); }
                                getId('loadMiscData').style.backgroundColor = '#ffffff';
                            } else {
                                getId('loadMiscData').style.backgroundColor = '#fac3c3';
                            }
                        },
                        onerror: function(error) {
                            console.error("Erreur réseau :", error);
                        }
                    });

                    CitiesOld = Cities;
                } else {
                    if (debug) { console.log("WME Draw Borders France: Pas de nouvelles Villes détectées"); }
                }
            } catch (ex) { console.error(`${SCRIPT_NAME}:`, ex); }
        }

        //Dpt_Layer.visibility - Limites départements
        if (Dpt_Layer.visibility === true) {
            if (W.model.states.objects.length === 0) return;

            // Collect list if unique states from the segments
            var States = [], temp_state = "";
            for (var sid in W.model.states.objects) {
                var state = W.model.states.getObjectById(sid).attributes;
                if (state.countryID == "73") {
                    state = state.name.replace(/[èé]/g, "e").replace(/[ô]/g, 'o').replace(/\'/g, '_').replace(/ /g, '_');
                    States.push({ name: state });
                    if (debug) { temp_state = temp_state + state + ", "; }
                }
            }
            if (debug) { console.log("Départements demandés : ", temp_state); }

            // Get Data
            try {
                if (JSON.stringify(StatesOld) != JSON.stringify(States)) {
                    getId('loadMiscData').style.backgroundColor = '#bbffcc';
                    if (debug) { console.log("XHR SEND ",States); }
                    var datas = JSON.stringify(States);

                    GM_xmlhttpRequest({
                        method: 'POST',
                        headers:{ "Content-Type": "application/JSON" },
                        url: 'https://api.wazefrance.com/dep',
                        data: datas,
                        onload: function(response) {
                            if (response.status == '200') {
                                var data = JSON.parse(response.responseText);
                                var temp_city = "", c = 0;
                                if (data.length > 0) {
                                    for (var i = 0; i < data.length; i++) {
                                        Dpt_Borders_DrawBorder(data[i].name, data[i].coord); c++;
                                        if (debug) { temp_state = temp_state + data[i].name + ", "; }
                                    }
                                }
                                if (debug) { console.log("WME Draw Borders France: " + c + " départements reçus ", temp_state); }
                                getId('loadMiscData').style.backgroundColor = '#ffffff';
                            } else {
                                getId('loadMiscData').style.backgroundColor = '#fac3c3';
                            }
                        },
                        onerror: function(error) {
                            console.error("Erreur réseau :", error);
                        }
                    });

                    StatesOld = States;
                } else {
                    if (debug) { console.log("WME Draw Borders France: Pas de nouveaux Départements détectés"); }
                }
            } catch (ex) { console.error(`${SCRIPT_NAME}:`, ex); }
        }

        //PR_Layer.visibility - Points routiers
        if (PR_Layer.visibility === true) {
            //Get Data
            try {
                getId('loadMiscData').style.backgroundColor='#bbffcc';
                var ret = GM_xmlhttpRequest({
                    method: 'GET',
                    url: 'https://api.wazefrance.com/pr?lat=' + clat + '&lon=' + clon + '&zoom=' + zoomLevel,
                    onload: function(response) {
                        if (response.status == '200') {
                            var r = JSON.parse(response.responseText), r=r.pr;
                            if (r.length > 0) {
                                for (var i = 0; r[i]; i++) {
                                    PR_Borders_DrawBorder(r[i].numero, r[i].longitude, r[i].latitude);
                                }
                            }
                            if (debug) { console.log("WME Draw Borders France: Points Routiers chargés", JSON.parse(response.responseText)); }
                            getId('loadMiscData').style.backgroundColor='#ffffff';
                        } else {
                            getId('loadMiscData').style.backgroundColor='#fac3c3';
                        }
                    },
                    onerror: function(error) {
                        console.error("Erreur réseau :", error);
                    }
                });
            } catch (ex) { console.error(`${SCRIPT_NAME}:`, ex); }
        }

        //Equip_Layer.visibility - Rond-Poin, Parking
        if (Equip_Layer.visibility === true) {
            //Get Data
            try {
                getId('loadMiscData').style.backgroundColor='#bbffcc';

                GM_xmlhttpRequest({
                    method: 'GET',
                    url: 'https://api.wazefrance.com/equipement_data?lat=' + clat + '&lon=' + clon + '&zoom=' + zoomLevel,
                    onload: function(response) {
                        if (response.status == '200') {
                            var r = JSON.parse(response.responseText), r=r.equipements;
                            if (debug) { console.log("WME Draw Borders France: Equipements chargés", JSON.parse(response.responseText)); }
                            if (r.length > 0) {
                                for (var i = 0; r[i]; i++) {
                                    Equip_Borders_DrawBorder("("+r[i].nature + ")\n" + r[i].toponyme, r[i].lon, r[i].lat);
                                }
                            }
                            getId('loadMiscData').style.backgroundColor='#ffffff';
                        } else {
                            getId('loadMiscData').style.backgroundColor='#fac3c3';
                        }
                    },
                    onerror: function(error) {
                        console.error("Erreur réseau :", error);
                    }
                });
            } catch (ex) { console.error(`${SCRIPT_NAME}:`, ex); }
        }

        //Etabl_Layer.visibility - Etablissement, Ecole
        if (Etabl_Layer.visibility === true) {
            //Get Data
            try {
                getId('loadMiscData').style.backgroundColor='#bbffcc';
                GM_xmlhttpRequest({
                    method: 'GET',
                    url: 'https://api.wazefrance.com/combined_data?lat=' + clat + '&lon=' + clon + '&zoom=' + zoomLevel,
                    onload: function(response) {
                        if (response.status == '200') {
                            var r = JSON.parse(response.responseText), r=r.établissements;
                            if (debug) { console.log("WME Draw Borders France: Etablissements chargés", JSON.parse(response.responseText)); }
                            if (r.length > 0) {
                                for (var i = 0; r[i]; i++) {
                                    Etabl_Borders_DrawBorder(r[i].appellation_officielle + "\n(" + r[i].adresse_uai+")", r[i].longitude, r[i].latitude);
                                }
                            }
                            getId('loadMiscData').style.backgroundColor='#ffffff';
                        } else {
                            getId('loadMiscData').style.backgroundColor='#fac3c3';
                        }
                    },
                    onerror: function(error) {
                        console.error("Erreur réseau :", error);
                    }
                });
            } catch (ex) { console.error(`${SCRIPT_NAME}:`, ex); }
        }

        //Cam_Layer.visibility
        if (Cam_Layer.visibility === true) {
            var listCam = localStorage.speedCamList;
            if (listCam) {
                var a = JSON.parse(listCam);
                if (debug) { console.log(a); }
                for (var i = 0; i < a.length; i++) { Cam_Borders_DrawBorder(a[i].typeLabel, a[i].lng, a[i].lat); }
            }
        }
    }
    function load_radar() {

        getId('zoomMiscValue').innerHTML="Zoom: " + W.map.getZoom();
        if (W.map.getZoom() < 13) { getId('zoomMiscValue').style.backgroundColor='#fac3c3'; return; }
        else { getId('zoomMiscValue').style.backgroundColor='#bbffcc'; }

        var listCam = localStorage.speedCamList;
        //Get Data
        getId('loadMiscData').style.backgroundColor='#bbffcc';
        try {
            var ret = GM_xmlhttpRequest({
                method: 'GET',
                url: 'https://radars.securite-routiere.gouv.fr/radars/all?_format=json',
                onload: function(response) {
                    if (response.status == '200') {
                        if (_.isEqual(JSON.parse(listCam), JSON.parse(response.responseText)) !== true && response.responseText) {
                            console.log("WME Draw Borders France: Mise à jour de la liste des radars");
                            localStorage.setItem('speedCamList', response.responseText);
                        }
                        getId('loadMiscData').style.backgroundColor='#ffffff';
                    } else {
                        getId('loadMiscData').style.backgroundColor='#fac3c3';
                    }
                },
                onerror: function(error) {
                    console.error("Erreur réseau :", error);
                }
            });
        } catch (ex) { console.error(`${SCRIPT_NAME}:`, ex); }
    }
    function load_ban() {

        var Ban_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_Ban"; });
        if (Ban_Layer.visibility === true) { getId('layerBanVisib').style.backgroundColor='#bbffcc'; }
        else { getId('layerBanVisib').style.backgroundColor='#fac3c3'; }

        if ($('#layer-switcher-item_house_numbers').prop('checked') === true) { getId('layerHNVisib').style.backgroundColor='#bbffcc'; }
        else { getId('layerHNVisib').style.backgroundColor='#fac3c3'; }

        getId('zoomBanValue').innerHTML="Zoom: " + W.map.getZoom();
        if (W.map.getZoom() < 19) { getId('zoomBanValue').style.backgroundColor='#fac3c3'; return; }
        else { getId('zoomBanValue').style.backgroundColor='#bbffcc'; }

        if (Ban_Layer.visibility === true) {
            if (getId('optionDBF4').checked) { Ban_Layer.destroyFeatures(); checklayer("__WME_Draw_Border_Ban"); }
            else { Ban_Layer.redraw(); }

            //try {
            getId('loadBanData').style.backgroundColor='#bbffcc';
            //Liste les noms de rue à l'écran
            var streetList = [];
            for (var i in W.model.streets.objects) {
                var streetName = W.model.streets.objects[i].attributes.name
                if (streetName != "") {
                    if (streetList.indexOf(streetName) == - 1) {
                        streetList.push(streetName);
                    }
                }
            }
            streetList.sort();

            //Création du menu déroulant après l'avoir vidé (actualisation), mis l'option par défaut et, éventuellement, la rue sélectionnée
            var tmp=getId('DBFselectRoad').value;
            getId('DBFselectRoad').innerHTML = "";
            getId('selectedRoad').innerHTML = "";
            var cList = document.createElement('wz-option');
            cList.value = "";
            cList.innerHTML = "---";
            getId('DBFselectRoad').appendChild(cList);
            if (tmp != "") {
                cList = document.createElement('wz-option');
                cList.value = tmp;
                cList.innerHTML = tmp;
                getId('DBFselectRoad').appendChild(cList);
            }

            //On complète avec les autres rues
            for (var k = 0; streetList[k]; k++) {
                if (tmp != streetList[k]) {
                    cList = document.createElement('wz-option');
                    cList.value = streetList[k];
                    cList.innerHTML = streetList[k];
                    getId('DBFselectRoad').appendChild(cList);
                }
            }

            //Segment sélectionné à l'écran
            if (typeof W.selectionManager.getSelectedWMEFeatures()[0] == 'object' && W.selectionManager.getSelectedWMEFeatures()[0].featureType == 'segment') {
                getId('selectedRoad').innerHTML = W.model.streets.objects[W.model.segments.objects[W.selectionManager.getSelectedWMEFeatures()[0].id].attributes.primaryStreetID].attributes.name;
            } else {
                getId('selectedRoad').innerHTML="";
            }

            //Liste des n° de rue déjà existants sur la carte
            var HNdone = [];
            for (var i in W.model.segmentHouseNumbers.objects) {
                if (typeof W.model.segmentHouseNumbers.objects[i].attributes.segID != "null"
                    && typeof W.model.segments.objects[W.model.segmentHouseNumbers.objects[i].attributes.segID] != "undefined") {

                    // Mise en mémoire des noms de rue et ville
                    let segId = W.model.segmentHouseNumbers.objects[i].attributes.segID;
                    let streetName = W.model.streets.objects[W.model.segments.objects[segId].attributes.primaryStreetID].attributes.name;
                    streetName = streetName.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase();
                    let cityName = W.model.cities.objects[W.model.streets.objects[W.model.segments.objects[segId].attributes.primaryStreetID].attributes.cityID].attributes.name
                    cityName = cityName.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase();
                    if(cityName.indexOf("(") > 0) { cityName = cityName.substring(cityName.indexOf("(")+1).replace(")",""); } // On garde le nom de la commune principale si sous-commune
                    HNdone.push(W.model.segmentHouseNumbers.objects[i].attributes.number + " " + streetName + " " + cityName);

                    // Mise en mémoire des noms de rue et ville alt
                    if (typeof W.model.segments.objects[segId].attributes.streetIDs[0] != "undefined") {
                        for (var j = 0; j < W.model.segments.objects[segId].attributes.streetIDs.length; j++) {
                            let streetAltName = W.model.streets.objects[W.model.segments.objects[segId].attributes.streetIDs[j]].attributes.name;
                            streetAltName = streetAltName.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase();
                            let cityName = W.model.cities.objects[W.model.streets.objects[W.model.segments.objects[segId].attributes.streetIDs[j]].attributes.cityID].attributes.name
                            cityName = cityName.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase();
                            if(cityName.indexOf("(") > 0) { cityName = cityName.substring(cityName.indexOf("(")+1).replace(")",""); } // On garde le nom de la commune principale si sous-commune
                            HNdone.push(W.model.segmentHouseNumbers.objects[i].attributes.number + " " + streetAltName + " " + cityName);
                        }
                    }
                }
            }

            //Liste des POI résidentiels déjà existants sur la carte
            for (var i in W.model.venues.objects) {
                if (typeof W.model.venues.objects[i].attributes.residential != "null"
                    && typeof W.model.venues.objects[i].attributes.streetID != "undefined"
                    && typeof W.model.streets.objects[W.model.venues.objects[i].attributes.streetID] != "undefined") {
                    let streetName = W.model.streets.objects[W.model.venues.objects[i].attributes.streetID].attributes.name;
                    streetName = streetName.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase();
                    let cityName = W.model.cities.objects[W.model.streets.objects[W.model.venues.objects[i].attributes.streetID].attributes.cityID].attributes.name
                    cityName = cityName.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase();
                    if(cityName.indexOf("(") > 0) { cityName = cityName.substring(cityName.indexOf("(")+1).replace(")",""); } // On garde le nom de la commune principale si sous-commune
                    HNdone.push(W.model.venues.objects[i].attributes.houseNumber + " " + streetName + " " + cityName);
                }
            }

            //On récupère les infos de la carte et vérification de la présence de toutes les données nécessaires
            let lonlat = new OpenLayers.LonLat(W.map.getProjectedCenter().lon, W.map.getProjectedCenter().lat);
            lonlat.transform(W.Config.map.projection.local, W.Config.map.projection.remote);
            let pt = new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat);
            var clat = pt.y;
            var clon = pt.x;
            var zoomLevel = W.map.getZoom();
            if (!clat || !clon || !zoomLevel) {
                console.error("Latitude, longitude ou zoomLevel manquant dans l'URL");
                return;
            }

            // Requête à l'API Flask
            try {
                var ret = GM_xmlhttpRequest({
                    method: 'GET',
                    url: 'https://api.wazefrance.com/combined_data?lat=' + clat + '&lon=' + clon + '&zoom=' + zoomLevel,
                    onload: function(response) {
                        if (response.status == '200') {

                            const correction = {
                                "mal ": "maréchal ",
                                "av ": "avenue ",
                                "oe": "œ", "œ": "oe",
                                "ae": "æ", "æ": "ae",
                                //" jean ": "jean-",
                                //" marie ": "marie-",
                                " st ": " saint-",
                                " saint ": " saint-",
                                "zone artisanale ": "z.a. "
                            };

                            var adresses = JSON.parse(response.responseText);

                            //Numéros de rue
                            if (debug) { console.log("N° BAN",adresses.info_ban); }

                            var a = adresses.info_ban;
                            getId('banQty').innerHTML=a.length;
                            (a.length > 199 ? getId('banQty').style.color="red" : getId('banQty').style.color="black")

                            for (var i = 0; i < a.length; i++) {
                                var adresse = a[i], nomRueCorr;
                                var nomRueBan = adresse.numero + (adresse.rep != null ? adresse.rep : "") + " " + adresse.nom_voie;
                                var nomCommuneBAN = adresse.nom_commune;

                                nomRueCorr=nomRueBan.toLowerCase();
                                Object.keys(correction).forEach((key) => {
                                    nomRueCorr = nomRueCorr.replaceAll(key, correction[key]);
                                    nomCommuneBAN = nomCommuneBAN.replaceAll(key, correction[key]);
                                });

                                nomRueCorr = nomRueCorr.normalize('NFD').replace(/\p{Diacritic}/gu, '').replace("’", "'");
                                var nomCommuneCorr=nomCommuneBAN.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase();

                                if (getId('optionDBF9').checked == true) {
                                    if (nomRueCorr.search(" - ") != "-1") { nomRueCorr = nomRueCorr.substring(0, nomRueCorr.search(" - ")); }
                                }

                                // Appel à Ban_Borders_DrawBorder avec le format attendu après avoir testé si le n° existe déjà sur WME
                                var state, Ville=nomCommuneBAN;
                                ((HNdone.indexOf(nomRueCorr +" "+nomCommuneCorr) == "-1") ? state = 'no' : state = 'yes')

                                if (getId('optionDBF0').checked == true && state == 'yes') { continue; } // On bloque l'affichage des n° renseignés sur WME
                                if (getId('optionDBF1').checked == true && adresse.certification_commune == 0) { continue; } // On bloque l'affichage des n° non certifiés
                                if (getId('optionDBF2').checked == true && adresse.nom_ancienne_commune != null) { Ville = "\n" + adresse.nom_ancienne_commune + ' (' + nomCommuneBAN + ')'; } // On affiche l'ancien nom de commune
                                if (getId('optionDBF3').checked == true && adresse.date_ajout_modif != null) { Ville = Ville + '\n' + deltaDate(adresse.date_ajout_modif); } // On affiche l'age de l'info
                                if (getId('optionDBF5').checked == true && (getId('selectedRoad').innerHTML != ""  || getId('DBFselectRoad').value != "")) {
                                    if (getId('selectedRoad').innerHTML != "") { var selectedRoad = getId('selectedRoad').innerHTML; } // Rue sélectionnée
                                    else if (getId('DBFselectRoad').value != "") { var selectedRoad = getId('DBFselectRoad').value; } // Sinon rue dans le menu déroulant
                                    var adres = adresse.nom_voie;
                                    adres  = adres.normalize('NFD').replace(/\p{Diacritic}/gu, '').replace("’", "'").toLowerCase();
                                    var selectRoad = selectedRoad.normalize('NFD').replace(/\p{Diacritic}/gu, '').replace("’", "'").toLowerCase();
                                    if (selectRoad != adres) { continue; } // On bloque si ce n'est pas la rue sélectionnée
                                }
                                if (getId('optionDBF7').checked == false) {
                                    if (getId('optionDBF8').checked == true) { Ban_Borders_DrawBorder(adresse.numero, adresse.lon, adresse.lat, state, adresse.certification_commune); }
                                    else {
                                        if (getId('optionDBF6').checked == true) { Ban_Borders_DrawBorder(nomRueBan, adresse.lon, adresse.lat, state, adresse.certification_commune); }
                                        else { Ban_Borders_DrawBorder(nomRueBan + "\n" + Ville, adresse.lon, adresse.lat, state, adresse.certification_commune); }
                                    }
                                }
                            }

                            //Lieux-dits
                            if (debug) { console.log("Lieux-dits",adresses.lieux_dits); }
                            var b = adresses.lieux_dits;
                            for (var i = 0; i < b.length; i++) {
                                var lieux = b[i], lieudit2;
                                var lieudit = lieux.nom_lieu_dit;

                                Object.keys(correction).forEach((key) => {
                                    lieudit = lieudit.replaceAll(key, correction[key]);
                                });

                                lieudit2 = lieudit.normalize('NFD').replace(/\p{Diacritic}/gu, '').replace("’", "'").toLowerCase();
                                if (getId('optionDBF6').checked == true) { var Ville = ""; } else { var Ville="\n" + nomCommune; }

                                // Appel à Ban_Borders_DrawBorder avec le format attendu après avoir testé si le n° existe déjà sur WME
                                var state;
                                ((HNdone.indexOf(lieudit2) == "-1") ? state = 'no' : state = 'yes')

                                if (getId('optionDBF0').checked == true && state == 'yes') { continue; } // On bloque l'affichage des lieux-dits renseignés sur WME
                                if (getId('optionDBF8').checked == false) { Ban_Borders_DrawBorder(lieudit + Ville, lieux.lon, lieux.lat,"",""); }
                            }
                            getId('loadBanData').style.backgroundColor='#ffffff';
                        } else {
                            getId('loadBanData').style.backgroundColor='#fac3c3';
                        }
                    },
                    onerror: function(error) { console.error("Erreur réseau :", error); }
                });
            } catch (ex) { console.error(`${SCRIPT_NAME}:`, ex); }
        }
    }

    function checklayer(layer) {
        var layers = W.map.getLayersBy("uniqueName", layer);
        if (layers.length === 0) {
            var DBF_style = new OpenLayers.Style({
                pointRadius: 2,
                fontWeight: "normal",
                label: "${labelText}",
                fontFamily: "Tahoma, Courier New",
                labelOutlineColor: "#FFFFFF",
                labelOutlineWidth: 2,
                fontColor: '#000000',
                fontSize: "10px"
            });
            if (layer == "__WME_Draw_Border_Cty") {
                Cty_Layer = new OpenLayers.Layer.Vector("Limites Villes", {
                    displayInLayerSwitcher: true,
                    uniqueName: layer,
                    styleMap: new OpenLayers.StyleMap(DBF_style)
                });
                Cty_Layer.setVisibility(false);
                W.map.addLayer(Cty_Layer);
                I18n.translations[I18n.locale].layers.name[layer] = "Villes";
            }
            if (layer == "__WME_Draw_Border_Dpt") {
                Dpt_Layer = new OpenLayers.Layer.Vector("Limites Departements", {
                    displayInLayerSwitcher: true,
                    uniqueName: layer,
                    styleMap: new OpenLayers.StyleMap(DBF_style)
                });
                Dpt_Layer.setVisibility(false);
                W.map.addLayer(Dpt_Layer);
                I18n.translations[I18n.locale].layers.name[layer] = "Departements";
            }
            if (layer == "__WME_Draw_Border_PR") {
                PR_Layer = new OpenLayers.Layer.Vector("Points Routiers", {
                    displayInLayerSwitcher: true,
                    uniqueName: layer,
                    styleMap: new OpenLayers.StyleMap(DBF_style)
                });
                PR_Layer.setVisibility(false);
                W.map.addLayer(PR_Layer);
                I18n.translations[I18n.locale].layers.name[layer] = "PR";
            }
            if (layer == "__WME_Draw_Border_Cam") {
                Cam_Layer = new OpenLayers.Layer.Vector("Radars", {
                    displayInLayerSwitcher: true,
                    uniqueName: layer,
                    styleMap: new OpenLayers.StyleMap(DBF_style)
                });
                Cam_Layer.setVisibility(false);
                W.map.addLayer(Cam_Layer);
                I18n.translations[I18n.locale].layers.name[layer] = "Radars";
            }
            if (layer == "__WME_Draw_Border_Ban") {
                Ban_Layer = new OpenLayers.Layer.Vector("Infos BAN", {
                    displayInLayerSwitcher: true,
                    uniqueName: layer,
                    styleMap: new OpenLayers.StyleMap(DBF_style)
                });
                Ban_Layer.setVisibility(false);
                W.map.addLayer(Ban_Layer);
                I18n.translations[I18n.locale].layers.name[layer] = "BAN";
            }
            if (layer == "__WME_Draw_Border_Equip") {
                Equip_Layer = new OpenLayers.Layer.Vector("Equipements", {
                    displayInLayerSwitcher: true,
                    uniqueName: layer,
                    styleMap: new OpenLayers.StyleMap(DBF_style)
                });
                Equip_Layer.setVisibility(false);
                W.map.addLayer(Equip_Layer);
                I18n.translations[I18n.locale].layers.name[layer] = "Equipements";
            }
            if (layer == "__WME_Draw_Border_Etabl") {
                Etabl_Layer = new OpenLayers.Layer.Vector("Etablissements", {
                    displayInLayerSwitcher: true,
                    uniqueName: layer,
                    styleMap: new OpenLayers.StyleMap(DBF_style)
                });
                Etabl_Layer.setVisibility(false);
                W.map.addLayer(Etabl_Layer);
                I18n.translations[I18n.locale].layers.name[layer] = "Etablissements";
            }
        }
    }
    function Cty_Borders_DrawBorder(Name, coordinateString) {
        var poly = new OpenLayers.Feature.Vector(Geometrize(Name, coordinateString), null, new Cty_Borders_Style(Name));
        var Cty_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_Cty"; });
        Cty_Layer.addFeatures(poly);
    }
    function Dpt_Borders_DrawBorder(Name, coordinateString) {
        var poly = new OpenLayers.Feature.Vector(Geometrize(Name, coordinateString), null, new Dpt_Borders_Style(Name));
        var Dpt_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_Dpt"; });
        Dpt_Layer.addFeatures(poly);
    }
    function PR_Borders_DrawBorder(Name, lon, lat) {
        var poly = new OpenLayers.Feature.Vector(Geometrize(Name, lon + ";" + lat), null, new PR_Borders_Style(Name));
        var PR_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_PR"; });
        PR_Layer.addFeatures(poly);
    }
    function Cam_Borders_DrawBorder(Name, lon, lat) {
        var poly = new OpenLayers.Feature.Vector(Geometrize(Name, lon + ";" + lat), null, new Cam_Borders_Style(Name));
        var Cam_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_Cam"; });
        Cam_Layer.addFeatures(poly);
    }
    function Ban_Borders_DrawBorder(Name, lon, lat, status, verif) {
        var cStat1, cStat2, cVerif;
        if (status == "yes") { cStat1 = "#99ffff"; cStat2 = "#002222"; }
        else { cStat1 = "#ff0000"; cStat2 = "#ffff00"; }
        (verif == "1" ? cVerif = "#00dd00" : cVerif = "#ff8000")
        var poly = new OpenLayers.Feature.Vector(Geometrize(Name, lon + ";" + lat), null, new Ban_Borders_Style(Name, cStat1, cStat2, cVerif));
        var Ban_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_Ban"; });
        Ban_Layer.addFeatures(poly);
    }
    function Equip_Borders_DrawBorder(Name, lon, lat) {
        var poly = new OpenLayers.Feature.Vector(Geometrize(Name, lon + ";" + lat), null, new Equip_Borders_Style(Name));
        var Equip_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_Equip"; });
        Equip_Layer.addFeatures(poly);
    }
    function Etabl_Borders_DrawBorder(Name, lon, lat) {
        var poly = new OpenLayers.Feature.Vector(Geometrize(Name, lon + ";" + lat), null, new Etabl_Borders_Style(Name));
        var Etabl_Layer = W.map.layers.find(function (l) { return l.uniqueName == "__WME_Draw_Border_Etabl"; });
        Etabl_Layer.addFeatures(poly);
    }
    function Cty_Borders_Style(Name) {
        this.fill = false;
        this.stroke = true;
        this.strokeColor = "#ce00ce";
        this.strokeWidth = 2;
        this.strokeDashstyle = "solid";
    }
    function Dpt_Borders_Style(Name) {
        this.fill = false;
        this.stroke = true;
        this.strokeColor = "#b20000";
        this.strokeWidth = 5;
        this.strokeDashstyle = "solid";
        this.label = Name.replace(/_/g, "'");
        this.fontSize = 24;
        this.fontColor = "#b20000";
        this.fontWeight = "bold";
    }
    function PR_Borders_Style(Name) {
        this.fill = false;
        this.stroke = true;
        this.strokeColor = "#3380ff";
        this.strokeWidth = 10;
        this.strokeDashstyle = "solid";
        this.label = "PR" + Name;
        this.labelYOffset = 10;
        this.fontSize = 12;
        this.fontColor = "#33ffee";
        this.labelOutlineColor = "#3380ff";
        this.labelOutlineWidth = 3;
    }
    function Cam_Borders_Style(Name) {
        this.stroke = true;
        this.strokeColor = "#ff0000";
        this.strokeWidth = 10;
        this.strokeDashstyle = "solid";
        this.label = Name;
        this.labelYOffset = 13;
        this.fontSize = 12;
        this.fontColor = "#ffff00";
        this.labelOutlineColor = "#ff0000";
        this.labelOutlineWidth = 3;
    }
    function Ban_Borders_Style(Name, cStat1, cStat2, cVerif) {
        this.fill = false;
        this.stroke = true;
        this.strokeColor = cVerif;
        this.strokeWidth = 10;
        this.strokeDashstyle = "solid";
        this.label = Name;
        this.labelYOffset = 22;
        this.fontSize = 12;
        this.fontColor = cStat2;
        this.labelOutlineColor = cStat1;
        this.labelOutlineWidth = 4;
    }
    function Equip_Borders_Style(Name) {
        this.fill = false;
        this.stroke = true;
        this.strokeColor = "#2d792d";
        this.strokeWidth = 10;
        this.strokeDashstyle = "solid";
        this.label = Name;
        this.labelYOffset = 10;
        this.fontSize = 12;
        this.fontColor = "#33ff33";
        this.labelOutlineColor = "#2d792d";
        this.labelOutlineWidth = 3;
    }
    function Etabl_Borders_Style(Name) {
        this.fill = false;
        this.stroke = true;
        this.strokeColor = "#690069";
        this.strokeWidth = 10;
        this.strokeDashstyle = "solid";
        this.label = Name;
        this.labelYOffset = 10;
        this.fontSize = 12;
        this.fontColor = "#ff77ff";
        this.labelOutlineColor = "#690069";
        this.labelOutlineWidth = 3;
    }
    function Geometrize(Name, coordinateString) {
        var tempVector = coordinateString.split(" ");
        var polyPoints = new Array(tempVector.length);
        for (var i = 0; i < tempVector.length; i++) {
            var coordinateVector = tempVector[i].split(";");
            polyPoints[i] = new OpenLayers.Geometry.Point(coordinateVector[0], coordinateVector[1]).transform(new OpenLayers.Projection("EPSG:4326"), W.map.getProjectionObject());
        }
        var polygon = new OpenLayers.Geometry.Polygon(new OpenLayers.Geometry.LinearRing(polyPoints));
        return polygon;
    }
    DBFstep1();
})();