Aller au contenu

Librairies carto Leaflet

La carte#

Pour créer une carte basée sur Leaflet :

  • centrée sur Paris : longitude 2.35, latitude 48.85
  • utilisant un élément HTML avec id="map"

Un élément HTML + chargement des librairies (CSS + JS)

<div id="map"></div>

<!-- Leaflet -->
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css">
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>

En CSS, une hauteur à la carte

#map {
    height: 500px;
}

Initialisation d’une carte Leaflet

L.map('map', {
    center: [48.85, 2.35],
    zoom: 13,
});

Ce que l’on note :

  • utilise des factory pour créer les objets, donc sans le mot-clé new (ici, c’est L.map)
  • la projection par défaut est EPSG:3857, mais on manipule uniquement des coordonnées en EPSG:4326
  • l’ordre des coordonnées est latitude/longitude
  • une carte n’a pas de couches chargées par défaut

Les projections#

Pour rappel, la projection par défaut est EPSG:3857 (Web Mercator), mais on ne manipule que des coordonnées en EPSG:4326 (WGS 84).

Pour manipuler des coordonnées dans d’autres projections, il faut alors utiliser PROJ avec le plugin Proj4Leaflet.

Les couches#

Rasters#

La principale classe est L.TileLayer

Ajout d’une couche OSM dans Leaflet

L.map('map', {
    center: [48.85, 2.35],
    zoom: 13,
    layers: [
        L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 19,
            attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
        }),
    ],
});

L’ajout de couches peut également se faire après la création de la carte avec map.addLayer(layer) ou layer.addTo(map)

WMS#

Pour une couche WMS, c’est la classe L.tileLayer.wms

Ajout d’un flux WMS

let wmsLayer = L.tileLayer.wms("https://api.ensg.eu/geoserver/wms", {
    layers: 'ensg:hydro',
    format: 'image/png',
    transparent: true,
    tiled: true,
    crs: L.CRS.EPSG4326
});

map.addLayer(wmsLayer);

Notez que le flux renvoit par défaut en EPSG:3857, mais Leaflet ne travaille qu’en EPSG:4326, il faut donc le préciser dans l’URL pour le retour avec crs: L.CRS.EPSG4326.

Vecteurs (points, lignes, surfaces)#

L’ajout d’objets vectoriels se réalise assez simplement. Il suffit d’utiliser les fonctions L.marker pour les marqueurs ou icônes, L.polyline/L.polygon pour les lignes/polygones, etc.

Leaflet

// icone sur Paris
let marker = L.marker([48.85, 2.35]);
map.addLayer(marker);

// polygon de l’ile de la cité
let polygon = L.polygon([[[48.8578,2.3393],[48.8568,2.3411],[48.8550,2.3432],[48.8534,2.3472],[48.8524,2.3497],[48.8516,2.3527],[48.8526,2.3522],[48.8538,2.3520],[48.8548,2.3510],[48.8557,2.3484],[48.8569,2.3439],[48.8573,2.3412],[48.8578,2.3393]]]);
map.addLayer(polygon);

Services web, APIs cartographiques#

La majeure partie du temps, les données affichées au sein des couches proviennent de services web géographiques ou d’APIs. Les fonds de cartes rasters par exemple sont fournis sous forme de services web (géographiques). Pour les données vectorielles, on parle le plus souvent d’APIs cartographiques (des URLs qui fournissent des données).

Voici un exemple qui affiche les tremblements de terre de plus de 4.5 sur l’échelle de Richter, sur le mois précédent.

Leaflet - Couche basée sur API en GeoJSON

let urlEarthQuakes = 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_month.geojson';

fetch(urlEarthQuakes)
.then(r => r.json())
.then(data => {
  L.geoJSON(data).addTo(map);
});

Il est nécessaire de faire un appel à l’API en AJAX (fetch()), puis d’utiliser ces données avec une couche L.geoJSON par exemple (puisque les données reçues sont en GeoJSON).

Les styles#

Styles statiques#

Style dans Leaflet

L.polygon([...], {
    color: 'red',
    weight: 5,
    fillColor: 'blue',
    fillOpacity: 0.5,
});

Exemple de style simple

Pour l’utilisation d’images (pixels ou vectorielles), il faut alors référencer l’URL, et préciser les différents alignements par rapport aux coordonnées de l’objet.

Icone dans Leaflet

L.marker([...], {
    icon: L.icon({
        iconUrl: 'icon.png',
        iconSize: [32, 32],
        iconAnchor: [16, 32], // pixels
    }),
});

Exemple d’icone

Styles dynamiques#

Dans Leaflet, les styles dynamiques sont uniquement possibles avec un objet L.GeoJSON. La fonction prend en paramètre l’objet (feature).

Leaflet - Style dynamique de GeoJSON

L.geoJSON(data, {
    style: function (feature) {
        return {
            color: feature.properties.color
        };
    }
})

Exemple de styles dynamiques

Styles multiples#

Pas de gestion de styles multiples dans Leaflet. Si c’est nécessaire, il faut alors dupliquer les objets, et leur appliquer des styles différents, mais beaucoup d’effets graphiques sont impossibles.

Les interactions#

Avec Leaflet, les objets vectoriels étant des objets HTML et/ou SVG, il est simple de créer des interactions. Il suffit par exemple d’utiliser CSS pour modifier le style d’un élément survolé, ou d’écouter des événements JavaScript pour les autres types d’interactions.

Leaflet - Changer le style en CSS du polygon au survol

/* besoin de préciser className sur l’objet Leaflet */
.classe-polygon:hover {
    fill: red;
    stroke: black;
    stroke-width: 10px;
}

Leaflet - Écouter le click sur un objet marker

marker.on('click', evt => {
    console.log(evt.latlng);
});

Certaines interactions sont prédéfinies. C’est le cas par exemple pour déplacer les marqueurs, ou les autres objets, avec l’option draggable ou la classe L.Draggable().

Leaflet - Rendre un marqueur déplaçable

let marker = L.marker([0, 0], { draggable: true });
marker.on('drag', (evt) => { });

Les popups#

Ajout d’une popup#

Si l’on souhaite ajouter une popup au click sur un marqueur, dans Leaflet, c’est assez simple. Il suffit... d’ajouter une popup. Il n’est pas nécessaire d’ajouter d’événement spécifique.

Leaflet - Ajout d’une popup

marker.bindPopup('Une popup');

Cela fonctionne également avec une couche L.geoJSON assez simplement. Il faut alors passer une fonction, qui sera appelée pour chaque objet

Leaflet - Ajout de multiples popups

L.geoJSON(data).bindPopup(function (layer) {
    return layer.feature.properties.description;
});

Modification d’une popup#

Pour modifier le contenu de la popup après sa création, il faut mettre à jour le HTML

Leaflet - Modification d’une popup

marker.on('click', evt => {
    marker.getPopup().setContent('lat: ' + e.latlng.lat + ' / lng: ' + e.latlng.lng);
});