Custom layer et manipulation des templates Mustache

Avertissement

Niveau nécessaire : Avancé

Cette section vous permettra de :

  • comprendre le fonctionnement technique des templates dans mviewer

  • être en mesure d’adapter un custom layer pour manipuler et personnaliser le template

  • être autonome sur la correction des erreurs entre le custom layer et le template Mustache

Prérequis

  • Connaissances en JavaScript

  • Maîtriser le fonctionnement des custom layer et des templates

  • Connaître le fonctionnement de Mustache.js

Des sections de la documentation sont dédiées à ces thématiques si vous avez besoin d’en savoir plus. Voici un rappel sur Mustache.js.

Rappels sur le fonctionnement des templates

Les templates Mustache (format .mst) permettent d’afficher de façon standard ou personnalisée les informations d’une entité géographique visible sur la carte. L’utilisateur cliquera alors sur la carte pour avoir des informations sur l’entité ciblée.

Au clic, le code mviewer réalise une requête (getFeatureInfo) vers le serveur cartographique utilisé (ex. geoserver) afin d’interroger la couche et obtenir les informations sur les entités localisées sous le clic.

Note

Les templates utilisés sont localisés dans le fichier mviewer/js/templates.js.

Si le résultat de la requête contient bien des informations à afficher, alors les informations seront intégrées par ce code mviewer dans le template à droite (right-panel) ou en bas (bottom-panel) au format HTML. C’est via la librairie Mustache.js que nous obtenons du HTML à partir d’un template (.mst) et d’information JSON.

schema apply template

Limite avec un custom layer

Il est possible que le template à afficher se base sur des informations (JSON) qui ne sont pas fournies par les informations fournies par le serveur cartographique. C’est le cas par exemple si vous récupérez des données statistiques et que vous souhaitez afficher des données agrégées ou calculées.

Vous rencontrerez ce problème si vous utilisez une représentation type cluster comme ici.

Vous devrez donc organiser avec le JavaScript les informations JSON à fournir au template .mst afin de l’afficher correctement.

Pour réaliser cette manipulation de données et préparer le JSON à fournir au template, vous pouvez ajouter du JavaScript dans le template via la balise HTML <script>. Cette solution rajoute de la complexité dans le code et alourdir considérablement le fichier .mst.

Une autre solution éxiste via l’utilisons d’une fonction personnalisée que nous allons expliquer dans la section suivante.

Utilisation d’une fonction personnalisée

Ce type de fonction permet de manipuler librement les données que l’on va fournir au template Mustache et qui seront affichées par la suite lors d’un clic sur un objet de la carte.

Cette méthode est très utile pour :

  • Afficher les informations d’un cluster (car on cherche à afficher les features qui sont dans la feature Cluster).

  • Créer un mustache simple à partir d’informations complexes qui doivent être agrégées par le custom layer.

  • Conserver le code JavaScript dans le custom layer pour alléger le fichier .mst.

Vous trouverez ici un (exemple avec un cluster) native dans mviewer.

Exemple d’utilisation

Voici un exemple de méthode (handle) pour manipuler les informations au sein d’une ou plusieurs features afin de les afficher dans le template mustache dédié :

 1  /**
 2  * Obligatoire pour que le template mustache fonctionne avec les clusters
 3  * @param {Array} clusters
 4  * @param {Object} views
 5  */
 6  const _handle = function(clusters, views) {
 7      if (clusters.length > 0) {
 8      var l = mviewer.getLayer("myclusterlayerid");
 9      var elements = [];
10      var html;
11      var panel = "";
12      // ici on parcours toutes les features pour accéder au contenu et manipuler les propriétés
13      // on pourra par exemple rajouter pour une entité de nouveaux attributs ou d'autres données supplémentaires
14      clusters.forEach(c => {
15          // ICI ON CREER MANUELLEMENT LES FEATURES POUR MUSTACHE ET LE TEMPLATE POUR V3.5 ET ANTERIEUR
16          if (c?.properties) {
17              // v<3.5
18              elements = elements.concat(
19                  c.properties.features.map(d =>
20                      ({
21                          properties: d.getProperties()
22                      })
23                  )
24              )
25          } else {
26              // v>=3.5
27              elements = elements.concat(
28                  c?.getProperties()?.features || c.properties.features
29              );
30          }
31      })
32      // Création du HTML à partir du template et des features issues de la manipulation des données
33      if (l.template) {
34          html = info.templateHTMLContent(elements, l);
35      } else {
36          html = info.formatHTMLContent(elements, l);
37      }
38      // force l'affichage selon le mode mobile ou desktop
39      if (configuration.getConfiguration().mobile) {
40          panel = "modal-panel";
41      } else {
42          panel = "right-panel"
43      }
44      var view = views[panel];
45      view.layers.push({
46          "id": view.layers.length + 1,
47          "firstlayer": true,
48          "manyfeatures": (elements.length > 1),
49          "nbfeatures": elements.length,
50          "name": l.name,
51          "layerid": "myclusterlayerid",
52          "theme_icon": l.icon,
53          "html": html
54      });
55      }
56  };
57  // déclarer la fonction _handle pour ce custom layer à sa création
58  new CustomLayer(ID_LAYER, layer, null, _handle);

Notez donc que vous pouvez modifier les propriétés d’une feature avec cette solution ou que vous pouvez totalement créer un nouveau JSON à donner en paramètre d’entrée du template.

Pour rajouter un attribut randomValue supplémentaire nous aurions donc pu utiliser quelque chose comme :

 1  elements = elements.concat(
 2      c.properties.features.map(d =>
 3          ({
 4              properties: {
 5                  ...d.getProperties(),
 6                  randomValue: math.random()
 7              }
 8          })
 9      )
10  )

L’attribut randomValue serait alors utilisable dans le template.mst via {{randomValue}}.