Carte interactive du métro de Paris avec Leaflet

Ajout d’interactivité

Au niveau interactivités nous voulons :

  • Au survol d’une ligne, qu’elle soit surlignée
  • Au survol d’une station, que son marqueur s’agrandisse
  • Au survol des 2, affichage dans un encart des informations de l’élément survolé

Pour l’ajout de ces interactions, pour les deux calques GeoJSON on va utiliser un paramètre « onEachFeature », qui correspond à une fonction exécutée pour chaque feature.

Cette fonction permet d’attacher des listener d’événements (dans notre cas, « mouseover » et « mouseout »).

Ajout de l’encart

Mais avant d’ajouter ces interactions, il faut d’abord ajouter l’encart. Pour Leaflet, l’encart correspond à un contrôle, qui se crée comme ceci :

var info = L.control();

Avant d’ajouter ce contrôle à notre carte, il d’abord lui rajouter deux méthodes « onAdd » et « update ».

La première, qui prend la carte en paramètre d’entrée, ajoute dans le DOM notre encart et y attache la méthode « update » :

info.onAdd = function (map) {
    this._div = L.DomUtil.create('div', 'info');
    this.update();
    return this._div;
};

La deuxième, qui prend en entrée des propriétés d’objet GeoJSON, met à jour le contenu de l’encart. La distinction ligne/station ce fait sur la présence ou non d’une propriété « line » :

info.update = function (props) {
    if(props) {
	if(props.line){
	    this._div.innerHTML = '<p>Ligne ' + props.line + '</p>';
	} else {
	    this._div.innerHTML = '<p>' + props.name + ' – ' + props.about + '</p>';
        }
    } else {
        this._div.innerHTML = '<p>Survoler un élément</p>';
    }
};

Une fois ces deux méthodes déclarées, on peut rajouter notre contrôle à la carte :

info.addTo(map);

Ajout de l’interactivité des stations

Pour s’assurer que le pictogramme de la station survolée soit toujours affiché au-dessus des autres, il faut mettre aux marqueurs un paramètre « riseOnHover » à true :

return L.marker(latlng,{
  icon: L.icon({
      iconUrl: './symbole.1541586932.svg',
      iconSize:     [14, 14],
      iconAnchor:   [7, 7]
  }),
  riseOnHover: true
});

Pour les stations, la fonction appelée par « onEachFeature » est :

function onEachStation(feature, layer) {
  layer.on({
    mouseover: highlightStation,
    mouseout: resetStation
  });
}

Les deux fonctions correspondant aux deux événements sont :

function highlightStation(e) {
  info.update(e.target.feature.properties);
  e.target.setIcon(
    L.icon({
      iconUrl: './symbole.1541586932.svg',
      iconSize:     [18, 18],
      iconAnchor:   [9, 9]
    })
  );
}

function resetStation(e) {
  info.update();
  e.target.setIcon(
    L.icon({
      iconUrl: './symbole.1541586932.svg',
      iconSize:     [14, 14],
      iconAnchor:   [7, 7]
    })
  );
}

Une fois tout cela fait, on ajoute le paramètre « onEachFeature » à notre calque :

var stations = L.geoJson(metro_stations, {
  pointToLayer: function(feature, latlng) {
    return L.marker(latlng,{
      icon: L.icon({
          iconUrl: './symbole.1541586932.svg',
          iconSize:     [14, 14],
          iconAnchor:   [7, 7]
      }),
      riseOnHover: true
    });
  },
  onEachFeature: onEachStation
}).addTo(map);

Ajout de l’interactivé des lignes

Pour les lignes, la fonction appelée par « onEachFeature » est :

function onEachLine(feature, layer) {
  layer.on({
    mouseover: highlightLine,
    mouseout: resetLine
  });
}

Les deux fonctions correspondant aux événements sont :

function highlightLine(e) {
  var target = e.target;
  info.update(target.feature.properties);
  target.setStyle({weight:6});

    if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
        target.bringToFront(); // positionne la ligne au-dessus dans le calque
    }
}

function resetLine(e) {
    info.update();
  lines.resetStyle(e.target);
}

Une fois la fonction « onEachLine » rajoutée dans le paramètre « onEachFeature » du calque des lignes, notre carte est terminée :


Sources sur la prédominance de Leaflet :

Une version complète et plus grande est disponible sur mon site.

Laisser un commentaire