Leaflet contour commune avec API Gouv

a marqué ce sujet comme résolu.

Bonjour,

A partir de l’API du gouvernement je cherche à faire les contours d’une commune par exemple versailles. Je bloque ça ne marche pas…

Voici mon code :

function initMap() {
            // Créer l'objet "macarte" et l'insèrer dans l'élément HTML qui a l'ID "map"
            macarte = L.map('map').setView([lat, long], 11);
            // Leaflet ne récupère pas les cartes (tiles) sur un serveur par défaut. Nous devons lui préciser où nous souhaitons les récupérer. Ici, openstreetmap.fr
            L.tileLayer('https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', {
                // Il est toujours bien de laisser le lien vers la source des données
                attribution: 'données OpenStreetMap - rendu OSM France',
                minZoom: 1,
                maxZoom: 20
            }).addTo(macarte)
            function style() {
                return {
                    fillColor: rgb(0,176,80),
                    weight: 2,
                    opacity: 1,
                    color: 'white',
                    dashArray: '3',
                    fillOpacity: 0.7
                };
            }     
            var url = "https://geo.api.gouv.fr/communes/78646/?&fields=contour"
            ajaxGet(url, function (reponse) {
                var contour = JSON.parse(reponse);
                
                for (var i = 0 ; i < contour.length ; i++) {
                    contour[i].reverse();
                }
                L.geoJson(contour).addTo(macarte);
                L.geoJson(contour, {style: style}).addTo(macarte);
                
            })
        window.onload = function(){
            // Fonction d'initialisation qui s'exécute lorsque le DOM est chargé
            initMap(); 
        };
    </script>

Salut \o

Il manque pas mal de truc à ton code pour marcher. À commencer par la fonction ajaxGet et la structure HTML de base.

À la ligne 13:

                    fillColor: rgb(0,176,80),

Devrait être :

                    fillColor: 'rgb(0,176,80)',

Mais l’erreur principale est je pense que reponse est un objet JSON. Mais seul le champ contour est un GeoJSON utilisable comme tu le souhaites.

Ton ta ligne 23 devrait être :

                var {contour} = JSON.parse(reponse);

Ou encore :

                var contour = JSON.parse(reponse).contour;

Au final, j’obtiens ça : 2019-07-15-043944_1920x1080_scrot.png

Qui est plutôt raccord avec le résultat souhaité.

+0 -0

Pourrais-tu poster le code que tu as utilisé ?

S4ndStorm

Désolé mais non. Déjà car je ne l’ai plus. Ensuite parce-que toi non plus tu n’as pas donné tout ton code.

Par-contre si tu donnes tout ton code alors je t’indiquerais volontiers les problèmes.

+0 -0

Bien sûr,

<!DOCTYPE html>
<html>

<head>

<meta charset="utf-8">
    
<link rel="stylesheet" href="leaflet.css"/>

<title>MAP</title>

</head>

<body>

<div id="map" style="height:180px;" }>Hello !
</div>

<script src="MAP.js"></script>
<script src="leaflet.js"></script>
</body>

</html>
function initMap() {
            // Créer l'objet "macarte" et l'insèrer dans l'élément HTML qui a l'ID "map"
            macarte = L.map('map').setView([lat, long], 11);
            // Leaflet ne récupère pas les cartes (tiles) sur un serveur par défaut. Nous devons lui préciser où nous souhaitons les récupérer. Ici, openstreetmap.fr
            L.tileLayer('https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', {
                // Il est toujours bien de laisser le lien vers la source des données
                attribution: 'données OpenStreetMap - rendu OSM France',
                minZoom: 1,
                maxZoom: 20
            }).addTo(macarte)
            function style() {
                return {
                    fillColor: 'rgb(0,176,80)',
                    weight: 2,
                    opacity: 1,
                    color: 'white',
                    dashArray: '3',
                    fillOpacity: 0.7
                };
            }   
            var url = "https://geo.api.gouv.fr/communes/78646/?&fields=contour"
            ajaxGet(url, function (reponse) {
                var contour = JSON.parse(reponse).contour;
                
                for (var i = 0 ; i < contour.length ; i++) {
                    contour[i].reverse();
                }
                L.geoJson(contour).addTo(macarte);
                L.geoJson(contour, {style: style}).addTo(macarte);
                
            })
        window.onload = function(){
            // Fonction d'initialisation qui s'exécute lorsque le DOM est chargé
            initMap(); };}
+0 -0

Cool !

Alors, j’ai passé vite fait ton code dans mon éditeur de texte. Après indentation automatique il m’a pondu ça :

function initMap() {
  // Créer l'objet "macarte" et l'insèrer dans l'élément HTML qui a l'ID "map"
  macarte = L.map('map').setView([lat, long], 11);
  // Leaflet ne récupère pas les cartes (tiles) sur un serveur par défaut. Nous devons lui préciser où nous souhaitons les récupérer. Ici, openstreetmap.fr
  L.tileLayer('https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', {
    // Il est toujours bien de laisser le lien vers la source des données
    attribution: 'données OpenStreetMap - rendu OSM France',
    minZoom: 1,
    maxZoom: 20
  }).addTo(macarte)
  function style() {
    return {
      fillColor: 'rgb(0,176,80)',
      weight: 2,
      opacity: 1,
      color: 'white',
      dashArray: '3',
      fillOpacity: 0.7
    };
  }   
  var url = "https://geo.api.gouv.fr/communes/78646/?&fields=contour"
  ajaxGet(url, function (reponse) {
    var contour = JSON.parse(reponse).contour;

    for (var i = 0 ; i < contour.length ; i++) {
      contour[i].reverse();
    }
    L.geoJson(contour).addTo(macarte);
    L.geoJson(contour, {style: style}).addTo(macarte);

  })
  window.onload = function(){
    // Fonction d'initialisation qui s'exécute lorsque le DOM est chargé
    initMap(); };}

Ce qu’on remarque immédiatement c’est que window.onload est encore indenté !
Il ne devrait pas justement sinon ton code n’est jamais appelé.

Bon en plus, le code de window.onload est pas très beau. Tu as juste à faire window.onload = initMap. Mais peu importe.

Au niveau du HTML, ajout le JS en même temps que le CSS pour leaflet. Ton élément MAP est un peu bizarre. Spécifie correctement la taille.

J’ai fais :

    <div id="map" style="width:545px; height:490px"></div>

Tout simplement.

Ton code et correcte sinon. Encore une fois, j’avais pas le fonction ajaxGet donc plutôt que la recoder j’ai tapé sur internet vite fait et j’ai copié/collé la première implémentation.

Au final, j’ai ça :

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>MAP</title>
    <script src="https://cdn.jsdelivr.net/npm/leaflet@1.5.1/dist/leaflet.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.5.1/dist/leaflet.css" />
  </head>
  <body>
    <div id="map" style="width:545px; height:490px"></div>
    <script src="MAP.js"></script>
  </body>
</html>

Et pour le JS :

const lat = 48.80;
const long = 2.08; // Ajuste ça pour mieux centrer

// Exécute un appel AJAX GET
// Prend en paramètres l'URL cible et la fonction callback appelée en cas de succès
function ajaxGet(url, callback) {
    var req = new XMLHttpRequest();
    req.open("GET", url);
    req.addEventListener("load", function () {
        if (req.status >= 200 && req.status < 400) {
            // Appelle la fonction callback en lui passant la réponse de la requête
            callback(req.responseText);
        } else {
            console.error(req.status + " " + req.statusText + " " + url);
        }
    });
    req.addEventListener("error", function () {
        console.error("Erreur réseau avec l'URL " + url);
    });
    req.send(null);
}

function initMap() {
  // Créer l'objet "macarte" et l'insèrer dans l'élément HTML qui a l'ID "map"
  macarte = L.map('map').setView([lat, long], 11);
  // Leaflet ne récupère pas les cartes (tiles) sur un serveur par défaut. Nous devons lui préciser où nous souhaitons les récupérer. Ici, openstreetmap.fr
  L.tileLayer('https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', {
    // Il est toujours bien de laisser le lien vers la source des données
    attribution: 'données OpenStreetMap - rendu OSM France',
    minZoom: 1,
    maxZoom: 20
  }).addTo(macarte)
  function style() {
    return {
      fillColor: 'rgb(0,176,80)',
      weight: 2,
      opacity: 1,
      color: 'white',
      dashArray: '3',
      fillOpacity: 0.7
    };
  }   
  var url = "https://geo.api.gouv.fr/communes/78646/?&fields=contour"
  ajaxGet(url, function (reponse) {
    var contour = JSON.parse(reponse).contour;

    for (var i = 0 ; i < contour.length ; i++) {
      contour[i].reverse();
    }
    L.geoJson(contour).addTo(macarte);
    L.geoJson(contour, {style: style}).addTo(macarte);

  })
}
window.onload = initMap;

Et ça marche. Voilà.

2019-08-05-163405_1920x1080_scrot.png
2019-08-05-163405_1920x1080_scrot.png
+0 -0

Je te remercie pour ton aide, c’est ma première utilisation de leaflet, désolé si ça a semblé un peu léger :)

S4ndStorm

Pas de soucis. Pour tout t’avouer, c’est surtout ta maîtrise de Javascript qui semble un peu légère.

Malheureusement, le site ne propose pas encore de tutoriel pour Javascript. Si tu veux te former, il en existe chez developpez.com: https://javascript.developpez.com/cours. Je n’apprécie pas particulièrement ce site web mais pour un débutant ça peut-être une introduction correcte ^^

+0 -0

Bonjour,

Excellente démo.

Comme les coordonnées communales sont obtenues à partir du code INSEE, est-il possible de créer une carte de toutes les communes d’un département à partir d’une base de données sql ? Je suis également débutant en leaflet et surtout javascript.

Merci Conil26

J’imagine qu’il faut que je récupère toutes les variables dans un array que je traduis avec <?php echo json_encode($arr); ?>

contenant les variables:

  • INSEE
  • couleur

mais je ne sais pas comment organiser la lecture de cet array dans un while, pour avoir :

function style() {
    return {
      fillColor: 'couleur', // variable : couleur
      weight: 1,
      opacity: 1,
      color: 'white',
      dashArray: '3',
      fillOpacity: 0.2,
    };

et

var url = "https://geo.api.gouv.fr/communes/"+ INSEE +"/?&fields=contour" // variable : INSEE 

Bsr,

Je progresse mais je ne pourrai pas faire les 135 communes du Vaucluse comme ça. Il faut que je trouve la bonne boucle for.

Le html :

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Villes du Vaucluse</title>
    <script src="https://cdn.jsdelivr.net/npm/leaflet@1.5.1/dist/leaflet.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.5.1/dist/leaflet.css" />
  </head>
  <body>
    <div id="map" style="width:1200px; height:500px"></div>
    <script src="MAP.js"></script>
  </body>
</html>

le JavaScript

//  Carte centrée sur les coordonnées d'Avignon

const lat = 43.9492493;
const long = 4.8059012; // Ajuste ça pour mieux centrer

// Exécute un appel AJAX GET
// Prend en paramètres l'URL cible et la fonction callback appelée en cas de succès
function ajaxGet(url, callback) {
    var req = new XMLHttpRequest();
    req.open("GET", url);
    req.addEventListener("load", function () {
        if (req.status >= 200 && req.status < 400) {
            // Appelle la fonction callback en lui passant la réponse de la requête
            callback(req.responseText);
        } else {
            console.error(req.status + " " + req.statusText + " " + url);
        }
    });
    req.addEventListener("error", function () {
        console.error("Erreur réseau avec l'URL " + url);
    });
    req.send(null);
}

function initMap() {
  // Créer l'objet "macarte" et l'insérer dans l'élément HTML qui a l'ID "map"
  macarte = L.map('map').setView([lat, long], 11);
  // Leaflet ne récupère pas les cartes (tiles) sur un serveur par défaut. Nous devons lui préciser où nous souhaitons les récupérer. Ici, openstreetmap.fr
  L.tileLayer('https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', {
    // Il est toujours bien de laisser le lien vers la source des données
    attribution: 'données OpenStreetMap - rendu OSM France',
    minZoom: 1,
    maxZoom: 20
  }).addTo(macarte)
  function style() {
    return {
      fillColor: 'purple', // 'rgb(185,218,255)'
      weight: 1,
      opacity: 1,
      color: 'white',
      dashArray: '3',
      fillOpacity: 0.2,
    };
  }

// Les contours des villes déterminés par le code INSEE, 
// de 84001 à 84008, etc

  var url = "https://geo.api.gouv.fr/communes/84001/?&fields=contour"
  ajaxGet(url, function (reponse) {
    var contour = JSON.parse(reponse).contour;

    for (var i = 0 ; i < contour.length ; i++) {
      contour[i].reverse();
    }
    L.geoJson(contour).addTo(macarte);
    L.geoJson(contour, {style: style}).addTo(macarte);

  })  
    var url = "https://geo.api.gouv.fr/communes/84002/?&fields=contour"
  ajaxGet(url, function (reponse) {
    var contour = JSON.parse(reponse).contour;

    for (var i = 0 ; i < contour.length ; i++) {
      contour[i].reverse();
    }
    L.geoJson(contour).addTo(macarte);
    L.geoJson(contour, {style: style}).addTo(macarte);

  })
    var url = "https://geo.api.gouv.fr/communes/84003/?&fields=contour"
  ajaxGet(url, function (reponse) {
    var contour = JSON.parse(reponse).contour;

    for (var i = 0 ; i < contour.length ; i++) {
      contour[i].reverse();
    }
    L.geoJson(contour).addTo(macarte);
    L.geoJson(contour, {style: style}).addTo(macarte);

  })
    var url = "https://geo.api.gouv.fr/communes/84004/?&fields=contour"
  ajaxGet(url, function (reponse) {
    var contour = JSON.parse(reponse).contour;

    for (var i = 0 ; i < contour.length ; i++) {
      contour[i].reverse();
    }
    L.geoJson(contour).addTo(macarte);
    L.geoJson(contour, {style: style}).addTo(macarte);

  })
    var url = "https://geo.api.gouv.fr/communes/84005/?&fields=contour"
  ajaxGet(url, function (reponse) {
    var contour = JSON.parse(reponse).contour;

    for (var i = 0 ; i < contour.length ; i++) {
      contour[i].reverse();
    }
    L.geoJson(contour).addTo(macarte);
    L.geoJson(contour, {style: style}).addTo(macarte);

  })
    var url = "https://geo.api.gouv.fr/communes/84006/?&fields=contour"
  ajaxGet(url, function (reponse) {
    var contour = JSON.parse(reponse).contour;

    for (var i = 0 ; i < contour.length ; i++) {
      contour[i].reverse();
    }
    L.geoJson(contour).addTo(macarte);
    L.geoJson(contour, {style: style}).addTo(macarte);

  })
  var url = "https://geo.api.gouv.fr/communes/84007/?&fields=contour"
  ajaxGet(url, function (reponse) {
    var contour = JSON.parse(reponse).contour;

    for (var i = 0 ; i < contour.length ; i++) {
      contour[i].reverse();
    }
    L.geoJson(contour).addTo(macarte);
    L.geoJson(contour, {style: style}).addTo(macarte);

  })
    var url = "https://geo.api.gouv.fr/communes/84008/?&fields=contour"
  ajaxGet(url, function (reponse) {
    var contour = JSON.parse(reponse).contour;

    for (var i = 0 ; i < contour.length ; i++) {
      contour[i].reverse();
    }
    L.geoJson(contour).addTo(macarte);
    L.geoJson(contour, {style: style}).addTo(macarte);

  })

//   Le marker pour la préfecture
  var marker = L.marker([43.9492493, 4.8059012]).addTo(macarte);
  marker.bindPopup("Avignon").openPopup();
}
window.onload = initMap;

Merci de tous les conseils qui m’aideront à finaliser ce projet

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte