Jan 17, 2018 10:56:29 AM Paul PLOUY avatar   92    

Afficher une carte avec le plugin leaflet

Le plugin leaflet apporte un socle de base afin d'afficher des cartes au sein d'une application Lutece:

  • librairie leaflet (core javascript et bibliothèque css)
  • assortiment d'icônes pour afficher des marqueurs
  • interface rest pour l'affichage de popup
  • interface de fourniture d'Icône pour les marqueurs

Ces deux dernieres interfaces sont à implémenter dans le code serveur de votre plugin pour retourner un contenu (icones et popup html) spécifique. Dans sa version actuelle, le plugin-leaflet ne propose pas de template incluant du code html/javascript pour l'affichage des cartes en elles-mêmes. Il revient à l'intégrateur d'inclure le code necessaire dans une page en fonction des besoins en fonctionalités cartographiques.

Conditions préalables

La démarche consiste à créer un plugin ou module lutece incluant le plugin-leaflet et apportant les implémentations java des interfaces dans le code serveur. Ces implémentations seront ensuite utilisées dans les pages.

Inclusion du plugin

Inclure le plugin-leaflet dans le pom.xml du plugin ou module en spécifiant la dernière version à jour

<dependency>
  <groupId>fr.paris.lutece.plugins</groupId>
  <artifactId>plugin-leaflet</artifactId>
  <version>1.0.1-SNAPSHOT</version>
  <type>lutece-plugin</type>
</dependency>

Implémentation d'un fournisseur de popup

Les popups sont des fenêtres affichant un contenu contextuel lors du clic sur un objet de la carte. Le plugin leaflet fournit une interface de webservice rest permettant de retourner le contenu d'une popup.

1- Créer la classe Provider implémentant l'interface IPopupContentProvider et sa méthode getPopup().

Exemple:

import fr.paris.lutece.plugins.leaflet.rest.service.IPopupContentProvider;

public class MyLutecePluginPopupContentProvider implements IPopupContentProvider
{
	// Templates
    private static final String TEMPLATE_MYLUTECEPLUGIN_POPUP="/skin/plugins/myluteceplugin/leaflet/popup.html";

    // Markers
    private static final String MARK_MYLUTECEPLUGIN_ENTITY = "entity";

    public String getPopup( HttpServletRequest request, String strIdEntity, String strCode )
    {
		//add your code here to build the html content of the popup
        int nId = Integer.parseInt( strIdEntity );
        MyLutecPluginEntity entity = MyLutecePluginService.LoadEntity(nId);
        Map<String, Object> model = new HashMap<String, Object>();
        model.put( MARK_MYLUTECEPLUGIN_ENTITY, entity );
        HtmlTemplate t = AppTemplateService.getTemplate( TEMPLATE_MYLUTECEPLUGIN_POPUP, request.getLocale(), model );
        return t.getHtml();
    }
}
2- référencer ce Provider dans le fichier webapp/WEB-INF/conf/plugins/<myLutecePlugin>_context.xml

<bean id="leaflet-icon-provider-myluteceplugin" class="fr.paris.lutece.plugins.myluteceplugin.leaflet.service.mylutecepluginPopupContentProvider" />

L'identifiant du bean "leaflet-icon-provider-XXX" détermine l'id du provider à passer en paramètre de la méthode getIcon(). Le code java de la page affichant la carte peut alors appeller fr.paris.lutece.plugins.leaflet.service.IconService.getIcon("XXX", strIconKey) ;

Ajouter une carte leaflet sur une page Lutece

Documentation sur la librairie leaflet, librairie javascript open-source : http://leafletjs.com/

Exemple simple d'ajout d'une carte leaflet sur une page. Ici la projection par défault est utilisée (EPSG:3857 en lat long).

Importer la librairie :

<link rel="stylesheet" type="text/css" href="js/plugins/leaflet/leaflet/leaflet.css">
<script type="text/javascript" src="js/plugins/leaflet/leaflet/leaflet.js"></script>

Créer une carte, une vue et une couche pour les marqueurs

var map = L.map('map_address').setView([48.85632, 2.33272], 12);
var markers_layer = L.featureGroup().addTo(map);
// create the tile layer with correct attribution
var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib='Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors';
var osm = new L.TileLayer(osmUrl, {minZoom: 8, maxZoom: 16, attribution: osmAttrib}).addTo(map);

Ajouter le marqueur, spécifier son icone et ajouter l'appel ajax au service de popup lors d'un clic sur ce marqueur:

//Base rest Url for plugin-leaflet popup provider
var popupProviderUrl = "rest/leaflet/popup/";
// Custom provider name that implements  plugin-leaflet popup provider interface
var popupProviderName = "myluteceplugin";
// Id parameter to retrieve an object
var formId = ${appointmentform.idForm};
// code parameter ( not used with this adpater, let's set a dummy value)
var code = "code";
//Full popup url
var popupUrl = popupProviderUrl+popupProviderName+"/"+formId+"/"+code;

//creating the icon from the provided path
var myIcon = L.icon({
	iconUrl: ${MyPluginIcon}
});

markers_layer.clearLayers();
var marker = L.marker([poi.y, poi.x], {icon:  myIcon}).addTo(markers_layer);

marker.bindPopup("Chargement...");
marker.on('click', function(e) {
	var popup = e.target.getPopup();
	$.get(popupUrl).done(function(data) {
		popup.setContent(data);
		popup.update();
	});		 
});

map.fitBounds(markers_layer.getBounds());

Exemple:

screenshot leaflet

Pour aller plus loin

La documentation leaflet en ligne permet d'aller plus loin en terme de fonctionnalités géographiques:

  • Autres sources et formats pour les couches de fonds de plan et les couches métiers de la carte
  • Affichage de multiples objets géolocalisés à partir d'une source Geojson
  • Utiliser les propriétés des données de la carte pour modifier les marqueurs ( paramétrage des icônes, couleurs, etc. en fonction des valeurs)
  • Utiliser les propriétés des données de la carte pour modifier les popups (passer en paramètre une valeur pour modifier la réponse du service fournisseur de popup)
  • ...

La librairie proj4js également fournie avec le plugin-leaflet facilite les calculs de conversion entre les référentiels de coordonnées géographiques ( conversion d'une projection à une autre).