Bienvenue sur la documentation mviewer !¶
Introduction¶
Ci-dessous vous trouverez une documentation pour les utilisateurs ou administrateurs de la plateforme mviewer.
Documentation utilisateur¶
Cette partie est dédiée aux utilisateurs qui souhaitent prendre en main l’interface de mviewer.
Interface utilisateur¶
L’interface de mviewer peut être décomposée en 8 rubriques :
- Gestion des couches
- Gestion de l’affichage
- Outils de navigation
- Outils aditionnels
- Barre de recherche
- Documentation
- Fond de carte
- Crédits

Gestion des couches¶
Panneau listant l’ensemble des couches pouvant être chargée dans la carte. Pour en savoir plus, consulter la page « Gestionnaire de couches ».
Gestion de l’affichage¶
Panneau de gestion de l’affichage des couches sélectionnées. Pour en savoir plus, consulter la page « Gestion de l’affichage ».
Outils aditionnels¶
Outils permettant :
- de mesurer des aires ou des distances sur la carte
- de partager la carte
- d’exporter la carte sous forme d’image
Pour en savoir plus, consulter la page « Outils additionnels ».
Barre de recherche¶
Moteur de recherche de lieux (ville, département, région, … ). Pour en savoir plus, consulter la page « Barre de recherche ».
Documentation¶
Information complémentaires permettant de décrire le contexte de la plateforme, les données diffusées, les points de contact, … Pour en savoir plus, consulter la page « Documentation ».
Fond de carte¶
Outil permettant de changer le fond de carte parmi une liste prédéfinie. Pour en savoir plus, consulter la page « Fonds de carte ».
Gestionnaire de couches¶
Dans mviewer, la liste des données disponibles à l’affichage est visible dans le panneau de gauche.

L’arborescence¶
Comme décrit dans la page « Configurer - Les couches », les couches peuvent être organisées de la manière suivante :
- un thème,
- un (ou plusieurs) groupe(s) (ce niveau est optionnel),
- une (ou plusieurs) couche(s).
Par défaut, l’arborescence est repliée et seuls les thèmes sont visibles. En cliquant sur un thème, son contenu (groupe(s) ou couche(s)) apparaît. Il en va de même sur un groupe qui peut être déplié pour voir apparaître les couches qu’il contient. De la même façon, un clic sur un thème / groupe déplié va le replier.
Afficher / cacher des couches¶
Pour afficher une couche dans la carte, il vous suffit de cliquer dessus. Dès lors, l’icone ( ) situé devant le nom devient (
).
Pour supprimer une couche de la carte, il vous suffit de cliquer de nouveau sur son nom.
Afficher / cacher le panneau¶
En cliquant sur l’icone ( ) vous avez la possibilité de plier / déplier le panneau.

Configurer¶
Pour savoir comment modifier la liste des couches présentes dans ce panneau, vous êtes invités à consulter la page « Configurer - Les couches ».
Gestion de l’affichage¶
Le gestionnaire d’affichage de couche se trouve sur la partie gauche de la carte.

Lorsque dans le panneau latéral (voir « Gestionnaire de couches ») vous cliquez sur une couche, celle-ci apparaît dans le gestionnaire d’affichage.
Options sur une couche¶
Là, vous avez la possibilité :
- de visualiser le rendu graphique (la légende),
- de modifier l’opacité (transparence),
- d’afficher des informations sous la forme d’infobulles (optionnel),
- de voir la source de la donnée (optionnel),
- de supprimer la couche de la carte*(en cliquant sur l’icone*
)

Autres options¶
De plus, l’utilisateur à la possibilité de :
- modifier l’ordre d’affichage : pour cela, il vous suffit de cliquer sur une couche et de la glisser / déposer à l’endroit désiré. Notez que la couche en haut dans la liste sera affichée au premier plan dans la carte.
- supprimer (ne plus afficher) l’ensemble des couches (
)
- plier / déplier le gestionnaire (
)
Outils additionnels¶
Les outils additionnels se comptent au nombre de trois :
Outils de mesure¶
En cliquant sur l’icone ( ), deux nouveaux outils apparaissent et vous avez la possibilité de mesurer :
Marche à suivre¶
Pour faire une mesure, il vous suffit de dessiner une ligne (ou une surface) à l’aide du clic-gauche de votre souris. Au fur et à mesure que vous avancez dans le dessin, la distance cumulée (ou bien la surface) est affichée.

Pour terminer une mesure, faites un double clic-gauche avec la souris.
Pour effacer une mesure (distance ou bien surface), il vous suffit de cliquer de nouveau sur l’outil que vous avez utilisé.
Partage de carte¶
Le partage de carte permet de générer un lien web fixant la situation actuelle de l’interface. Ainsi sont conservés :
- la position de la carte,
- le niveau de zoom,
- la liste des couches affichées avec leurs paramètres de transparence.
Une fois que vous avez cliqué sur l’icone ( ), une nouvelle fenêtre apparaît :

Choix du mode d’affichage du permalien¶
Normal
Simplifié
Ultra Simplifié (idéal intégration page web)
Choix du type de lien¶
- générer un lien hypertext (icone de gauche) : lorsque vous cliquez, un nouvel onglet de votre navigateur s’ouvre avec le lien permanent,
- utiliser un QR Code (icone de droite).
Exemple de permalien : http://localhost/mviewer/?x=-220750&y=6144926&z=8&l=epci&lb=positron&mode=u
- x et y : coordonnées du centre de la carte
- z : niveau de zoom
- l : liste des couches
- lb : couche de fond par défaut
- mode : mode d’affichage (n,s ou u)
Export de la carte¶
En cliquant sur l’icone ( ) la carte est automatiquement exportée au format .png.

Barre de recherche¶
La barre de recherche, située en haut à droite de l’interface, permet de rechercher tout type de lieux, comme par exemple des noms de communes, de département ou de région ainsi que, si c’est paramètré, des entités.

Au fur et à mesure que l’utilisateur écrit, le moteur de recherche affiche les propositions correspondantes. Là, l’utilisateur est invité à cliquer sur l’entrée qui correspond à son attente. Dès lors, le navigateur va zoomer sur l’entité sélectionnée.
En cliquant sur la croix (à droite de la zone d’écriture), l’utilisateur efface le contenu de la zone de texte.
Options¶
En cliquant sur l’icone composée de 3 points, l’utilisateur à la possibilité d’affiner les options de recherche, avec les choix suivants :
- Rechercher dans l’emprise de la carte
- Rechercher des adresses
- Rechercher des entités

Documentation¶
Le panneau de documenation offre aux utilisateurs des informations complémentaires permettant de décrire le contexte de la plateforme, les données diffusées, les points de contact ou toutes autres données nécessaires.
Ouvrir et fermer le panneau¶
En cliquant sur le bouton « ? », un nouveau panneau s’affiche au premier plan de l’écran.

Pour fermer ce panneau, il vous suffit soit :
- de cliquer sur la croix en haut en droite du cadre,
- de cliquer en dehors du cadre.
Configurer le panneau¶
Techniquement, ce panneau de documentation se présente sous la forme d’un fichier .html que l’on retrouve à la racine du dossier de mviewer : mviewer_help.html.

En éditant et modifiant ce fichier, vous aurez la possibilité de gérer (ajouter/supprimer/renommer) les onglets, ainsi que leur contenu. Pour plus d’information, veuillez consulter la page XXXX.
Fonds de carte¶
En cliquant sur l’icone ( ) en bas à droite de la carte, l’utilisateur à la possibilité de changer le fond de carte. Par défaut, quatre fonds sont proposés :
- Positron (actif au démarrage),
- OpenStreetMap,
- Carroyage,
- Dark Matter.

Pour modifier la liste des fonds de carte, veuillez consulter la page « Configurer - Les couches de fond ».
Crédits¶
En cliquant sur l’icone ( ) l’utilisateur fait apparaître les crédits du Fonds de carte actuellement affiché. Lorsque ce dernier est changé, les crédits sont automatiquement mis à jour.

Pour replier la fenêtre de crédit, il vous suffit de cliquer sur l’icone .
Documentation technique¶
Cette partie est dédiée aux personnes qui ont vocation à déployer et configurer la plateforme mviewer.
Installer MVIEWER¶
Mviewer est une application web développée en HTML / CSS / JAVASCRIPT. Elle nécessite simplement d’être déployée sur un serveur WEB qui peut être APACHE, NGINX, TOMCAT…
Avec un serveur web Apache¶
Avertissement
Prérequis : disposer d’une instance Apache
Clonage des sources et déploiement¶
L’objectif est de copier les sources depuis github.com dans le répertoire web d’Apache.
Avec git¶
Dans un terminal, après vous être placé dans le dossier web Apache, exécuter la commande git suivante.
git clone https://github.com/geobretagne/mviewer.git
Sans git¶
Télécharger ce fichier zip présent sur la page d’accueil du dépôt mviewer sur GitHub : https://github.com/geobretagne/mviewer
Dézipper le contenu du zip dans le dossier web Apache /var/www/ (ou autres dossiers de déploiement Apache).

Avec Docker¶
Avertissement
Prérequis : disposer de docker
mviewer en mode standalone¶
C’est la solution la plus simple. Il est ainsi possible de lancer mviewer et de visualiser toutes les démos disponibles dans l’application. Ce mode ne convient pas pour effectuer ses propres applications mviewer.
#Récupérer la dernière image buildée de mviewer
docker pull mviewer/mviewer
#Lancer le container docker mviewer
docker run --rm -p80:80 mviewer/mviewer
mviewer et un dossier d’applications¶
C’est la solution à privilégier pour créer ses propres applications. En parallèle de mviewer, un dossier web apps (volume) est monté. Ce dossier web contient vos applications mviewer ainsi que les ressources nécessaires.
# Lancer le container mviewer + le répertoire web apps qui pointe vers
# /chemin/vers/repertoire_de_configurations_xml
docker run --rm -p80:80 \
-v/chemin/vers/repertoire_de_configurations_xml:/usr/share/nginx/html/apps \
mviewer/mviewer
mviewer avec docker-compose¶
Cette solution permet de mettre en place les mêmes possibilités que la méthode précédante (mviewer + volume d’applications) en utilisant docker-compose et deux fichiers de paramétrage
Avertissement
Prérequis : disposer de docker et docker-compose
- Création du fichier environemment
APPSPATH=/home/prod/mviewer-apps
- Création du fichier de configuration
version: '3.2.1'
services:
mviewer:
container_name: mviewer
build: .
ports:
- "80:80"
image: mviewer/mviewer
volumes:
- '${APPSPATH}:/usr/share/nginx/html/apps'
- Lancer mviewer
docker pull mviewer/mviewer
docker-compose up
Test navigateur¶
Une fois déployée, l’application est accessible dans le navigateur internet en saisissant l’URL http://nom_du_serveur/demo/
exemples :
Configuration et adaptations¶
Si vous souhaitez publier vos propres couches/thèmes ou bien ajouter/supprimer certaines fonctionnalités, veuillez consulter la page « Configurer - Principe ».
Configurer - Principe¶
Le visualiseur cartographique mviewer consomme des données et des services servis par le web (flux OGC WMS/WFS/WMTS, services de géocodage…). La connexion et le paramétrage de ces services se fait dans un fichier de configuration pivot qui permet en outre de personnaliser l’application (titre, logo, feuille de style…).
Si aucune configuration n’est indiquée dans l’URL, c’est la configuration par défaut qui s’applique ( apps/default.xml).
Il est possible de créer n fichiers de configuration (config1.xml, config2.xml…) de façon à créer plusieurs applications thématiques à partir d’une seule instance mviewer. Pour appeler une configuration particulière, il suffit alors de rajouter le paramètre config dans l’url, exemple ?config=demo/geobretagne.xml . Pour d’autres exemples, consulter la page : démos.
Structure du fichier de configuration¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?xml version="1.0" encoding="UTF-8"?>
<config>
<application />
<extensions>
<mapoptions />
<baselayers>
<baselayer />
</baselayers>
<proxy />
<olscompletion />
<elasticsearch />
<searchparameters />
<themes>
<theme>
<layer />
</theme>
</themes>
</config>
|
Paramètres d’URL¶
Il est possible d’instancier un mviewer avec des paramètres de configuration transmis par URL
config
: Fichier de configuration à charger ex:mviewer/?config=apps/mon_appli.xml
.#
: Il s’agit d’un raccourci pour appeler une config présente dans le dossier apps. ex:mviewer/#mon_appli
.theme
: Thème css à utiliser ex:?theme=geobretagne
pour charger le theme doit être dans css/themes/geobretagne.css.wmc
: liste des contextes OGC WMC (séparés par des virgules) à charger afin d’alimenter le panel de gauche ex :mviewer/?wmc=demo/hydro.wmc
popup
: true ou false. Si true, une popup s’affiche sur la carte afin d’afficher le résultat de l’interrogation de couches.lang
: Langue à utiliser pour l’interface. Passer exemple?lang=en
.mode
: Mode d’affichage à utiliser (d - default, s - simplifié, u - ultrasimplifié). Le mode simplifié ne dispose pas du panneau des thématiques et le mode ultra simplifié ne dispose pas de la barre de navigation.title
: Titre à utiliser. Seulement exploité en mode défault et simplifié.topics
: Thèmes à filtrer.
Paramètres d’URL utilisés pour les permaliens¶
x
: Coordonnées x du centre de la carte dans le système de projection utilisé par l’application.y
: Coordonnées y du centre de la carte dans le système de projection utilisé par l’application.z
: Zoom de la carte (1 à 20).lb
: Identifiant de la couche de fond affichée.
Sections de configurations¶
- Configurer l’application « Configurer - Application ».
- Configurer les extensions « Configurer - Extensions
- Configurer la carte « Configurer - les options de la carte ».
- Configurer les couches de fonds « Configurer - Les couches de fond ».
- Configurer les couches thématiques « Configurer - Les couches ».
- Configurer la recherche « Configurer - La recherche ».
- Configurer le proxy « Configurer - Le proxy ».
Bien commencer avec mviewer¶
Préparer votre environnement de travail¶
Si vous débutez, nous vous conseillons de créer un dossier unique nommé « git ». Nous installerons ensuite Git et le terminal Git Bash pour passer les commandes à Git.
Sur Windows:
C:\Users\jean\Documents\git
Sur Ubuntu/Debian (autre):
/home/user/jean/git
Le code mviewer sera par la suite placé dans un répertoire « mviewer »:
Exemple: C:\Users\jean\Documents\git\mviewer
Télécharger ensuite Git et installez le tout. Le terminal Git Bash sera installé en même temps.
Git Bash vous permettra de réaliser les commandes qui suivront.
Travailler avec un fork¶
Règle générale : Ne jamais modifier la branche MASTER.
La branche master est une branche « mirroir » de la branche master du code initial (geobretagne/mviewer).
C’est votre point de départ pour tout nouveau travail et tout nouveau travail doit repartir d’une base à jour et propre.
Nous recommandons de créer une branche à partir de la branche master à jour pour chaque nouveau travail.
La section qui suit vous donnera la procédure pour obtenir votre fork.
Récupérer les sources (fork)¶
Pour bien débuter, nous vous recommandons de réaliser un fork vers votre espace GitHub.
Prérequis
- Disposer d’un compte GitHub
- Avoir les droits de création sur ce compte
- Être connecté sur GitHub
Procédure
Sur la page GitHub du mviewer cliquer sur « Fork » en haut à droite.

Choisissez ensuite le compte vers lequel réaliser votre fork.
Vous détenez maintenant un fork disponible à l’adresse : https://github.com/MON_ORG/mviewer MON_ORG étant à remplacer par le nom de votre compte GitHub.
Votre fork contient nativement les mêmes branches à l’identique, dont la branche master.
Vous pourrez créer des nouvelles branches et modifier le code sans impacter le code natif du repository inital (geobretagne/mviewer).
Ouvrez Git Bash
Allez sur le repository mviewer GitHub et cliquez sur « clone or download ». Copier ensuite l’URL dans la commande suivante.
Réalisez un clone (copie) du code mviewer sur votre ordinateur en collant l’URL précédente:
git clone https://github.com/MON_ORG/mviewer.git
Gestion des droits¶
Vous pouvez gérer les droits de votre repository pour les utilisateurs, développeurs et autres personnes disposant d’un compte GitHub.
Pour cela, cliquez en haut dans « Settings » et accédez à gauche à l’onglet « Collaborators & team ».
Créer une branche¶
Vous pouvez créer une branche sur GitHub directement ou avec Git.
Pour créer une branche su GitHub.
- Cliquez sur le bouton de la liste Branch:(nom de branche)
- Choisissez la branche de départ (master) dans la liste des branches disponibles
- Cliquez à nouveau sur le bouton de la liste Branch:(nom de branche)
- Dans le champ de recherche, saisissez le nom de votre nouvelle branche (*).
- Cliquez ensuite sur « Create Branch: (nom de votre branche) »
Vous avez maintenant une nouvelle branche.
Pour récupérer cette nouvelle branche dans votre dépôt Git, suivez la procédure qui suit:
Positionnez-vous dans votre dossier ../git/mviewer/:
Synchronisez votre dossier git:
git fetch
Positionnez-vous dans votre dossier mviewer (le dossier créé par la commande “git clone”):
git pull
Si vous souhaitez changer de branche, saisissez cette commande:
git checkout NOM_DE_MA_BRANCHE
Récupérer les nouveautés de la branche¶
Pour mettre à jour votre dépôt (dossier) local mviewer (/git/mviewer) réalisez la commande:
git pull
Vous travaillerez maintenant sur la nouvelle branche de votre choix. Chaque nouvelle mise à jour de la branche master de votre fork devra être reportée sur cette branche aussi souvent que possible.
Pour mettre à jour la branche master de votre fork, nous devons définir en premier une « source distante » (upstream).
(*) Attention : Choisissez un nom permettant d’identifier rapidement cette branche pour vous et votre équipe.
Définir un upstream¶
Pour mettre à jour la branche master depuis le code de GéoBretagne, vous devrez indiquer quelle est la « source distante » (upstream). Votre « origin » sera votre votre repository mviewer (fork).
Voici la manipulation.
Définir un upstream:
git remote add upstream https://github.com/geobretagne/mviewer
Observer que vous avez bien un upstream:
git remote -v > origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch) > origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (push) > upstream https://github.com/geobretagne/mviewer.git (fetch) > upstream https://github.com/geobretagne/mviewer.git (push)
Bravo ! Mettons maintenant à jour votre branche master.
Mettre à jour votre fork - master¶
Attention : assurez-vous d’avoir réalisé l’étape précédente avant celle-ci.
Vous devrez un jour mettre à jour votre branche master au sein de votre fork. Faites ainsi :
Avec Git Bash ou votre terminal, positionnez-vous dans votre dossier mviewer (dossier récupéré via le clone):
cd C:\Users\jean\Documents\git\mviewer
Vérifiez que vous avez bien un upstream qui pointe vers https://github.com/geobretagne/mviewer.git (voir l’étape précédente).
Positionnez vous sur la branche master:
git checkout origin/master
Synchronisez vous avec la source distante:
git fetch upstream
Remplacez votre branche master (origin) par celle de géoBretagne (upstream):
git reset --hard upstream/master
Poussez ensuite ce code récupéré depuis géoBretagne (upstream) vers votre branche master (origin):
git push origin master --force
Organisation des fichiers de carte¶
Rgèle générale
Ne JAMAIS modifier les fichiers du coeur.
Les fichiers du coeur sont tous les fichiers que vous obtenez nativement avec un clone de départ.
Nous vous recommandons d’intégrer la structure décrite dans cette section afin de simplifier vos manipulations de fichier :
Créer un répertoire « apps » à la racine du mviewer.
Positionner tous les fichiers de configuration XML à la racine du répertoire apps:
Exemple : C:\Users\jean\Documents\git\mviewer\apps\ma_carte.xml
Créer un dossier par fichier de configuration que nous appellerons « dossiers de carte »:
Exemple : C:\Users\jean\Documents\git\mviewer\apps\ma_carte\
Pour chaque dossier de carte, vous devrez créer les dossiers : templates, customcontrols, customlayers, data, sld, css, img.
Pour notre fichier de config « ma_carte.xml », nous aurons donc cette structure:
/apps
├── ma_carte.xml
└── ma_carte
├── customcontrols
├── customlayers
├── data
├── css
├── sld
├── img
└── templates
Vous placerez dans ces dossiers les données (geojson), les customcontrols (js), les cunstomlayers (js) ainsi que les template mustache (js). Vous prendrez en compte la localisation de ces fichiers dans le fichier de configuration XML en donnant les bons chemins d’accès.
Organisation des autres fichiers¶
- Créer un répertoire « common » à la racine du répertoire « apps » (/apps/common/)
- Créer un dossier js, css, img, lib
- Créer un dossier basemaps, logo, legend, credit dans /img (/apps/common/img/)
On obtiendra donc cette structure:
/apps
├── common
└── js/
├── css/
├── lib/
└── img/
├── legend/
├── logo/
├── credit/
└── basemap/
├── ma_carte.xml
└── ma_carte
├── customcontrols
├── customlayers
├── data
└── templates
Vous placerez tous les fichiers que vous avez créés ou modifiés dans ces dossiers au sein de /apps/common. Vous prendrez en compte la localisation de ces fichiers dans le fichier de configuration XML en donnant les bons chemins d’accès.
URL de carte¶
Il vous faudra prendre en compte le dossier « apps » dans vos urls de carte ainsi:
http://kartenn.region-bretagne.fr/kartoviz/?config=apps/aide-droit-carte.xml
Addons¶
Si vous souhaitez enrichir vos cartes de fonctionnalités (isochrones, recherches, filtres temporels, …) vous pouvez dupliquer cet addon dans tous les dossiers de carte.
Vous pouvez aussi créer un dossier « addons » dans le répertoire common et y ajouter la structure nécessaire (customlayers, customcontrols) pour être réexploitable par toutes les cartes :
Voici exemple d’organisation de fichier avec un addon « Isochrone »:
/apps
├── common
└── js/
├── css/
├── lib/
├── addons/
└── isochrone
├── customlayers
├── customcontrols
└── img/
├── legend/
├── logo/
├── credit/
└── basemap/
Le dossier « apps » étant votre dossier de travail, vous pouvez l’organiser selon vos besoins.
Participer à la communauté¶
Pour apporter une correction d’anomalie ou une évolution, nous vous recommandons d’aller à la la page « Contribuer ».
Bonnes pratiques de développements¶
Commits
Lorsque vous réalisez des commits, séparez les commits de style des commits de code.
Un commit de style comprend :
- Suppression / ajout d’un espace
- Suppression / ajout d’un saut de ligne
- Tout ce qui n’est pas du code
Un commit de code comprendra à l’inverse :
- Une modification sur une syntaxe
- Une modification sur une fonction
- Une modification sur un nom de variable
- Tout ce qui n’est pas du style
Encodage
L’encodage a utiliser est l’UTF-8.
Formatage
Lors de vos développements, inspectez le formatage du code initial :
- Le nombre d’espace pour indenter
- La présence d’espace avant et après les parenthèses
- La présence d’espace avant ou après les opérateurs logiques (==, <, >, ||, &&)
- Le nombre de saut de lignes avant ou après une fonction, un bloc de clode, etc…
- autres
Méfiez-vous de votre éditeur de code. Pensez à désactiver les plugins ou à configurer les règles de formatage.
Respectez ensuite ce formatage.
Commentaires
Un code commenté est un code compréhensible par tous. Nous recommandons très fortement d’utiliser les commentaires. Mieux vaut trop de commentaires que pas assez.
Commentaires JavaScript:
// ceci est un commentaire une sune ligne /* Ceci est un commentaire sur plusieurs lignes*/
Commentaire CSS:
/*Je suis un commentaire CSS*/
Commentaire HTML:
<!--Je suis un commentaire HTML-->
Pour les fonctions ou méthodes JavaScript, nous recommandons d’ajouter en commentaire:
- Ce que fait cette fonction ou méthode
- Les paramètres en entrée
- Le résultat attendu et ce qui est retourné en sortie
Les indésirables
Nous déconseillons les affichages d’informations qui ne sont utiles qu’aux développeurs (console.log, alert, …).
Editeur de code
Il n’y a pas d’obligation et vous êtes libre d’en choisir un.
- Notepadd++
- Sublime
- Visual Studio Code
- Atome
- autre
Informations git & GitHub¶
Vous trouverez plus d’information sur la page « Travailler avec Git et GitHub ».
Vous trouverez notamment de la documentation dans la partie « Documentation ».
Configurer - Application¶
Personnalisation de l’application
Syntaxe
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <application title=""
logo=""
help=""
showhelp=""
titlehelp=""
iconhelp=""
style=""
exportpng=""
measuretools=""
stats=""
statsurl=""
coordinates=""
geoloc=""
mouseposition=""
togglealllayersfromtheme=""
templaterightinfopanel=""
templatebottominfopanel=""
studio=""
home=""
mapfishurl=""
lang=""
langfile=""
/>
|
Paramètres
title
studio : paramètre optionnel de type texte qui définit le titre de l’application. Valeur par défaut mviewer.logo
studio : paramètre optionnel de type url qui définit l’emplacement du logo de l’application. Valeur par défaut img/logo/earth-globe.svg.help
studio : paramètre optionnel de type url qui définit l’emplacement du fichier html de l’aide.showhelp
studio : paramètre optionnel de type booléen (true/false) précisant si l’aide est affichée en popup au démarrage de l’application. Valeur par défaut false.titlehelp
: paramètre optionnel de type texte qui définit le titre de la popup d’aide. Valeur par défaut Documentation.iconhelp
: paramètre optionnel de type texte qui précise l’icône à utiliser afin d’illustrer la thématique. Les valeurs possibles sont à choisir parmi cette liste : http://fontawesome.io/icons/style
studio : paramètre optionnel de type url précisant la feuille de style à utiliser afin de modifier l’apparence de l’application (couleurs, polices…). Valeur par défaut css/themes/default.css. Voir : « Configurer - Apparence ».exportpng
studio : paramètre optionnel de type booléen (true/false) activant l’export de la carte en png. Valeur par défaut false. Attention l’export ne fonctionne qu’avec des couches locales (même origine) ou avec des couches servies avec CORS activé.measuretools
studio : paramètre optionnel de type booléen (true/false) activant les outils de mesure. Valeur par défaut false.stats
: paramètre optionnel de type booléen (true/false) activant l’envoi de stats d’utilisation l’application. Valeur par défaut false.statsurl
: paramètre optionnel de type url précisant l’url du service reccueillant les données d’utilisation de l’application (ip, application title, date). Ce service n’est pas proposé dans mviewer.coordinates
studio : paramètre optionnel de type booléen (true/false) activant l’affichage des coordonnées GPS ( navbar) lors de l’interrogation. Valeur par défaut false.geoloc
: paramètre optionnel de type booléen (true/false) activant la géolocalisation. Nécessite une connection https. Valeur par défaut false.mouseposition
: paramètre optionnel de type booléen (true/false) activant l’affichage des coordonnées correspondant à la position de la souris. Les coordonnées sont affichées en bas à droite de la carte. Valeur par défaut false.togglealllayersfromtheme
studio : Ajoute un bouton dans le panneau de gauche pour chaque thématique afin d’afficher/masquer toutes les couches de la thématique.Valeur : true/false. Valeur par défaut false.templaterightinfopanel
: Template à utiliser pour le rendu du panneau de droite. Valeur à choisir parmi les templates de mviewer.templates.featureInfo (default|brut|accordion). Valeur par défaut default.templatebottominfopanel
: Template à utiliser pour le rendu du panneau du bas. Valeur à choisir parmi les templates de mviewer.templates.featureInfo (default|brut|accordion). Valeur par défaut default.studio
: Lien vers le mviewerstudio pour modifier la carte en cours.home
: Lien vers le site parent de mviewermapfishurl
: Lien permettant d’afficher les couches courantes visibles vers un mapfishapp (geOrchestra) ciblehideprotectedlayers
: Indique si les couches protégées doivent être masquées dans l’arbre des thématiques lorsque l’utilisateur n’y a pas accès. Valeur : true/false (true par défaut).lang
: Langue à utiliser pour l’interface. Passer « ?lang=en » dans l’url pour forcer la langue et ignorer la config. Par défaut, lang n’est pas activé. Le fichier mviewer.i18n.json contient les expressions à traduire dans différentes langues. Pour traduire le texte d’un élément html, il faut que cet élément dispose d’un attribut i18n=texte.a.traduire. En javascript la traduction s’appuie sur la méthode mviewer.tr(« texte.a.traduire »).langfile
: URL du fichier de traduction supplémentaire à utiliser en complément de mviewer.i18n.json.
Exemple
1 2 3 4 5 6 | <application title="Exemple"
logo="img/logo/g.png"
help=""
exportpng="false"
measuretools="true"
style="css/themes/blue.css"/>
|
Configurer - les options de la carte¶
Syntaxe
1 2 3 4 5 6 7 8 9 10 11 | <mapoptions
maxzoom=""
projection=""
center=""
zoom=""
projextent=""
maxextent=""
rotation=""
scalebar=""
scaleunits=""
scalesteps=""/>
|
Paramètres
maxzoom
: paramètre optionnel de type entier qui définit le seuil maximum de zoom de l’application. Valeur par défaut 19..projection
: paramètre obligatoire de type texte définissant la projection (code EPSG) utilisée par la carte. Exemple EPSG:3857.center
studio : paramètre optionnel de type numérique définissant les coordonnées géographiques du centre de la carte. Exemple -220750.13,6144925.57.zoom
studio : paramètre optionnel de type entier définissant le zoom initial de la carte. Valeur par défaut 8.projextent
: paramètre obligatoire de type texte définissant les limites géographiques de la projection utilisée. Ce paramètre n’est pas obligatoire pour les projections EPSG:4326 et EPSG:3857.maxextent
studio : paramètre optionnel de type texte définissant les limites géographiques pour la vue cartographiquescalebar
: paramètre optionnel de type texte pour afficher l’échelle en barre et non en ligne (« false » par défaut).scaleunits
: paramètre optionnel de type texte pour préciser l’unité de mesure de l’échelle (« metric » par défaut)scalesteps
: paramètre optionnel de type texte pour préciser le nombre de pas de l’échelle (« 2 » par défaut).scaletext
: paramètre optionnel de type texte pour préciser si on souhaite afficher le texte au dessus d’une échelle en barre (« true » par défaut).
Exemple
1 2 3 4 5 6 7 8 9 10 11 | <mapoptions
scalebar="true"
scaletext="true"
scaleunits="metric"
scalesteps="3"
maxzoom="18"
projection="EPSG:3857"
center="-161129,6140339"
zoom="9"
projextent="-20037508.342789244, -20037508.342789244, 20037508.342789244, 20037508.342789244"
maxextent="-550346.603653, 5975541.123222, -45250.720745, 6262944.349574" />
|
Astuce
La carte dispose également d’un marker qui s’affiche au clic sur la carte. Il est possible de modifier ce marker via css.

#mv_marker path {
fill: #337ab7;
}
Configurer - Les couches de fond¶
<Baselayers>
¶
Paramétrages de la liste des fonds de plan.
Syntaxe
1 2 3 4 | <baselayers style="">
<baselayer />
<baselayer />
</baselayers>
|
Paramètre
style
studio : paramètre optionnel de type texte à choisir parmi (default/gallery) et définissant le style du contrôle permettant de changer de fond de carte. Valeur par défaut default.
Le mode « default » active le contrôle suivant :

Le mode « gallery » active une liste à deux états :
un état déplié :

un état replié:

<baselayer>
¶
Elément enfant de <baselayers>
permettant le paramétrage de chaque fond de plan.
Syntaxe
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <baselayer type=""
owsoptions=""
id=""
label=""
title=""
maxscale=""
thumbgallery=""
url="" layers=""
format=""
visible=""
fromcapacity=""
attribution=""
style=""
matrixset=""
maxzoom=""
opacity=""
/>
|
Paramètres
type
: paramètre obligatoire de type texte qui définit le type de la couche. Les options sont (OSM, WMTS, WMS, fake). Fake permet de disposer d’un fond vierge. C’est alors le motif ou la couleur du fond de l’application qui s’affiche.owsoptions
: Pour une couche WMS, permet de forcer certains paramètres des requêtes GetMap. Exemple : « VERSION:1.3.0 ».id
: paramètre obligatoire de type texte pour attribuer un identifiant unique et interne à la couchelabel
: paramètre obligatoire de type texte pour définir le nom du fond de plantitle
: paramètre obligatoire de type texte pour définir le sous-titre du fond de plan. Utilisé avec le mode « gallery »maxscale
: paramètre optionnel définissant l’échelle max du fond de planthumbgallery
: paramètre obligatoire de type url permettant de sélecionner l’imagette à associer au fond de plan.url
: paramètre obligatoire de type url définissant l’URL du service web OSM, WMTS ou WMS.layers
: paramètre optionnel de type texte définissant l’identifiant technique de la couche. (Obligatoire pour les couches de type WMS et WMTS)format
: paramètre optionnel de type texte définissant le Format d’image retourné par le serveur. (Obligatoire pour les couches de type WMS et WMTS)visible
studio : paramètre obligatoire de type booléen (true/false) précisant si la couche est visible au démarrage. Il s’agit d’un paramètre exclusif. Une seule couche de fond peut être affichée sur la carte. Attention un baseselayer et un seul doit disposer du paramètre visible= »true ».fromcapacity
: paramètre optionnel de type booléen (true/false)spécifique aux fonds de plan WMTS. Permet la construction de la couche à partir des capacités du service WMTS.attribution
: paramètre obligatoire alimentant le contrôle attributions de la carte ().
style
: paramètre optionnel précisant le style à associer à la couche. Paramètre obligatoire pour les couches de type WMTSmatrixset
: paramètre optionnel précisant le style à associer à la couche. Paramètre obligatoire pour les couches de type WMTS si le paramètre fromcapacity n’est pas activémaxzoom
: paramètre optionnel de type numérique définissant le zoom maximum pour la couche.opacity
: Opacité du fond de carte . Valeur numérique de 0 à 1. Défaut = 1.
Exemple
1 2 3 4 5 6 7 8 9 | <baselayer
type="OSM"
id="osm1"
label="OpenStreetMap"
title="OpenSTreetMap"
thumbgallery="img/basemap/osm.png"
url="http://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution="Données : les contributeurs d'<a href='http://www.openstreetmap.org/' target='_blank'>OpenStreetMap </a>, <a href='http://www.openstreetmap.org/copyright' target='_blank'>ODbL </a>"
visible="true"/>
|
Configurer - Les thématiques¶
La configuration des thématiques qui seront visibles dans l’interface se fait dans le fichier config.xml.
Principe général¶
Ici, les couches <configlayers> sont organisées de la manière suivante :
- une couche (layer) est intégrée à un groupe ou à un thème,
- un groupe est intégré à un thème et peut contenir entre 1 et n couches,
- un thème est intégré au parent « themes » et peut contenir entre 1 et n groupes ainsi que 1 et n couches,
- le parent « themes » peut contenir entre 1 et n thème.
Ceci peut être résumé avec l’arborescence suivante :
1 2 3 4 5 6 7 8 9 10 11 | <themes>
<theme>
<layer> </layer>
</theme>
<theme>
<group>
<layer> </layer>
<layer> </layer>
</group>
</theme>
</themes>
|
Structure par défaut¶
Par défaut, le contenu suivant est proposé :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <themes>
<theme name="Population" collapsed="false" id="habitant" icon="group">
<layer id="rp_struct_pop_geom" name="Densité de population (hab/km²)" visible="false" tiled="false"
searchable="false" queryable="false" attributefilter="true" attributefield="level" attributevalues="Commune,EPCI,Pays" attributelabel="Échelle" attributestylesync="true" attributefilterenabled="true" infopanel="bottom-panel" infoformat="application/vnd.ogc.gml" featurecount="5" timefilter="true" timeinterval="year" timecontrol="slider" timemin="1999" timemax="2013" timevalues="1999,2008,2013" style="rphab_densite@commune" stylesalias="" url="http://ows.region-bretagne.fr/geoserver/rb/wms" attribution="Sources: INSEE (RP) - OpenStreetMap | Traitements: Région Bretagne - Service connaissance, observation, planification et prospective" metadata="http://kartenn.region-bretagne.fr/geonetwork/?uuid=26324529-e0b7-450c-9506-2dcdca608f5f" metadata-csw="http://kartenn.region-bretagne.fr/geonetwork/srv/eng/csw?SERVICE=CSW&VERSION=2.0.2&REQUEST=GetRecordById&elementSetName=full&ID=26324529-e0b7-450c-9506-2dcdca608f5f">
</layer>
</theme>
<theme name="Environnement" collapsed="false" id="environnement" icon="leaf">
<layer id="reserve_naturelle_regionale" name="Réserves naturelles régionales" visible="false" tiled="false" searchable="false" queryable="true" fields="axe" aliases="axe" infoformat="application/vnd.ogc.gml" featurecount="20" sld="http://kartenn.region-bretagne.fr/styles/reserve_naturelle.sld" url="http://ows.region-bretagne.fr:80/geoserver/rb/wms" legendurl="http://kartenn.region-bretagne.fr/doc/icons_region/reserve_naturelle.svg" attribution="Source: Région Bretagne" metadata="https://geobretagne.fr/geonetwork/apps/georchestra/?uuid=77f8fc52-ae57-41d1-8f08-7b121b013f51" metadata-csw="https://geobretagne.fr/geonetwork/srv/eng/csw?SERVICE=CSW&VERSION=2.0.2&REQUEST=GetRecordById&elementSetName=full&ID=77f8fc52-ae57-41d1-8f08-7b121b013f51" >
<template url="templates/global.reserve_naturelle_reg.mst"></template>
</layer>
</theme>
<theme name="Éducation" collapsed="false" id="education" icon="graduation-cap">
<layer id="lycee" name="Lycées" visible="false" tiled="false" searchable="false" queryable="true" fields="axe" aliases="axe" attributefilter="true" attributefield="secteur_li" attributevalues="Public,Privé sous contrat avec l'éducation nationale" attributelabel="Filtre" attributestylesync="false" attributefilterenabled="false" infoformat="application/vnd.ogc.gml" featurecount="20" sld="http://kartenn.region-bretagne.fr/styles/lycee_secteur.sld" url="http://ows.region-bretagne.fr/geoserver/rb/wms" attribution="Source: Région Bretagne" metadata="http://kartenn.region-bretagne.fr/geonetwork/?uuid=99e78163-ce9a-4eee-9ea0-36afc2a53d25" metadata-csw="http://kartenn.region-bretagne.fr/geonetwork/srv/eng/csw?SERVICE=CSW&VERSION=2.0.2&REQUEST=GetRecordById&elementSetName=full&ID=99e78163-ce9a-4eee-9ea0-36afc2a53d25" >
<template url="templates/global.lycee.mst"></template>
</layer>
</theme>
<theme name="Transports" collapsed="false" id="transport" icon="bus">
<group name="Transport ferroviaire" id="grp1" >
<layer id="troncon_ferroviaire" name="Lignes ferroviaires" visible="false" tiled="false" searchable="false" queryable="true" fields="axe" aliases="axe" infoformat="application/vnd.ogc.gml" featurecount="20" style="ligne_ferroviaire_defaut" stylesalias="Par défaut" url="http://ows.region-bretagne.fr/geoserver/rb/wms" attribution="Source: Région Bretagne" metadata="http://kartenn.region-bretagne.fr/geonetwork/?uuid=0da27e88-4da6-423e-ba4c-dbcad9128cd2" metadata-csw="http://kartenn.region-bretagne.fr/geonetwork/srv/eng/csw?SERVICE=CSW&VERSION=2.0.2&REQUEST=GetRecordById&elementSetName=full&ID=0da27e88-4da6-423e-ba4c-dbcad9128cd2">
<template url="templates/transport.ligne_ferroviaire.mst"></template>
</layer>
<layer id="arret_ferroviaire" name="Arrêts ferroviaires régionaux" visible="false" tiled="false" searchable="true" queryable="true" fields="" aliases="" infoformat="application/vnd.ogc.gml" featurecount="20" style="arret_ferroviaire_defaut, arret_ferroviaire_nature" stylesalias="Par défaut,Nature des arrêts ferroviaires" legendurl="http://kartenn.region-bretagne.fr/doc/icons_region/gare_ter.svg" url="http://ows.region-bretagne.fr/geoserver/rb/wms" attribution="Source: Région Bretagne" metadata="http://kartenn.region-bretagne.fr/ geonetwork/?uuid=4a9d13f7-17be-4a98-9f8f-907cf223072f" metadata-csw="http://kartenn.region-bretagne.fr/geonetwork/srv/eng/csw?SERVICE=CSW&VERSION=2.0.2&REQUEST=GetRecordById&elementSetName=full&ID=4a9d13f7-17be-4a98-9f8f-907cf223072f" >
<template url="templates/global.arret_ferroviaire.mst"></template>
</layer>
</group>
<group name="Transport maritime" id="grp2" >
<layer id="gare_maritime" name="Gares maritimes" visible="false" tiled="false" searchable="false" queryable="true" fields="axe" aliases="axe" infoformat="application/vnd.ogc.gml" featurecount="20" sld="http://kartenn.region-bretagne.fr/styles/gare_maritime.sld"
url="https://geobretagne.fr/geoserver/dreal_b/ows" legendurl="http://kartenn.region-bretagne.fr/doc/icons_region/gare_maritime.svg" attribution="Source: DREAL Bretagne"
metadata="https://geobretagne.fr/geonetwork/apps/ georchestra/?uuid=ffcb4e72-a01b-44f0-8da3-95a5b13c6e42" metadata-csw="https://geobretagne.fr/geonetwork/srv/eng/csw?SERVICE=CSW&VERSION=2.0.2&REQUEST=GetRecordById&elementSetName=full&ID=ffcb4e72-a01b-44f0-8da3-95a5b13c6e42" >
<template url="templates/global.gare_maritime.mst"></template>
</layer>
<layer id="port" name="Ports" visible="false" tiled="false" searchable="false" queryable="true" fields="axe" aliases="axe" infoformat="application/vnd.ogc.gml" featurecount="20" sld="http://kartenn.region-bretagne.fr/styles/port.sld" url="http://ows.region-bretagne.fr:80/geoserver/rb/wms" legendurl="http://kartenn.region-bretagne.fr/doc/icons_region/port.svg" attribution="Source: Région Bretagne" metadata="https://geobretagne.fr/geonetwork/apps/georchestra/?uuid=c55c4fba-6a37-48ea-8754-a1bf770a684b" metadata-csw="https://geobretagne.fr/geonetwork/srv/eng/csw?SERVICE=CSW&VERSION=2.0.2&REQUEST=GetRecordById&elementSetName=full&ID=c55c4fba-6a37-48ea-8754-a1bf770a684b" >
<template url="templates/global.port.mst"></template>
</layer>
</group>
</theme>
<theme name="Découpages territoriaux" collapsed="true" id="territoire" icon="globe">
<layer id="commune" name="Commune" visible="false" queryable="false" fields="nom_geo" aliases="Nom" type="customlayer" style="" opacity="1" legendurl="img/legend/commune.png" url="customlayers/commune.js" tooltip="true" attribution="Source: GéoBretagne" metadata="https://geobretagne.fr/geonetwork/apps/ georchestra/?uuid=b08e6cb1-236c-49b7-88f9-42b500d274d5" metadata-csw="https://geobretagne.fr/geonetwork/srv/eng/csw?SERVICE=CSW&VERSION=2.0.2&REQUEST=GetRecordById&elementSetName=full&ID=b08e6cb1-236c-49b7-88f9-42b500d274d5"/>
<layer id="epci" name="Intercommunalité" visible="true" queryable="false" fields="nom_geo" aliases="Nom" customcontrol="true" type="customlayer" style="" opacity="1" legendurl="img/legend/epci.png" url="customlayers/epci.js" tooltip="true" tooltipenabled="true" attribution="Source: GéoBretagne" metadata="https://geobretagne.fr/geonetwork/apps/ georchestra/?uuid=2298d744-49cb-4fcb-9487-26f916fecdff" metadata-csw="https://geobretagne.fr/geonetwork/srv/eng/csw?SERVICE=CSW&VERSION=2.0.2&REQUEST=GetRecordById&elementSetName=full&ID=2298d744-49cb-4fcb-9487-26f916fecdff"/>
</theme>
</themes>
|
Ici, ce code .xml peut être résumé à l’arborescence suivante :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <themes>
<theme name="Population">
<layer name="Densité de population (hab/km²)"> </layer>
</theme>
<theme name="Environnement">
<layer name="Réserves naturelles régionales"> </layer>
</theme>
<theme name="Éducation">
<layer name="Lycées"> </layer>
</theme>
<theme name="Transports">
<group name="Transport ferroviaire">
<layer name="Lignes ferroviaires"> </layer>
<layer name="Arrêts ferroviaires régionaux"> </layer>
</group>
<group name="Transport maritime">
<layer name="Gares maritimes"> </layer>
<layer name="Ports"> </layer>
</group>
</theme>
<theme name="Découpages territoriaux">
<layer name="Commune"> </layer>
<layer name="Intercommunalité"> </layer>
</theme>
</themes>
|
Ce qui donne visuellement ceci :

Configuration de la liste des thèmes¶
Syntaxe <themes>
¶
1 | <themes mini="" legendmini="" />
|
Paramètres
mini
: paramètre optionnel de type booléen (true/false) qui précise si le panneau de gauche est réduit à l’ouverture de l’application. L’attributcollapsed
des<theme>
doit être à true pour que cet attribut soit pris en compte. Défaut = false.legendmini
: paramètre optionnel de type booléen (true/false) qui précise si le panneau de la légende est réduit à l’ouverture de l’application. Défaut = true.
Syntaxe <theme>
¶
Elément enfant de <themes>
1 | <theme name="" collapsed="" id="" url="" icon="" />
|
Paramètres
name
studio : paramètre obligatoire de type texte qui précise le nom de la thématique.id
studio : paramètre obligatoire de type texte qui affecte un identifiant unique interne à la thématique.url
studio : URL de la thématique. Des thèmes externes (présents dans d’autres configurations peuvent être automatiquement chargés par référence au fichier xml utilisé (url=) et à l’id de la thématique (id=). Attention si la configuration externe est sur un autre domaine, il faut alors que mviewer utilise un proxy Ajax ou alors s’assurer que CORS est activé sur le serveur distant. Les thématiques externes peuvent utiliser des ressources particulières (templates, customLayer, sld…) si les URLs de ces ressources sont absolues et accessibles.collapsed
studio : paramètre optionnel de type booléen (true/false) qui précise si la thématique est fermée au démarrage de l’application. Pour que la thématique soit ouverte au démarrage, il faut choisir l’option false. Attention, il ne peut y avoir qu’une thématique ayant ce paramètre à false. Valeur par défaut true.icon
studio : paramètre optionnel de type texte qui précise l’icône à utiliser afin d’illustrer la thématique. Les valeurs possibles sont à choisir parmi cette liste : http://fontawesome.io/icons/
Syntaxe <group>
¶
Elément enfant de <theme>
1 | <group name="" />
|
Paramètres
name
: paramètre obligatoire de type texte qui précise le nom du groupe.
Configurer - Les couches¶
Syntaxe <layer>
¶
Élément enfant de <theme>
ou <group>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <layer id=""
name=""
scalemin=""
scalemax=""
visible=""
owsoptions=""
tiled=""
queryable=""
fields=""
aliases=""
type=""
filter=""
searchable=""
searchid=""
fusesearchkeys=""
fusesearchresult=""
useproxy=""
secure=""
authentification=""
authorization=""
toplayer=""
exclusive=""
infoformat=""
infohighlight=""
featurecount=""
style=""
stylesalias=""
timefilter=""
timeinterval=""
timecontrol=""
timevalues=""
timemin=""
timemax=""
attributefilter=""
attributefield=""
attributevalues=""
attributeoperator=""
attributestylesync=""
attributelabel=""
attributefilterenabled=""
opacity=""
legendurl=""
dynamiclegend=""
vectorlegend=""
nohighlight=""
url=""
attribution=""
tooltip=""
tooltipcontent=""
tooltipenabled=""
expanded=""
metadata=""
metadata-csw="" >
<template url=""></template>
</layer>
|
Paramètres pour une configuration minimaliste¶
name
studio : paramètre obligatoire de type texte qui précise le nom de la couche.url
studio : paramètre obligatoire de type URL (URL du service web).id
studio : paramètre obligatoire de type texte qui renseigne l’identifiant technique de la couche côté serveur WMS ou WFS.
Paramètres pour gérer l’affichage de la couche¶
scalemin
studio : Échelle minimum de la couchescalemax
studio : Échelle maximum de la couchedynamiclegend
: Booléen précisant si la légende est liée à l’échelle de la carte et si elle nécessite d’être actualisée à chaque changement d’échelle de la carte.visible
studio : Booléen stipulant est ce que la couche est actuellement visibleexclusive
: Booléen stipulant si la couche est exclusive. Si la valeur est « true », l’affichage de cette couche masquera automatiquement toutes les autres couches ayant ce paramètre activé.style
studio : Style(s) de la couche. Si plusieurs styles , utiliser la virgule comme séparateur. Si la couche est de type wms, il faut faire référence à un style sld. Si la couche est de type geojson, il faut faire référence à un style définit dans lib/featurestyles.js. Si la couche est de type customlayer, le style n’est pas défini ici.stylesalias
studio : Titres à utiliser pour chaques style. utiliser la virgule comme séparateur si plusieurs styles.sld
studio : Lien vers un SLD stocké sur le web. Dans ce fichier SLD, la balise sld:Name contenue dans sld:NamedLayer doit être égale au nom de la couche. Si plusieurs styles , utiliser la virgule comme séparateur. S’applique uniquement aux layers WMS. Il faut indiquer l’URL résolvable par le serveur WMS du ou des sld.tiled
studio : Booléen stipulant est ce que la couche est tuiléeopacity
studio : Opacité de la couche (1 par défaut)legendurl
studio : url permettant de récupérer la légende. Si non défini, c’est un GetLegendGraphic qui est effectué.filter
studio : Expression CQL permettant de filtrer la couche ex: insee=35000 Ou INTERSECT(the_geom, POINT (-74.817265 40.5296504)) [tutorial] (http://docs.geoserver.org/stable/en/user/tutorials/cql/cql_tutorial.html#cql-tutorial)toplayer
: Précise si la couche demeure figée. Booléen. Défaut = true.expanded
studio : Booléan précisant si le panneau de la couche est agrandi au démarrage. La valeur par défaut est false.
Paramètres pour gérer attributions et métadonnées¶
attribution
studio : Copyright de la couche. Le mot-clé « metadata » permet de récupérer cette information depuis des métadonnées compliantes au Dublin Core (champs « source »).metadata
studio : Lien vers la fiche de metadonnées complètemetadata-csw
studio : Requête CSW pour l’affiche dans la popup du détail de la couche. Mviewer récupère également la date de création ou dernière mise à jour si cela est en Dublin Core.
Paramètres pour gérer l’interrogation et la mise en forme de la fiche d’interrogation de la couche¶
queryable
studio : Booléen stipulant est ce que la couche est intérrogeable via un GetFeatureInfoinfoformat
studio : Format du GetFeatureInfo. 2 formats sont supportés : text/html et application/vnd.ogc.gmlinfohighlight
: Booléen précisant si les features de la couche sont mises en surbrillance en interrogeant leurs informations, défaut = true. Si false un markeur est affiché.featurecount
studio : Nombre d’éléments retournés lors de l’interrogationfields
studio : Si les informations retournées par l’interrogation est au format GML, fields représente les attributs à parser pour générer la vignettealiases
studio : Si les informations retournées par l’interrogation est au format GML, aliases représente le renommage des champs parsés.
Paramètres pour gérer la recherche¶
searchable
: Booléen précisant si la couche est interrogeable via la barre de recherchesearchengine
: elasticsearch|fuse. Défault=elasticsearch.searchid
: Nom du champ à utiliser côté WMS afin de faire le lien avec l’_id elasticsearchiconsearch
: Lien vers l’image utilisée pour illustrer le résultat d’une recherche ElasticSearchfusesearchkeys
: Chaîne de caractères contenant la liste des champs de la couche à indexer pour la recherche. Les noms des champs doivent être séparés par des virgules. À n’utiliser que si searchengine = fuse.fusesearchresult
: Chaîne de caractères décrivant l’information à afficher dans les résultats de recherche. Cette chaîne contient soit le nom d’un champ de la couche soit un template Mustache combinant plusieurs noms de champs. Exemple : « {{name}} ({{city}}) ». A n’utiliser que si searchengine = fuse
Paramètres pour les couches non WMS¶
type
: Type de la couche (wms|geojson|kml|customlayer|import) default=wms. Si customlayer est défini, il faut instancier un Layer OpenLayers dans un fichier javascript ayant pour nom l’id de la couche (voir « Configurer - Une recherche Fuse »). Ce fichier js doit être placé dans le répertoire customlayers/
Pour le type import l’extension fileimport doit être activée.
* tooltip
: Pour les couches de type vecteur uniquement. Booléen précisant si les entités de la couche sont affichées sous forme d’infobulle au survol de la souris. (Les infobulles ne fonctionnent qu’avec une seule couche à la fois). Valeur par défaut = false.
* tooltipenabled
: Précise la couche prioritaire pour l’affichage des infobulles.
* tooltipcontent
: Chaîne de caractères décrivant l’information à afficher dans les infobulles. Cette chaîne contient soit le nom d’un champ de la couche soit un template Mustache (code html) combinant plusieurs noms de champs. Exemple : tooltipcontent="{{name}} - ({{city}})"
.
Note
Il est possible d’utiliser du code HTML pour mettre en forme la tooltip.
Exemple : {{name}} </br> {{city}}
.
En HTML, </br>
permet d’effectuer un saut de ligne, ce qui nous permet ici d’avoir une tooltip sur 2 lignes. Attention, cette expression doit être convertie en une expression compatible XML, c’est à dire avec le code HTML échappé.
Il existe des outils en ligne pour cela.
L’expression valide pour l’expression précédente est :
tooltipcontent="{name}} </br> {{city}}"
vectorlegend
: Booléen précisant si la légende pour les couches de type vecteur (customlayer ou import) est dynamiquement crééenohighlight
: Booléen précisant, pour les couches de type vecteur (customlayer, geojson ou import), si la mise en surbrillance du hover est désactivée
Paramètres pour gérer la dimension temporelle des couches WMS¶
timefilter
: Booléen précisant si la dimension temporelle est activée pour cette couche. Voir (http://docs.geoserver.org/latest/en/user/services/wms/time.html)timeinterval
: day|month|yeartimecontrol
: calendar|slider|slider-rangetimevalues
: valeurs séparées par des virgules - À utiliser avec le controle slider pour des valeurs non régulières ex (1950, 1976, 1980, 2004).timemin
: Date mini format : « yyyy-mm-dd »timemax
: Date maxi format : « yyyy-mm-dd »
Paramètres pour gérer le filtre attributaire (liste déroulante) des couches WMS¶
attributefilter
studio : Booléen précisant si on active la sélection attributaire par menu déroulantattributefield
studio : Nom du champ à utiliser avec le contrôle attributefilter.attributevalues
studio : valeurs séparées par des virgules.attributelabel
: Texte à afficher pour la liste déroulante associée.attributestylesync
: Booléen qui précise s’il convient d’appliquer un style (sld) spécifique lors du filtre attributaire. Dans ce cas la convention est la suivante : nom_style@attributevalue ou url_style_externe@attributevalue.sld.attributefilterenabled
: Booléen précisant si le filtre est activé par défaut (avec la première valeur de la liste attributevalues).attributeoperator
: guilabel:studio : Opérateur utilisé pour construire le filtre. (= ou like). Defaut = « = ». Attention dans le cas de like, le wildcard est harcodé : %
Autres paramètres¶
customlayer
: Texte précisant le nom du fichier JavaScript permettant la création d’une couche ou bien l’url complet du fichier JavaScript.URL renseignée
: le fichier JavaScript (.js) correspondant à l’URL est chargéNom du fichier renseigné
: l’URL est fabriquée automatiquement à partir de l’ID de la couche. Le fichier devra être dans le répertoire customLayers/layerid.js (ou layerid correspond à l’id de la couche)
customcontrol
: Booléen précisant si la couche dispose d’un addon html à intégrer. La valeur par défaut est false.Valeur renseignée
: le fichier JavaScript (.js) correspondant à l’url est chargéValeur non renseignée
: l’url est fabriquée à partir de l’ID de la couche (ex: custom:ayers/layerid.js)
customcontrolpath
: Texte Précisant le répertoire hébergeant les fichiers nécessaires au contrôle. Dans ce pépertoire, il faut déposer un fichier js et un fichier html ayant pour nom l’id de la couche. La structure du js doit être la suivante : (../controls/epci.js). Valeur par défaut = customcontrols.secure
studio : Texte précisant le niveau de protection de la couche Les valeurs possibles sont :public
: (ou paramètre absent), l’accès à la couche est publicglobal
: l’accès à la couche est contrainte par le CAS geoserver. Un test est effectué pour savoir si la couche est accessible. Si ce n’est pas le cas, la couche est retirée du panneau et de la carte.layer
: l’accès à la couche nécessite une authentification sur le service (WMS). Un bouton « cadenas » est ajouté dans la légende pour cette couche. Au clic sur ce bouton, un formulaire est affiché permettant de saisir des identifiants d’accès qui seront envoyés à chaque appel au service.authorization
: Permet d’indiquer des identifiants par défaut si secure est à « layer »useproxy
studio : Booléen précisant s’il faut passer par le proxy ajax (nécessaire pour fixer les erreurs de crossOrigin lorsque CORS n’est pas activé sur le serveur distant.owsoptions
: Pour une couche WMS, permet de forcer certains paramètres des requêtes GetMap. Exemple : « VERSION:1.1.1,EXCEPTIONS:application/vnd.ogc.se_inimage ».
Syntaxe <template>
¶
Elément enfant de <layer>
- Cet élément optionnel, permet d’associer un template type Mustache (https://github.com/janl/mustache.js) à la fiche d’information de la couche.
- Pour fonctionner, il faut que le paramètre
infoformat
ait la valeur « application/vnd.ogc.gml ». Le template peut être un fichier statique ex templates/template1.mst ou directement saisi dans le noeud <template> avec les balises <![CDATA[ ]]>.
1 | <template url="" />
|
Paramètres
url
: paramètre optionnel de type url qui indique l’emplacement du template à utiliser.
Configurer - La recherche¶
Recherche d’adresse via olscompletion¶
Liens vers service d’autocomplétion et de géocodage d’adresses.
Syntaxe
1 | <olscompletion url="" type="" attribution="" />
|
Attributs
url
: Url du service d’autocomplétion d’adressetype
: Optional - Type de service utilisé geoportail ou ban - defaut = geoportailattribution
: Attribution du service de geocodage
Recherche d’entités¶
2 possibilités sur mviewer :
Paramétrage des recherches¶
Options liées à la recherche d’adresse (olscompletion) et à la recherche d’entitées (elasticsearch ou fuse).
Syntaxe
1 2 3 4 5 6 7 8 9 10 11 12 13 | <searchparameters
imgurl=""
imgwidth=""
svgcolor=""
bbox=""
inputlabel=""
localities=""
features=""
static=""
querymaponclick=""
closeafterclick=""
animate=""
duration=""/>
|
Attributs
bbox
(optionnel) : Recherche d’adresse et/ou d’entitées dans l’emprise de la carte : true ou false (defaut = false),localities
(optionnel) : Utilisation du service d’adresse olscompletion : true ou false (defaut = true),features
(optionnel) : Utilisation du service de recherche d’entitées elasticsearch ou fuse : true ou false (defaut = true),static
(optionnel) : En lien avec le paramètre doctypes. Active ou désactive la recherche associée à des documents requêtés systématiquement, indépendamment des couches affichées : true ou false (defaut = false),inputlabel
(optionnel) : Texte à utiliser pour le placeholder de la zone de saisie de la barre de recherche. default = « Rechercher »,querymaponclick
(optionnel) : Interroge la carte après sélection d’un résultat : true ou false - defaut = false,closeafterclick
(optionnel) : Ferme la liste des résultats de recherche après avoir sélectionné un item : true ou false - defaut = false,animate
(optionnel) : Active ou désactive l’animation de la vue lorsqu’un résultat de recherche est sélectionné : true ou false (defaut = false),duration
(optionnel) : Durée en ms de l’animation définie dans l’option “animate” (defaut = 1000).imgurl
(optionnel) : Url de l’image PNG / JPEG à afficher à l’emplacement du résultat sélectionné en guise de pointeur.imgwidth
(optionnel) : Taille de l’image (voir paramètre imgurl) du pointeur représentant le résultat sélectionné.svgcolor
(optionnel) : Couleur du pointeur représentant la localisation du résultat sélectionné.

Activation de l’option animate.
Configurer - Une recherche basée sur un index Elasticsearch¶
Permettre d’interroger un index Elasticsearch à partir d’une saisie libre (exemple « Port de Brest »). Le résultat retourné est une collection de documents disposant d’un champ commun avec les entités géographiques servies par l’instance WMS/WFS. Par convention les types elasticsearch ont le même nom que les couches WMS/WFS.
Prérequis¶
Installer une instance Elasticsearch https://www.elastic.co/fr/downloads/elasticsearch.
Création d’un index¶
créer un index nommé mviewer avec un champ de type geo_shape nommé geometry et un champ de type keyword nommé id.
Pour celà, depuis le serveur hôte hébergeant l’instance Elasticsearch, lancer la commande CURL suivante :
$ curl -XPUT 'localhost:9200/mviewer?pretty' -d '{
"template": "mviewer",
"settings": {
"number_of_shards": 1
},
"mappings": {
"_default_": {
"properties": {
"geometry": {
"type": "geo_shape",
"tree": "quadtree",
"precision": "10m"
},
"id": {
"type": "keyword"
}
}
}
}
}'
Alimenter l’index avec des données¶
Il existe plusieurs mode d’alimentation. Un des plus connus consiste en l’utilisation de logstash https://www.elastic.co/downloads/logstash. et du plugin jdbc https://www.elastic.co/guide/en/logstash/current/plugins-inputs-jdbc.html. permettant d’indexer des données provenant de bases de données.
Une autre méthode consiste à utiliser l’API d’indexation d’Elasticsearch https://www.elastic.co/guide/en/elasticsearch/reference/5.6/docs-bulk.html. via une commande CURL et un fichier contenant les instructions et données d’indexation et les données. Le fichier démo lycee permet de rapidement alimenter un index avec les données des lycées bretons.
Télécharger le fichier lycee http://kartenn.region-bretagne.fr/doc/lycee.bulk.json. et exécuter la commande suivante.
$ curl -s -H "Content-Type: application/x-ndjson" -XPOST 'http://localhost:9200/_bulk' --data-binary "@lycee.bulk.json"
Tester l’index¶
Si tout s’est bien déroulé, la commande suivante doit renvoyer deux lycées :
$ curl -XGET 'localhost:9200/mviewer?q=zola&pretty'
Connecter mviewer à cet index Elasticsearch¶
Il est conseillé de n’exposer que l’API de recherche (_search) sur le web. Imaginons qu’une configuration serveur expose sur le web “localhost:9200/mviewer/_search” en “http://monserveur/els/_search”
En partant de la démo Elasticsearch : http://kartenn.region-bretagne.fr/kartoviz/demo/els.xml, modifier le fichier de configuration pour que l’application pointe sur l’index Elasticsearch précédemment créé.
Syntaxe
1 | <elasticsearch url="http://monserveur/els/_search" geometryfield="geometry" linkid="search_id" querymode="match"/>
|
Attributs
url
: Url de l’API Searchgeometryfield
: Nom du champ utilisé par l’instance elasticsearch pour stocker la géométrielinkid
: Nom du champ à utiliser côté serveur wms/wfs pour faire le lien avec la propriété _id des documents elasticsearchquerymode
(optionnel) : Query mode used by elasticsearch to find results : match ou term ou phrase - default = match. Le mode match convient pour la recherche libre et naturelle. Le mode phrase permet de faire des recherches sur une phrase et le mode terme permet de faire une recherche sur un terme exact. Il est à noter que l’utilisateur peut activer le mode terme en préfixant sa recherche de # et activer le mode phrase en encadrant sa recherche de « ».doctypes
(optionnel) : types des documents elasticsearch à requêter systématiquement, indépendamment des couches affichéesversion
(optionnel) : version de l’instance elasticsearch (exemple = 5.3)
Tester en Lançant http://monserveur/mviewer/?config=demo/els.xml et saisir zola dans la barre de recherche.
Configurer - Une recherche Fuse¶
Présentation de Fuse¶
Fuse permet de rechercher une entité dans la barre de recherche sans installer de solution lourde. Il est adapté à un nombre limité d’entités.
Création du fichier javascript¶
Il est nécessaire de créer un fichier javascript pour utiliser la recherche Fuse. La donnée apparaît sur la carte au format vectoriel.
Ce fichier devra :
- son nom et le nom de la variable déclarée au début être le même que le nom de la couche
- la donnée issue de la requête WFS devra être dans la même projection que le mviewer (ici 4326)
- le style de la couche s’appuie sur openLayer (https://openlayers.org/workshop/fr/vector/style.html)
Voici un exemple de fichier javascript pour une donnée ponctuelle (fichier auto_ecole.js)
{
mviewer.customLayers.auto_ecole = {};
var auto_ecole = mviewer.customLayers.auto_ecole;
// Génération de la liste des légendes
auto_ecole.legend = {items: [{
geometry: "Point",
label: "Auto Ecole",
styles: [new ol.style.Style({
image: new ol.style.Circle({
fill: new ol.style.Fill({
color: "#ff2a00"
}),
stroke: new ol.style.Stroke({
color: "#ff2a00",
width: 4
}),
radius: 4
})
})]
}]
};
// Appel de la source de donnée (attention à la projection) et affichage du style sur la carte
mviewer.customLayers.auto_ecole.layer = new ol.layer.Vector({
source: new ol.source.Vector({
url: "https://geobretagne.fr/geoserver/dreal_b/wfs?SERVICE=WFS&VERSION=1.0.0&REQUEST=GETFEATURE&TYPENAME=auto_ecole&outputFormat=application/json&srsName=EPSG:4326",
format: new ol.format.GeoJSON()
}),
style: function(feature, resolution) {
return auto_ecole.legend.items[0].styles;
}
});
mviewer.customLayers.auto_ecole.handle = false;
}
Vous trouverez d’autres exemples ici
Configuration dans le XML¶
Au niveau du fichier de configuration mviewer, il est nécessaire de faire les adaptations suivantes au niveau de la couche :
type="customlayer" vectorlegend="true" url="https://geobretagne.fr/pub/mviewer-formation/exemples/customlayers/auto_ecole.js"
searchable="true" searchengine="fuse" fusesearchkeys="NOM" fusesearchresult="{{NOM}} - {{TYPE}}" fusesearchthreshold="0.5"
type
: mettre customlayervectorlegend
: activer l’affichage de la légende saisie dans le fichier javascripturl
: url du fichier javascriptsearchable
: activer la recherchesearchengine
: activer le mode de recherche fusefusesearchkeys
: champ dans lequel on va effectuer la recherche. Possible sur plusieurs champs (exemple : « NOM,TYPE »)fusesearchresult
: expression d’affichage du résultat de la recherchefusesearchthreshold
: optionnel, cette valeur permet de préciser si la recherche doit retourner des résultat très proches de la saisie (0) ou tout mot ou partie de mot qui correspond (1)
Configurer - Le proxy¶
Lien vers votre proxy permmettant l’interrogation CROSS DOMAIN des couches. Mviewer n’est pas fourni avec un proxy Ajax. L’application peut fonctionner avec le proxy de GeorChestra. Un proxy cgi peut être utilisé. Plus de détail ici
Syntaxe
1 | <proxy url="" />
|
Attributs
url
: Url vers votre proxy
Configurer - Extensions¶
Chargement de librairies javascripts externes ou de composants personnalisés. Ce module d’extension permet de répondre à deux cas d’usage :
- J’ai besoin d’une librairie javascript (chart.js) pour faire mes templates de couche.
- J’ai besoin de créer un nouveau composant (mini carte de localisation) sans modifier le cœur de mviewer. Plus de précisions ici : « Configurer - Custom Component »
Syntaxe
1 2 3 4 | <extensions>
<extension type="javascript" src=""/>
<extension type="component" id="" path=""/>
</extensions>
|
Paramètres pour les extensions de type javascripts
src
: paramètre obligatoire qui correspond à l’URL vers le fichier.
Paramètres pour les extensions de type component
id
: paramètre obligatoire qui correspond au nom du dossier du composant.path
: paramètre obligatoire qui correspond à l’URL vers le dossier contenant la structure su composant.
Exemple
1 2 3 4 | <extensions>
<extension type="javascript" src="chart.js"/>
<extension type="component" id="graph3d" path="demo/addons"/>
</extensions>
|
Configurer - Apparence¶
Pour configurer l’apparence de mviewer, vous avez la possibilité de changer le style présent dans un fichier .css.
Par défaut, une liste de .css est fournie dans le dossier /css/themes/

Changer l’apparence¶
Pour changer l’apparence (et donc le .css associé) de mviewer, il vous suffit d’éditer le fichier index.html et de modifier l’adresse du fichier .css à la ligne suivante (n°49).
var style = "css/themes/default.css";
Par défaut, le fichier associé est css/themes/default.css.

Remarque¶
À noter qu’un fichier themes_css_kartenn.pdf permet de visualiser à l’avance le rendu de chacun des thèmes proposés.
Configurer - Templates¶
Personnalisation de la fiche d’information
Pour les couches de type vecteur et WMS, il est possible de définir un template afin de formater côté client, la fiche d’information des entités sélectionnées. Le moteur de template (logic less) utilisé est Mustache : https://github.com/janl/mustache.js
Exemple de template structuré¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | {{#features}}
<li id="{{feature_ol_uid}}" class="item">
Exemple de formatage
<h3 class="title-feature">{{nom}}</h3>
<img src="{{image}}" class="img-responsive" style="margin-top:5%;" /><br/>
<p class="text-feature">
<b> Surface : </b> {{surface}} ha <br/>
</p>
<a href="{{url}}" target="_blank" title="Lien site internet" class="but-link">
<span class="fa fa-globe" aria-hidden="true"></span> <b>Site Web</b>
</a>
</li>
{{/features}}
<style>
.title-feature {
color: #BA88A4;
font-family:"Trebuchet MS";
font-size:20px;
margin-bottom:3%;
line-height:1;
}
.text-feature{
font-family:"Trebuchet MS";
color:#555;
font-size:13px;
margin-top:2%;
margin-bottom:2%;
}
.but-link, .but-link:focus, .but-link:hover{
display:inline-block;
padding:0.5em 1em;
margin:0 0.3em 0.3em 0;
border-radius:0.3em;
box-sizing: border-box;
text-decoration:none;
font-family:'Trebuchet MS';
font-weight:300;
color:#FFFFFF;
background-color:#BA88A4;
text-align:center;
transition: all 0.2s;
}
.but-link:hover{
background-color:#b0006b;
}
</style>
|
Les éléments en rouge sont obligatoires.
Explications : {{#features}}{{/features}}
est une boucle effectuée sur chaque entité présente dans la couche sélectionnée.
<li id="{{feature_ol_uid}}" class="item"></li>
est une entrée de liste html utilisée par le mviewer. S’il y a plusieurs entrées de liste car plusieurs entités sélectionnées, le mviewer présentera les réponses sous la forme d’un carousel.
Pour synchroniser le carousel et la sous-sélection sur la carte lors d’un clic, l’injection de la feature_ol_uid
est requise dans l” id
de la balise.
Puisque une feature id
n’est pas obligatoire comme attribut pour une feature l” ol_uid
interne d’OpenLayers est utilisée à ce propos.
Ce qu’il faut savoir de Mustache¶
- On fait référence à la valeur d’un champ de cette façon :
{{champ}}
. - Il est possible de gérer une absence de valeur ou une valeur false de cette façon :
1 2 3 | {{#champ2}}
Ce texte s'affiche si champ2 contient une valeur ou est différent de false.
{{/champ2}}
|
La finalité du template est ici de fabriquer un contenu formaté HTML. L’ajout des balises <style> permet de personnaliser l’affichage du champ via du CSS. Exemple ici sur le formatage du texte et d’un bouton pour clic.
Pour aller plus loin sur la personnalisation, consulter les différentes documentation sur HTML et CSS.
Nous avons la possibilité d’injecter du code via la balise <script>.
Résultat de l’exemple ci-dessus¶

Itérer sur les champs disponibles¶
En plus d’afficher la valeur d’un champ comme expliqué précédemment, il est aussi possible de lire et parcourir l’ensemble des champs disponibles avec {{#fields_kv}}...{{/fields_kv}}
.
Pour chaque champ listé, on peut accéder :
- au nom du champ via
{{key}}
- à la valeur via
{{value}}
Par exemple, ce code :
1 2 3 4 5 6 7 8 9 | {{#features}}
<li id="{{feature_ol_uid}}" class="item" style="width:238px;">
<ul>
{{#fields_kv}}
<li>{{key}} : {{value}}</li>
{{/fields_kv}}
</ul>
</li>
{{/features}}
|
affichera la liste des champs avec leur nom suivi de leur valeur sans avoir à connaître les noms des champs à l’avance.
Dans le même ordre d’idée, un autre « champ virtuel », {{serialized}}
, permet de récupérer l’ensemble des champs sous forme sérialisée, prête à être passée en paramètre dans une URL. Par exemple, dans une iframe:
1 | <iframe class="iframe_bottom"src="apps/myapp/presentation/en/pages/mylayer_charts.html?data={{serialized}}"></iframe>
|
Vous pourrez ensuite le désérialiser de façon standard. Par exemple, en javascript dans le fichier mylayer_charts.html (cf. exemple ci-dessus) :
<script>
var url = new URL(location.href);
var data = url.searchParams.get("data");
if(data) {
var obj = JSON.parse(data)
keys = Object.keys(obj);
for ( i=0 ; i<keys.length ; i++ ) {
key=keys[i];
console.log(key + ': '+obj[key]);
}
...
}
</script>
Les champs {{#fields_kv}}
et {{serialized}}
sont tous les deux virtuels : ils sont créés grâce à une fonctionnalité de Mustache permettant de définir des champs comme des fonctions.
S’ils ne sont pas utilisés, ils ne consomment pas de ressource.
Ils ont été ajoutés aux champs simples afin de faciliter certains flux de traitement des données.
Appel depuis le XML¶
Le template sera enregistré au format mst. Pour l’appeler dans la configuration mviewer au niveau de la layer, il faut le bon format infoformat="application/vnd.ogc.gml"
et ajouter un appel au mst via une balise template au sein du layer <template url=""/>
.
Débug erreurs courantes¶
Dans cette page nous mettrons des exemples de bug récurrents dans le mviewer et la façon de les résoudre.
- Légende non disponible

A venir…
A venir…
- Je n’arrive pas à interroger ma couche
Ce problème peut venir de plusieurs facteurs.
Bien vérifier le infoformat. Pour rappel 2 possibilités :
- text/html : fichiers FTL GeoServer
- application/vnd.ogc.gml : fichiers mustache ou utilisations de fields et aliasfields
Vérifier sur votre serveur carto (GeoServer, MapServer…) que votre couche est interrogeable.
- Je ne vois pas mon thème
L’identifiant unique de mon thème n’est pas unique. Pour corriger, changer l’identifiant du thème invisible. Même principe pour un groupe de couche.
Configurer - Traduction¶
Cette parge vous servira à comprendre et mettre en place les éléments pour traduire le mviewer.
Fonctionnement technique¶
Librairies Le mviewer utilise la libraire i18n.js pour traduire l’interface vers le langage de votre choix.
Principe
La traduction s’appuie sur un dictionnaire de traduction (fichier mviewer.i18n.json). Tous les éléments html disposant d’un attribut i18n seront traduits si une correspondance est trouvée dans le dictionnaire:
<span i18n="une.cle.a.traduire"> une valeur par défaut </span>
Le fichier mviewer.i18n.json est structuré pour utiliser plusieurs langues de traduction:
{
"fr": {
"une.cle.a.traduire": "une valeur en français",
"une.autre.cle": "une autre valeur en français"
},
"en": {
"une.cle.a.traduire": "a value",
"une autre cle": "another value"
}
}
Pour trouver la valeur à traduire, le système recherchera donc la clé contenue dans l’attribut « i18n » de notre élément de la page dans la langue sélectionnée:
<span i18n="search.adresse"> une valeur par défaut </span>
// donnera pour le français
"une.cle.a.traduire": "une valeur en français"
La valeur traduite sera ensuite appliquée sur l’élément de la page à la place de la valeur par défaut.
Le texte affiché pour notre élément de la page (<span>) sera alors:
"une valeur en français"
Quels sont les paramètres de configuration utilisés ?¶
Il vous faudra ajouter dans votre fichier de configuration les propriétés suivantes comme décrit dans la page mviewer:
- lang
Langue à utiliser pour l’interface. Si plusieurs langues sont spécifiées, un menu additionnel sera créé afin de permettre à l’utilisateur de choisir sa langue a première langue de la liste saisie sera alors utilisée par défaut. Par défaut, lang n’est pas activé.
- langfile
URL du fichier de traduction supplémentaire à utiliser en complément de mviewer.i18n.json. Ce fichier peut être un fichier distant (URL classique type https://) ou bien un fichier localisé n’importe où dans votre serveur web.
Voici un exemple:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<application title="Une belle carte" langfile="./custommviewer.i18n.js" lang="en,fr"></>
Vous pouvez donc changer de langue via l’URL directement. Essayez en premier avec cette url:
Maintenant rajoutez
lang=fr
http://kartenn.region-bretagne.fr/kartoviz/?config=demo/lang.xml&lang=fr
Interface de changement de langue¶
Sélecteur de langue
Selon votre paramètre lang le mviewer vous permettra de sélectionner parmis les valeurs de traduction disponibles.
Avec « lang=fr » ou aucun paramètre « lang » vous n’ajouterez pas cette interface. Avec lang=en,fr vous pourrez modifier la langue dans l’interface du mviewer.
Affichage du sélecteur
Deux types d’affichage existent:
Une liste de sélection:
<application lang="en,fr" langfile="demo/demo.i18n.json"/> .. image:: ../_images/dev/config_translate/list_lang.png :alt: lang selector :align: center
Dans cette configuration, la liste de sélection sera remplacée par une popup pour les petits écrans (mobiles et tablettes).
Cette fenêtre sera accessible via la barre de navigation en haut.
Dans la fenêtre d’aide en ajoutant le paramètre showhelp= »true » dans la configuration de l’application:
<application lang="en,fr" langfile="demo/demo.i18n.json" help="demo/demo_lang_help.html" showhelp="true"/>
Les langues seront visibles ainsi :
Comment insérer vos traductions ?¶
1 - Créez un fichier de traduction au format JSON ou compléter le fichier mviewer.i18n.json déjà disponible
Nous recommandons de créer un nouveau fichier. Le fichier mviewer.i18n.js sera ainsi surchargé (= complété) par votre fichier de traduction.
2 - Insérez les traductions dans le fichier en respectant ce formalisme:
{
"fr": {
"popup.help.title": "Bienvenu"
},
"en": {
"popup.help.title": "Welcome"
},
"bzh": {
"popup.help.title": "Degemer mat"
}
}
3 - Pour du nouveau contenu HTML, rajoutez l’attribut i18n=”popup.help.title” pour que le contenu soit traduit et rajoutez les nouvelles clés dans votre fichier de traduction:
<span i18n="search.adresse"> une valeur par défaut </span>
4 - Ajoutez les paramètres lang=”en,fr,bzh” et langfile=”./chemin/fichier/traduction”
5 - Eventuellement, choissisez d’afficher le sélecteur de langue dans la popup d’aide avec le paramètre showhelp=”true”
6 - Testez
Configurer - Custom layer¶
Un custom layer est une couche personnalisée s’appuyant sur la librairie openlayers
. Exemples
- J’ai besoin d’afficher une couche de type KML.
- J’ai besoin de créer une couche de type cluster avec une analyse personnalisée
- J’ai besoin d’une couche de tuiles vectorielles OSM…
Syntaxe
<layer id="moncustomlayer"
type="customlayer"
url="chemin_vers_customlayer.js">
</layer>
Paramètres custom layer
type="customlayer"
: paramètre précisant qu’il s’agit d’une couche de type customlayer.url
: paramètre qui indique où mviewer doit charger le fichier customlayer.js.
Exemple
<layer id="heatmap"
name="Earthquakes Heatmap"
visible="true"
queryable="true"
url="demo/heatmap/customlayer.js"
type="customlayer"
legendurl="demo/heatmap/legend.png"
opacity="1"
expanded="true"
attribution=""
metadata=""
metadata-csw="">
</layer>
Configurer - Custom control¶
Un custom control est une interface permettant à l’utilisateur d’interagir avec une couche. Le customcontrol est affiché dans le bloc de légende associée à la couche concernée.
Un custom control est associé à une seule couche et est constitué de deux fichiers html + javascript. Ces deux fichiers doivent obligatoirement être nommé comme l” id
de la couche associée.
Exemples
- J’ai besoin d’une liste déroulante pour filtrer ma couche.
- J’ai besoin d’une zone de saisie pour filtrer ma couche
Syntaxe
<layer id="moncustom"
customcontrol="true"
customcontrolpath="chemin_vers_fichiers">
</layer>
Paramètres custom control
customcontrol
: paramètre qui indique si mviewer doit charger un customcontrol. valeurs : true || false. Défaut = false.customcontrolpath
: paramètre qui indique où mviewer doit charger le customcontrol. Si ce paramètre n’est pas renseigné, le customcontrol est recherché dans le répertoire racine customcontrols.
Exemple
<layer id="heatmap"
name="Earthquakes Heatmap"
visible="true"
url="demo/heatmap/customlayer.js"
queryable="true"
type="customlayer"
customcontrol="true"
customcontrolpath="demo/heatmap/control"
legendurl="demo/heatmap/legend.png"
opacity="1"
expanded="true"
attribution=""
metadata=""
metadata-csw="">
</layer>
Configurer - Custom Component¶
Pour quoi faire ?¶
On utilise les composants personnalisés pour modifier l’apparence de mviewer, ajouter des fonctionnalités, rajouter des librairies sans modifier le coeur de Mviewer. De cette façon, le Mviewer est ainsi plus facile à maintenir.
Il est ainsi possible de créer un composant très simple pour :
- afficher un logo dans une zone particulière
- ajouter un nouveau bouton dans la barre de navigation mviewer
- Créer un sélecteur temporel qui répercutera la sélection à l’ensemble des couches…
Les composants apportent donc plus de souplesse pour personnaliser vos Mviewer selon vos besoins.
Qui peut réaliser un composant ?¶
Tout le monde peut réaliser un composant à condition d’être un petit peu familier avec la configuration mviewer et d’avoir des notions en JavaScript. Une fois votre premier composant réaliser, il vous sera très facile d’en réaliser de nouveaux.
Comment faire ?¶
Un composant personnalisé - customComponent - est un dossier physique disposant d’un fichier obligatoire config.json
qui identifie toutes les ressources à charger. Les ressources sont de 3 types :
html
–> html à chargercss
–> feuille de style à chargerjs
–> liste de fichiers javascripts à charger
Exemple d’arborescence :
/demo
├── components
│ ├── 3d
│ │ ├── js
│ │ │ ├── lib.js
│ │ │ └── main.js
│ │ │
│ │ ├── config.json
│ │ ├── component.html
│ │ ├── style.css
│ │
│ ├── autre_customComponent
Exemple de fichier config.json :
1 2 3 4 5 6 7 8 9 10 11 12 13 | {
"js": [
"js/lib.js",
"js/main.js"
],
"css": "style.css",
"html": "component.html",
"target": "map",
"options": {
"title": "3D",
"position": 0,
}
}
|
Le composant sera alors créé dans une div mviewer existante ciblée par le paramètre target. Par défaut le composant est ajouté comme dernier noeud enfant du target dans le DOM. Le paramètre optionnel position permet de changer cette position et ajouter le composant comme enfant n du target.
Voici un extrait de la configuration xml :
1 2 3 4 5 | <config>
<extensions>
<extension type="component" id="3d" path="demo/components"/>
</extensions>
</config>
|
Exemples¶
Afin de mieux comprendre ce que fait un composant et pour vous en inspirer, voici des exemples de niveau simple et avancé.
- Ajouter un logo.
Ce composant permet d’ajouter un logo dans votre Mviewer. Pour vous approprier facilement les composant, vous pouvez commencer par observer et reproduire ce premier composant avec votre propre composant.
- Réaliser un graphique en 3D
Ce composant permet de créer un graphique en 3D avec des boutons et iterfaces de contrôle. Ce composant montre que l’on peut vraiment importer des librairies externes et afficher ce que l’on souhaite dans l’interface Mviewer.
- Filtrer les données dans une fenêtre flottante
Ce composant permet de créer une fenêtre qui contiendra des filtres sur la couche de votre choix. Ici, nous utilisons une librairie externes pour ajouter une fenêtre flottante qui n’existe pas nativement dans le Mviewer.
Ce composant permet ainsi de rajouter une fonctionnalité de filtre sur les données qui n’existe pas nativement dans le Mviewer.
Documentation dévelopeur¶
Cette partie est dédiée aux personnes qui souhaite développer des fonctionnalités pour mviewer.
Développer avec mviewer¶
Note
Mviewer est développé en javascript
et utilise les librairies suivantes :
Chapitres abordés¶
- Intro : Les grands principes de mviewer
- Partie 1 : « Développer ses propres composants ».
- Partie 2 : Découvrir « Les fonctions publiques de mviewer ».
Les grands principes de mviewer¶
MVIEWER s’appuie sur les 2 principes suivants :
Chargements à la demande¶
mviewer s’initialise avec un fichier de configuration - config.xml. Ce fichier contient les paramétrages nécessaires à l’application ainsi que les ressources utiles à charger :
- Résumé des fiches de métadonnées - .xml
- templates de couche personnalisés - .mst
- fichier d’aide personnalisé - .html
- feuille de style personnalisée - .css
- données - (formats multiples)
- extensions - .js
- composants personnalisés ( .js .css .html )
Tout est personnalisable¶
Si mviewer est avant tout une application aux nombreux paramétrages possibles, il peut être nécessaire de personnaliser l’interface voire de créer des couches personnalisées avec leurs propres contrôles (liste déroulante, slider, calendrier…) Les couches personnalisées sont par exemple nécessaires pour appliquer une analyse thématique sur une source de données de type vecteur ou développer un nouveau type d’intéraction entre l’utilisateur et une source de données (mise à jour par exemple).
- La mise en forme de la fiche d’information des données « Configurer - Templates »
- La représentation des données servies par WMS - SLD
- Une couche personnalisée - javascript
- un contrôle personnalisé - javascrip + html
- un composant personnalisé - javascript + html + css
Développer ses propres composants¶
Il est possible de développer 3 types de composants dans mviewer en s’appuyant sur la le socle natif de mviewer et sans modification de son coeur
Type | Portée | Affichage | Lien |
---|---|---|---|
customLayer | couche identifiée par son id | Carte | détail |
customControl | couche identifiée par son id | Légende de la couche | détail |
customComponent | détail |

Exemple de customlayer heatmap

Exemple de customcontrol heatmap

Exemple de customcomponent 3d
Note
Pour aller plus loin :
Développer un customLayer¶

L’ojectif est ici de créer une couche personnalisée de type heatmap
à partir d’un fichier KML en utilisant la librairie Openlayers
et en s’inspirant de cet exemple. Avant tout, il faut préparer la structure de fichiers qui convient.
/ demo
│
├── heatmap
│ │
│ ├── config.xml
│ ├── customlayer.js
│ ├── legend.png
│ ├── data
│ │ ├── 2012_Earthquakes_Mag5.kml
|
L’exemple complet est disponible sur github.
Ecrire le customLayer¶
Astuce
L’ancienne méthode fonctionne toujours mais est plus verbeuse que la nouvelle. Les 3 lignes mises en surbrillance sont remplacées par une seule ligne, également mise en surbrillance, dans la nouvelle version.
Ancienne méthode¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | //Layerid is the same than the layerid in config.xml
const layerid = "heatmap";
//Create customlayer object
mviewer.customLayers[layerid] = {};
//Create Openlayers heatmap layer
const layer = new ol.layer.Heatmap({
source: new ol.source.Vector({
url: 'demo/heatmap/data/2012_Earthquakes_Mag5.kml',
format: new ol.format.KML({
extractStyles: false
})
}),
blur: 10,
radius: 10,
weight: function(feature) {
var name = feature.get('name');
var magnitude = parseFloat(name.substr(2));
return magnitude - 5;
}
});
// Set the openlayers layer to the customLayer object layer
mviewer.customLayers[layerid].layer = layer;
|
Nouvelle méthode¶
Depuis la version 3.2 de mviewer, une classe CustomLayer
a été développée afin de faciliter la saisie de nouveaux customLayers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | const layer = new ol.layer.Heatmap({
source: new ol.source.Vector({
url: 'demo/heatmap/data/2012_Earthquakes_Mag5.kml',
format: new ol.format.KML({
extractStyles: false
})
}),
blur: 10,
radius: 10,
weight: function(feature) {
var name = feature.get('name');
var magnitude = parseFloat(name.substr(2));
return magnitude - 5;
}
});
new CustomLayer('heatmap', layer);
|
Ecrire le config.xml¶
Dans le fichier de configuration, il faut reprendre l’id du customlayer id="heatmap"
, préciser type="customlayer"
ainsi que l’URL du fichier url="demo/heatmap/customlayer.js"
<layer id="heatmap"
name="Earthquakes Heatmap"
visible="true"
type="customlayer"
legendurl="demo/heatmap/legend.png"
opacity="1"
url="demo/heatmap/customlayer.js"
attribution=""
metadata=""
metadata-csw="">
</layer>
Exemples de customLayers¶
En respectant les consignes détaillées plus haut, voici quelques exemples prêts à l’emploi.
customlayer ArcGis REST Feature¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | {
mviewer.customLayers.test_esri_college_80 = {};
var esrijsonFormat = new ol.format.EsriJSON();
mviewer.customLayers.test_esri_college_80.layer = new ol.layer.Vector({
source: new ol.source.Vector({
url: 'https://services2.arcgis.com/aYGUaoapooTe49i1/arcgis/rest/services/COLLEGES_PUBLICS_avec_Liens/FeatureServer/0/query?where=&objectIds=&time=&geometry=154415%2C6384802%2C345565%2C6494181&geometryType=esriGeometryEnvelope&inSR=3857&spatialRel=esriSpatialRelIntersects&resultType=none&distance=0.0&units=esriSRUnit_Meter&returnGeodetic=false&outFields=*&returnGeometry=true&featureEncoding=esriDefault&multipatchOption=xyFootprint&maxAllowableOffset=&geometryPrecision=&outSR=2154&datumTransformation=&applyVCSProjection=false&returnIdsOnly=false&returnUniqueIdsOnly=false&returnCountOnly=false&returnExtentOnly=false&returnQueryGeometry=false&returnDistinctValues=false&cacheHint=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&having=&resultOffset=&resultRecordCount=&returnZ=false&returnM=false&returnExceededLimitFeatures=true&quantizationParameters=&sqlFormat=none&f=pjson&token=',
format: esrijsonFormat
}),
style: new ol.style.Style({
image: new ol.style.Circle({
fill: new ol.style.Fill({
color: 'rgba(255, 118, 117,1.0)'
}),
stroke: new ol.style.Stroke({
color: "#ffffff",
width: 4
}),
radius: 9
})
})
});
mviewer.customLayers.test_esri_college_80.handle = false;
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | let esrijsonFormat = new ol.format.EsriJSON();
const layer = new ol.layer.Vector({
source: new ol.source.Vector({
url: 'https://services2.arcgis.com/aYGUaoapooTe49i1/arcgis/rest/services/COLLEGES_PUBLICS_avec_Liens/FeatureServer/0/query?where=&objectIds=&time=&geometry=154415%2C6384802%2C345565%2C6494181&geometryType=esriGeometryEnvelope&inSR=3857&spatialRel=esriSpatialRelIntersects&resultType=none&distance=0.0&units=esriSRUnit_Meter&returnGeodetic=false&outFields=*&returnGeometry=true&featureEncoding=esriDefault&multipatchOption=xyFootprint&maxAllowableOffset=&geometryPrecision=&outSR=2154&datumTransformation=&applyVCSProjection=false&returnIdsOnly=false&returnUniqueIdsOnly=false&returnCountOnly=false&returnExtentOnly=false&returnQueryGeometry=false&returnDistinctValues=false&cacheHint=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&having=&resultOffset=&resultRecordCount=&returnZ=false&returnM=false&returnExceededLimitFeatures=true&quantizationParameters=&sqlFormat=none&f=pjson&token=',
format: esrijsonFormat
}),
style: new ol.style.Style({
image: new ol.style.Circle({
fill: new ol.style.Fill({
color: 'rgba(255, 118, 117,1.0)'
}),
stroke: new ol.style.Stroke({
color: "#ffffff",
width: 4
}),
radius: 9
})
})
});
new CustomLayer('test_esri_college_80', layer);
|
Développer un customControl¶
Les Customs Controls permettent de créer des interactions entre l’utilisateur et un layer. Si on souhaite créer une nouvelle fonctionnalité en lien avec une couche particulière, c’est la solution à privilégier. Le mécanisme de customControl permet le développement à façon de solution nouvelle sans modifier le coeur de mviewer.
Convention
Un custom control consiste en deux fichiers - javascript et html. Ces deux fichiers doivent impérativement respecter la règle de nommage suivante :
- layerid.html
- layerid.js
- où layerid correspond à l’id du layer tel que définit dans le config.xml.
L’emplacement de ces fichiers doit être précisé dans le config.xml avec le paramètre
customcontrolpath=""

Ecrire le code - html¶
Le bloc écrit en HTML s’affichera dans le panneau légende associé à la couche. Il est possible de créer des éléments html qui permettront à l’utilisateur d’interagir avec la couche associée. Dans l’exemple suivant, on affiche deux sliders qui vont nous permettre de modifier dynamiquement l’affichage de notre couche.
<form>
<label>radius size</label>
<input id="heatmap-radius" class="" type="range" min="1" max="50" step="1" value="10"/>
<label>blur size</label>
<input id="heatmap-blur" type="range" min="1" max="50" step="1" value="10"/>
</form>
Ecrire le code - javascript¶
Ancienne méthode¶
La ligne 2 surlignée indique la notation propre à l’ancienne méthode.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | const layerid = "heatmap";
mviewer.customControls[layerid] = (function() {
/*
* Private
*/
var _initialized = false;
var _layer;
var _blurElement = false;
var _radiusElement = false;
var _blurHandler = function(e) {
_layer.setBlur(parseInt(e.target.value, 10));
};
var _radiusHandler = function(e) {
_layer.setRadius(parseInt(e.target.value, 10));
};
return {
/*
* Public
*/
init: function () {
// mandatory - code executed when layer is added to legend panel
if (!_initialized) {
_layer = mviewer.getLayer(layerid).layer;
_blurElement = document.getElementById('heatmap-blur');
_radiusElement = document.getElementById('heatmap-radius');
if (_blurElement && _radiusElement) {
_blurElement.addEventListener('change', _blurHandler);
_radiusElement.addEventListener('change', _radiusHandler);
_initialized = true;
}
}
},
destroy: function () {
// mandatory - code executed when layer panel is closed
_initialized = false;
}
};
}());
|
Nouvelle méthode¶
Depuis la version 3.2 de mviewer, une classe CustomControl
a été développée afin de faciliter la saisie de nouveaux customControls. Les 2 lignes surlignées (2, 51) indiquent les lignes modifiées par rapport à l’ancienne méthode.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | const layerid = "heatmap";
const cc = (function() {
/*
* Private
*/
var _initialized = false;
var _layer;
var _blurElement = false;
var _radiusElement = false;
var _blurHandler = function(e) {
_layer.setBlur(parseInt(e.target.value, 10));
};
var _radiusHandler = function(e) {
_layer.setRadius(parseInt(e.target.value, 10));
};
return {
/*
* Public
*/
init: function () {
// mandatory - code executed when layer is added to legend panel
if (!_initialized) {
_layer = mviewer.getLayer(layerid).layer;
_blurElement = document.getElementById('heatmap-blur');
_radiusElement = document.getElementById('heatmap-radius');
if (_blurElement && _radiusElement) {
_blurElement.addEventListener('change', _blurHandler);
_radiusElement.addEventListener('change', _radiusHandler);
_initialized = true;
}
}
},
destroy: function () {
// mandatory - code executed when layer panel is closed
_initialized = false;
}
};
}());
new CustomControl(layerid, cc.init, cc.destroy);
|
Avertissement
Si on souhaite disposer d’un bloc de code publique, il faut remplacer la ligne
const cc = (function() {
par var cc = (function() {
Ecrire le config.xml¶
Dans le fichier de configuration, à partir de l’exemple customLayer heatmap, il faut ajouter les 3 lignes mises en surbrillance.
<layer id="heatmap"
name="Earthquakes Heatmap"
visible="true"
url="demo/heatmap/customlayer.js"
queryable="true"
type="customlayer"
customcontrol="true"
customcontrolpath="demo/heatmap/control"
legendurl="demo/heatmap/legend.png"
opacity="1"
expanded="true"
attribution=""
metadata=""
metadata-csw="">
</layer>
Développer un Custom component¶

L’ojectif est ici de créer un bouton dont la fonction est d’afficher la carte en mode « plein écran » en utilisant l’API html 5 requestFullscreen
.
/ demo/addons
│
├── fullscreen
│ │
│ ├── config.json
│ ├── fullscreen.js
│ ├── fullscreen.html
│ ├── style.css
L’exemple complet est disponible sur github.
Ecrire le code html¶
Le code html est la partie visible du composant. Le code html sera intégré par mviewer et « dessiné » dans la div
ciblée via le fichier config.json.
Dans le cas présent on créé un simple bouton avec une icône fontawesome;
<a class="btn btn-default btn-raised" type="button" id="fullscreen-btn">
<span class="fas fa-expand"></span>
</a>
Ecrire le code javascript¶
Le code javascript est la partie logique de notre composant. Dans lexemple ci-dessous, on associe une fonction à l’évènement click
du bouton créé précédemment.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | const fullscreen = (function() {
var _btn;
var _fullscreen = function (e) {
document.getElementById("map").requestFullscreen();
};
return {
init : function () {
_btn = document.getElementById("fullscreen-btn");
_btn.addEventListener('click', _fullscreen);
}
};
})();
new CustomComponent("fullscreen", fullscreen.init);
|
Avertissement
Si on souhaite disposer d’un bloc de code publique, il faut remplacer la ligne
const fullscreen = (function() {
par var fullscreen = (function() {
Ecrire le code css¶
Le code css permet d’affiner le style de notre bouton.
#fullscreen-btn {
border-radius: 0px;
padding: 5px 10px 5px 10px;
}
Ecrire le config.json¶
Dans le fichier de configuration - config.json - , il faut référencer toutes les ressources utiles. le paramètre target
permet de cibler la div
dans laquelle le composant sera affiché.
{
"js": ["fullscreen.js"],
"css": "style.css",
"html": "fullscreen.html",
"target": "toolstoolbar"
}
Les fonctions publiques de mviewer¶
Pour accéder à ces fonctions publiques il faut simplement utiliser l’objet mviewer
et accéder à une fonction (mviewer.nomDeLaFonction()
).
Il existe déjà les fonctions suivantes :
-
mviewer
-
getActiveBaseLayer
()¶ Renvoie: L’id du baselayer (couche de fond visible).
-
setBaseLayer
(id)¶ Paramètres: id (string) – Id du layer Renvoie: Affiche le baselayer correspondant à l’id.
-
getLayer
(layerid)¶ Paramètres: layerid (string) – Id du layer Renvoie: La configuration du layer. -
getLayer(layerid).layer
Renvoie: Le layer (ol.Layer) du layerid.
-
-
getMap
()¶ Renvoie: La map (ol.Map).
-
toggleLayer
(layerid)¶ Paramètres: layerid (string) – Id du layer Renvoie: Affiche/masque le layer correspondant au layerid.
-
removeAllLayers
()¶ Renvoie: Masque toutes les couches.
-
showLocation
(projection, x, y)¶ Paramètres: Renvoie: Affiche une punaise sur les coordonnées entrées.
-
tr
()¶ Renvoie: Traduit dans la langue courante de mviewer une valeur de type machaine.a.traduire
(cf Configurer - Traduction) .
-
Appronfondir - Custom Layer¶
Les Customs Layers permettent de personnaliser la représentation et les interactions que l’on a avec les layers de façon plus avancée que ce que l’on peut faire avec le fichier de configuration XML.
Dans chacune des deux méthodes présentées dans la suite de cette page les customs layers ont pour base commune la classe CustomLayer
présente dans le fichier custom.js
.
Les méthodes suivantes sont à utiliser dans le fichier maLayer.js
qui est dans l’arborescence suivante :
/apps
├── ma_carte1
│ ├── addons
│ │ ├── couche1
│ │ │ ├── control
│ │ │ └── layer
│ │ │ └── malayer.js
│ │ └── couche2
│ │ ├── control
│ │ └── layer
│ ├── data
│ ├── css
│ ├── sld
│ ├── img
│ ├── templates
│ └── ma_carte1.xml
└── ma_carte2
Première Méthode : Définition Simple¶
Cette solution permet de rapidement mettre en place un custom layer mais ne permet pas de travailler avec des variables ou des méthodes privées.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // Définition de la couche représentant le custom layer
const aerial = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + key,
maxZoom: 20
})
});
// Votre code ici
...
/* Créer le custom layer à partir du code ci-dessus */
// Le custom layer aura pour id "monCustomLayer" et pour couche aerial définit dans l'exemple
new CustomLayer("monCustomLayer", aerial);
|
Tous les paramètres de la classe CustomLayer
ne sont pas nécessaires seul l’ID et la couche (layer) sont indispensables.
Ajouter des fonctions et des variables¶
Une fonction privée ne sera pas accessible en dehors du code de la classe alors qu’une fonction publique sera accessible depuis n’importe où ce qui peut entrainer des conflits avec d’autres fonctions de l’application si l’on ne fait pas attention.
Pour les variables et fonctions de classe publique¶
Il faut définir un nouvel attribut pour la classe CustomControl
de la manière suivante :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ...
// Initialiser l'objet avec les fonctions init() et destroy() et l'id de couche "monLayer".
var monLayer = new CustomLayer("monLayer",aerial);
// Une fois créé on peut ajouter des propriétés (une propriété peut être une fonction ou une variable)
// Ajouter une fonction
monLayer.maNouvelleFonction = function(){
// Votre Code ici
...
}
// Ajouter une variable
monLayer.maNouvelleVariable = "je suis un exemple";
|
Ces attributs seront alors publics et accessibles depuis l’extérieur.
Deuxième Méthode : Création d’une sous-classe¶
La création d’une sous-classe permet de mieux structurer le code et de faciliter l’ajout de fonctions et variables privées sans avoir à modifier la classe parent CustomLayer
. Ell se présente comme suit :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | const aerial = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + key,
maxZoom: 20
})
});
// Classe qui étend la classe 'CustomLayer' et décrit le custom Layer
class MonCustomLayer extends CustomLayer {
// Initialiser le custom layer
constructor(id, layer, legend, handle = false) {
// Initialiser les attributs de la classe parent
super(id, layer, legend, handle);
}
}
// Créer le Custom Layer
new MonCustomLayer("monCustomLayer",aerial);
|
La classe MonCustomLayer
hérite de la classe CustomLayer
et doit donc utiliser le constructor()
parent pour créer un objet en spécifiant au minimum l’ID et la layer.
Ajouter des fonctions et des variables¶
Pour empêcher de potentiels bugs on peut ajouter à la classe MonCustomLayer
(vue dans la partie précédente) des fonctions privées ou publiques.
Une fonction privée ne sera pas accessible en dehors du code de la classe alors qu’une fonction publique sera accessible depuis n’importe où ce qui peut entraîner des conflits avec d’autres fonctions de l’application si l’on ne fait pas attention.
Pour les variables et fonctions de classe publique¶
Directement en ajoutant dans le code de la classe MonCustomLayer
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // Classe qui étend la classe et décrit le custom Layer
class MonCustomLayer extends CustomLayer {
constructor(id, layer, legend, handle = false, nouvelleVariable) {
// Initialiser les attributs de la classe parent
super(id, layer, legend, handle);
// Ajout d'une variable publique qui prend en valeur le paramètre de constructor "nouvelleVariable"
this.nouvelleVariable = nouvelleVariable;
}
maFonctionPublique(){
// Votre code ici
...
}
}
// Créer l'objet layer avec l'id 'monLayer' qui est le nom de la couche
new MonCustomLayer("monLayer",aerial);
|
Cette fonction sera appelable grâce à monobjet.maFonctionPublique()
et l’on peut bien sûr y passer des paramètres.
Concernant la variable elle est de la même façon accessible grâce à monobjet.nouvelleVariable
.
Pour les variables et fonctions de classe privée¶
Une fonction privée est définie en dehors du code de la classe MonCustomLayer
et déclarée comme une constante
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // Fonction privée non utilisable en dehors de ce code
const maFonctionPrivée = function(){
// Votre code ici
...
}
// Classe qui étend la classe et décrit le custom Layer
class MonCustomLayer extends CustomLayer {
...
maFonctionPublique(){
maFonctionPrivée();
// Votre code ici
...
}
}
// Créer l'objet layer avec l'id 'monLayer' qui est le nom de la couche
new MonCustomLayer("monLayer",aerial);
|
Cette fonction sera appelable grâce à maFonctionPrivée()
seulement dans ce bout de code et donc on peut par exemple l’utiliser dans une fonction publique (ici maFonctionPublique()
).
Pour ajouter une variable de classe privée il faut ajouter le « # » avant le nom de la variable et la déclarer avant la fonction constructor()
:
...
// Classe qui étend la classe et décrit le custom Layer
class MonCustomLayer extends CustomLayer {
// Déclaration de la variable Privée
#maVariablePrivee;
constructor(id, layer, legend, handle = false,maVariablePrivee = "valeurParDefaut") {
// Initialiser les attributs de la classe parent
super(id, layer, legend, handle);
// Initialiser #maVariablePrivee
this.#maVariablePrivee = maVariablePrivee
...
}
...
}
// Initialiser un objet avec la chaine de caractères "maVariablePrivee" dans la variable de classe privée #maVariablePrivee et l'id de couche "monLayer".
new MonCustomLayer("monLayer",aerial);
Si vous voulez quand pouvoir accéder et modifier la valeur de cette variable en dehors de ce code mais de manière plus sécuriser il faut déclarer une fonction get()
pour récupérer la valeur et une fonction
set(valeur)
pour la modifier :
...
// Classe qui étend la classe et décrit le custom Layer
class MonCustomLayer extends CustomLayer {
// Déclaration de la variable Privée
#maVariablePrivee;
constructor(id, layer, legend, handle = false,maVariablePrivee = "valeurParDefaut") {
// Initialiser les attributs de la classe parent
super(id, layer, legend, handle);
// Initialiser #maVariablePrivee
this.#maVariablePrivee = maVariablePrivee
...
}
// Fonction pour récupérer la valeur de #maVariablePrivee
getMaVariablePrivee(){
return this.#maVariablePrivee;
}
// Fonction pour modifier la valeur de #maVariablePrivee
setMaVariablePrivee(valeur){
this.#maVariablePrivee = valeur;
}
}
// Initialiser un objet avec la chaîne de caractères "maVariablePrivee" dans la variable de classe privée #maVariablePrivee et l'id de couche "monLayer".
new MonCustomLayer("monLayer",aerial);
Interactions customLayer et mviewer¶
Depuis le customLayer il est possible de communiquer et d’interagir avec la carte et d’une façon plus générale avec mviewer. Vous pouvez ainsi mobiliser toutes les méthodes publiques dans votre développement. Pour en savoir plus, consultez, dans la documentation développeur, la partie « Les fonctions publiques de mviewer ».
Appronfondir - Custom Control¶
Les Customs Controls permettent de personnaliser la représentation et les interactions que l’on a avec les layers de façon plus avancée que ce que l’on peut faire avec le fichier de configuration XML.
Voici un exemple, le custom control s’affiche dans la légende en dessous des attributions :

Première méthode : Définition Simple (CustomControl)¶
Cette méthode permet de créer des customs controls plus simples qu’avec la deuxième méthode mais permet moins de personnalisation.
Dans ce cas précis on utilise la classe de base CustomControl
dans le fichier custom.js
.
La classe possède une méthode constructor()
qui prend en paramètre les méthodes init()
et destroy()
que l’on peut définir dans le fichier Javascript (dans cet exemple moncontrol.js
)
présent dans l’arborescence suivante:
/apps
├── ma_carte1
│ ├── addons
│ │ ├── couche1
│ │ │ ├── control
│ │ │ │ ├── moncontrol.html
│ │ │ │ └── moncontrol.js
│ │ │ └── layer
│ │ └── couche2
│ │ ├── control
│ │ └── layer
│ ├── data
│ ├── css
│ ├── sld
│ ├── img
│ ├── templates
│ └── ma_carte1.xml
└── ma_carte2
Pour cela il faut donc définir les deux fonctions en les déclarant avec le mot-clé const pour les rendre inaccessibles depuis le reste de l’application indépendamment du custom control dans lequel elles
sont définies, puis il faudra les donner en paramètre à la classe CustomControl
vue plutôt.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | const init = function() {
// Obligatoire - code exécuté quand le panel est ouvert
// Votre code ici
...
};
const destroy = function() {
// Obligatoire - code exécuté quand le panel se ferme
// Votre code ici
...
}
// Initialiser l'objet avec les fonctions init() et destroy() et l'id de couche "monControl".
new CustomControl("monControl", init, destroy);
|
Ajouter des fonctions et des variables¶
Une fonction/variable privée ne sera pas accessible en dehors du code de la classe alors qu’une fonction/variable publique sera accessible depuis n’importe où ce qui peut entrainer des conflits avec d’autres fonctions/variables de l’application si l’on ne fait pas attention.
Pour les variables et fonctions de classe publique¶
Il faut définir un nouvel attribut pour la classe CustomControl
de la manière suivante :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ...
// Initialiser l'objet avec les fonctions init() et destroy() et l'id de couche "monControl".
var monControl = new CustomControl("monControl", init, destroy);
// Une fois créer on peut ajouter des propriétés (une propriété peut être une fonction ou une variable)
// Ajouter une fonction
monControl.maNouvelleFonction = function(){
// Votre Code ici
...
}
// Ajouter une variable
monControl.maNouvelleVariable = "je suis un exemple";
|
Ces attributs seront alors publics et accessibles depuis l’éxterieur.
Deuxième méthode : Création d’une sous-classe (AdvancedCustomControl)¶
Cette méthode est la plus complète des deux et permet de créer des customs controls plus poussés.
Tous les Custom Control ont une base commune dans le fichier custom.js
où est définie la classe AdvancedCustomControl
.
Pour utiliser cette classe il faut modifier le fichier Javascript (dans cet exemple moncontrol.js
) présent dans l’arborescence suivante:
/apps
├── ma_carte1
│ ├── addons
│ │ ├── couche1
│ │ │ ├── control
│ │ │ │ ├── moncontrol.html
│ │ │ │ └── moncontrol.js
│ │ │ └── layer
│ │ └── couche2
│ │ ├── control
│ │ └── layer
│ ├── data
│ ├── css
│ ├── sld
│ ├── img
│ ├── templates
│ └── ma_carte1.xml
└── ma_carte2
Ce fichier définit une classe qui étend (est un héritier de la classe) la classe AdvancedCustomControl
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // Classe qui étend la classe abstraite et décrit le custom Control
class MonControl extends AdvancedCustomControl {
constructor(id) {
// Initialise l'id de l'objet avec le constructeur parent
super(id);
}
// Obligatoire - ce code est exécuté lors de l'ouverture du panel
init() {
// Votre code ici
...
}
// Obligatoire - ce code est exécuté lors de la fermeture du panel
destroy() {
// Votre code ici
...
}
}
|
La classe AdvancedCustomControl
étant abstraite cela signifie qu’elle nous oblige à redéfinir les fonctions init()
et destroy()
qui sont obligatoires sinon elle nous renvoie une erreur.
De plus la fonction constructor(id)
permet à l’objet d’être initialisé avec la valeur id (obligatoire) lors de la création d’un objet MonControl.
Pour créer cet objet et le rendre disponible au reste de l’application il faut rajouter le code suivant :
1 2 | // Créer l'objet MonControl avec l'id 'monControl' qui est le nom de la couche
new MonControl("monControl");
|
Ajouter des fonctions¶
Pour empêcher de potentiels téléscopage de variables ou de méthodes on peut ajouter à la classe MonControl
(vue dans les parties précendentes) des fonctions privées ou publiques.
Une fonction privée ne sera pas accessible en dehors du code de la classe alors qu’une fonction publique sera accessible depuis n’importe où ce qui peut entrainer des conflits avec d’autres fonctions de l’application si l’on ne fait pas attention.
Pour une fonction publique¶
Directement en ajoutant dans le code de la classe MonControl
:
1 2 3 4 5 6 7 8 9 10 | // Classe qui étend la classe abstraite et décrit le custom Control
class MonControl extends AdvancedCustomControl {
...
maFonctionPublique(){
// Votre code ici
...
}
}
// Créer l'objet control avec l'id 'monControl' qui est le nom de la couche
new MonControl("monControl");
|
Cette fonction sera appelable grâce à monobjet.maFonctionPublique()
et l’on peut bien sûr y passer des paramètres.
Pour une fonction privée¶
En dehors du code de la classe MonControl
et en la déclarant comme une constante
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // Fonction privée non utilisable en dehors de ce code
const maFonctionPrivée = function(){
// Votre code ici
...
}
// Classe qui étend la classe abstraite et décrit le custom Control
class MonControl extends AdvancedCustomControl {
...
maFonctionPublique(){
maFonctionPrivée();
// Votre code ici
...
}
}
// Créer l'objet control avec l'id 'monControl' qui est le nom de la couche
new MonControl("monControl");
|
Cette fonction sera appelable grâce à maFonctionPrivée()
seulement dans ce bout de code et donc on peut par exemple l’utiliser dans une fonction publique (ici maFonctionPublique()
).
Ajouter des variables¶
Pour empêcher de potentiels bugs on peut ajouter à la classe MonControl
(vue dans les parties précendentes) des variables de classe privée ou publique.
Une variable de classe privée ne sera pas accessible en dehors du code de la classe alors qu’une variable de classe publique sera accessible depuis n’importe où ce qui peut entrainer des bugs (modification involontaire de celle-ci) si l’on ne fait pas attention.
Pour une variable de classe publique¶
Pour ajouter une variable de classe publique il faut juste ajouter une propriété à l’objet :
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Classe qui étend la classe abstraite et décrit le custom Control
class MonControl extends AdvancedCustomControl {
constructor(id,maVariablePublique){
// Initialise l'id de l'objet avec le constructeur parent
super(id);
// Initialiser maVariablePublique
this.maVariablePublique = maVariablePublique
...
}
...
}
// Initialiser l'objet avec la chaine de caractères "maVariablePublique" dans la variable de classe publique maVariablePublique et l'id de couche "monControl".
new MonControl("monControl","maVariablePublique");
|
Cette variable est accessible à partir du moment où l’on accède à l’objet (dans le navigateur par exemple).
Si on ne souhaite pas forcément donner une valeur à maVariablePublique
on peut déclarer une valeur par défaut en spécifiant une valeur dans les paramètres de la fonction constructor()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // Classe qui étend la classe abstraite et décrit le custom Control
class MonControl extends AdvancedCustomControl {
// Fonction avec un paramètre ayant une valeur par défaut
constructor(id,maVariablePublique = "valeurParDefaut"){
// Initialise l'id de l'objet avec le constructeur parent
super(id);
// Initialiser maVariablePublique
this.maVariablePublique = maVariablePublique
...
}
...
}
// Initialiser l'objet avec la chaine de caractères par défaut "valeurParDefaut" dans la variable de classe publique maVariablePublique et l'id de couche "monControl".
new MonControl("monControl");
|
La valeur de maVariablePublique
sera toujours « valeurParDefaut » tant que vous ne spécifiez pas d’autres valeurs.
Pour une variable de classe privée¶
Attention
La syntaxe suivante ne fonctionne que sur Chrome pour les autres navigateurs remplacez le « # » par un « _ » et vous n’aurez plus besoin de déclarer la variable.
Pour ajouter une variable de classe privée il faut ajouter le « # » avant le nom de la variable et la déclarer avant la fonction constructor()
:
// Classe qui étend la classe abstraite et décrit le custom Control
class MonControl extends AdvancedCustomControl {
// Déclaration de la variable Privée
#maVariablePrivee;
constructor(id,maVariablePrivee = "valeurParDefaut"){
// Initialise l'id de l'objet avec le constructeur parent
super(id);
// Initialiser #maVariablePrivee
this.#maVariablePrivee = maVariablePrivee
...
}
...
}
// Initialiser un objet avec la chaine de caractères "maVariablePrivee" dans la variable de classe privée #maVariablePrivee et l'id de couche "monControl".
new MonControl("monControl","maVariablePrivee");
Si vous voulez quand même pouvoir accéder et modifier la valeur de cette variable en dehors de ce code mais de manière plus sécuriser il faut déclarer une fonction get()
pour récupérer la valeur et une fonction
set(valeur)
pour la modifier :
// Classe qui étend la classe abstraite et décrit le custom Control
class MonControl extends AdvancedCustomControl {
// Déclaration de la variable Privée
#maVariablePrivee;
constructor(id,maVariablePrivee = "valeurParDefaut"){
// Initialise l'id de l'objet avec le constructeur parent
super(id);
// Initialiser #maVariablePrivee
this.#maVaribalePrivée = maVariablePrivee
...
}
// Fonction pour récupérer la valeur de #maVariablePrivee
getMaVariablePrivee(){
return this.#maVariablePrivee;
}
// Fonction pour modifier la valeur de #maVariablePrivee
setMaVariablePrivee(valeur){
this.#maVariablePrivee = valeur;
}
}
// Initialiser un objet avec la chaine de caractères "maVariablePrivee" dans la variable de classe privée #maVariablePrivee et l'id de couche "monControl".
new MonControl("monControl","maVariablePrivee");
Interactions customLayer et mviewer¶
Depuis le customControl il est possible de communiquer et d’interagir avec la carte et d’une façon plus générale avec mviewer. Vous pouvez ainsi mobiliser toutes les méthodes publiques dans votre développement. Pour en savoir plus, consultez, dans la documentation développeur, la partie « Les fonctions publiques de mviewer ».
Documentation contribution¶
Cette partie est dédiée aux personnes qui ont vocation à contribuer au code mviewer.
Contribuer¶
Cette partie permet de donner des clés pour contribuer à mviewer.
Présentation générale¶
Après un déploiement, mviewer permet nativement d’obtenir une carte fonctionnelle.
Cependant vous pouvez ressentir le besoin de modifier mviewer pour créer vos propres cartes, vos propres fonctionnalités et apporter vos propres styles. Pour y arriver vous vous sentez probablement un peu perdu dans cet ensemble de dossiers et fichiers dont vous ne savez pas lesquels il est pertinent de modifier.
Vous trouverez ici une présentation et des recommandations pour créer vos cartes et vos fonctionnalités sans modifier le cœur (ou presque). Vous obtiendrez un mviewer maintenable et vous n’aurez plus l’appréhension de toucher aux mauvais fichiers.
Le cœur de mviewer¶
Qu’est-ce que c’est ?
C’est l’ensemble des fichiers et dossiers présents nativement sur la page GitHub mviewer.
Quand puis-je le modifier ?
Vous devez éviter de modifier les fichiers natifs du mviewer. En effet, modifier ces fichiers vous empêchera de mettre à jour facilement votre déploiement de mviewer pour prendre en compte une nouvelle version officielle.
Néanmoins, vous pouvez être amené à modifier ces fichiers principalement pour contribuer au développement de l’outil :
- Vous détectez un bogue ou un comportement suspect et vous le corrigez
- Vous créez une évolution sur le cœur (une nouvelle fonctionnalité)
- Vous créez une amélioration du code existant
Dans chacune de ces situations l’intervention sur le cœur de mviewer doit être justifiée par une issue sur GitHub.
Les autres fichiers¶
Pour vos modifications et l’organisation de vos fichiers, nous recommandons de suivre la page « Organisation des fichiers de carte ».
Proposer une modification¶
Pour proposer une correction d’anomalie ou une évolution, vous devez suivre ces étapes :
- Créer une issue sur Github en suivant la page Créer une issue
- Faire un fork du code (si ce n’est pas encore fait) en suivant la page Récupérer les sources (fork)
- Créer une branche portant le numéro de l’issue (ex: issue-2287)
- Apporter vos modifications sur cette branche
- Partager cette branche via l’issue pour que les autres puissent tester et obtenir des conseils ou des avis
- Réaliser une pull request via GitHub en suivant la page Pull Request
La pull request permettra d’importer votre modification dans le code natif. Vous diposerez alors de votre modification de manière native sans vous en préoccuper ultérieurement.
Contribuer à la documentation - Readthedoc¶
Avertissement
La documentation est désormais dans le répertoire docs du dépôt principal mviewer et non plus dans le dépôt mviewer.doc.
Participez à l’amélioration de la documentation en ligne de mviewer.
Respectez le processus de contribution décrit dans la section « Proposer une modification ».
Sources
Les sources de la documentation sont disponibles sur GitHub geobretagne/mviewer, dans le répertoire docs.
Créez une issue sur GitHub
Voir la page « Créer une issue » pour proposer une modification.
Fork
Pour apporter des modifications sur la documentation, vous devrez réaliser un fork vers votre compte organisation de Github. Pour réaliser un fork, dirigez-vous vers l’exemple dans la section « Récupérer les sources (fork) ».

Déployer la documentation en local¶
Prérequis
- Vous devez disposez d’un serveur web type Apache2
Si vous ne connaissez pas Apache, vous pouvez installer facilement XAMPP en suivant l’explicatif « Installer XAMPP (windows) » plus bas.
- Vous devez disposer des droits sur votre ordinateur pour installer python et disposer de pip.
- Avoir réalisé un fork du repository geobretagne/mviewer
- Avoir réalisé un clone de votre fork vers un répertoire local de votre ordinateur :
cd /home/user/pierre/git/
git clone https://github.com/mon_compte_github/mviewer.git
L’URL de votre fork est disponible en cliquant sur « Clone or download »
- Avoir installé python sphinx en suivant la page sphinx :
// debian
apt-get install python3-sphinx
- Disposer de pip (debian) :
// debian
sudo apt install python-pip
pip --version
- Installer le package stemmer (si manquant au build) :
// Debian
sudo apt-get install python-stemmer
// pip
pip install PyStemmer
Actions
- Positionnez-vous dans votre dossier mviewer issu du clone :
cd /home/user/pierre/mviewer
- Vous pouvez apporter des modifications dans le dossier « docs » :
cd /home/user/pierre/mviewer/docs
- Pour rajouter des parties et sous-parties dans le menu de gauche, il vous faudra modifier le fichier index.rst :
/home/user/pierre/mviewer/docs/index.rst
- Rajouter par exemple une partie « Nouvelle partie » en respectant cette syntaxe :
Nouvelle partie
-------------------------------------------------
Nouvelle partie pour tester.
.. toctree::
:hidden:
:maxdepth: 1
:caption: Ici le Titre
doc_test/introduction
doc_test/sous_partie1
doc_test/sous_partie2
- Comme décrit dans la syntaxe précédente, vous devez rajouter un dossier « doc_test » (où « doc_test » est le nom que vous avez choisis)
/home/user/pierre/mviewer/docs/doc_test
- Dans ce dossier, rajoutez les fichiers comme décrits dans l’arborescence :
../mviewer/docs/doc_test/introduction.rst
../mviewer/docs/doc_test/sous_partie1.rst
../mviewer/docs/doc_test/sous_partie2.rst
- Inspirez-vous de l’existant pour comprendre l’organisation des fichiers avec index.rst
- Vous devrez écrire selon une syntaxe particulière. Recherchez dans les fichiers et dans les exemples de cette page pour vous aider.
Ajouter des blocs de code¶
Utilisez la syntaxe suivante (respectez les sauts de ligne) :
mon text::
mon bloc de code
Suite du texte.
Ajouter des puces¶
Utilisez la syntaxe suivante (respectez les sauts de ligne) :
Voici une liste :
- premier tiret
- deuxième tiret
Suite du texte.
Rajouter des images¶
- Ajoutez un dossier dans ../docs/_images tel que :
/home/user/pierre/mviewer/docs/_images/doc_test/
- Ajoutez vos images dans ce dossier et renseignez le chemin de l’image à afficher dans le code tel que :
Voici une image :
.. image:: ../_images/doc_test/image1.png
:alt: description de l'image
:align: center
Suite du texte.
Liste numérotée¶
Utilisez la syntaxe suivante (respectez les sauts de ligne) :
Une liste avec des numéros:
#. Mon premier
#. Mon second
#. ...
Suite du texte.
Référencer une page¶
- Pour créer un point de référence .._reference: que l’ont peut citer comme lien depuis n’importe quelle page (lien interne)
- Utilisez les titres pour afficher le texte à afficher comme référence :
.. _reference:
Page de référence
-----------------
- Appelez la référence affichera « Voir la Page de référence » :
Voir la ":ref:`reference`"
- « Page de référence » sera cliquable pour s’y rendre
Lien, hyperlien¶
Utilisez la syntaxe suivante (respectez les sauts de lignes) :
Ceci est un `lien cliquable <https://github.com/geobretagne/mviewer>`_
Construire et déployer la documentation¶
- Les sources de la documentation sont localisées dans votre dossier git/mviewer/docs crée par le clone (voir plus haut) :
/home/user/pierre/mviewer/docs
- Nous voulons que notre documentation soit construite (build) dans le dossier :
/var/www/mviewer-doc/
- Si vous avez utilisé XAMPP (voir « xampp »::), le dossier cible où sera construite la documentation sera (sous windows) :
C:\xampp\mviewer-doc\
- Nous avons ensuite à passer la commande :
sphinx-build -b html home/user/pierre/mviewer/docs /var/www/mviewer-doc/
- La documentation est maintenant dans le dossier de notre choix :
/var/www/mviewer-doc/
ou pour XAMPP:
C:\xampp\mviewer-doc\
- Déployez la documentation crée via la commande avec Apache2 si vous avez d’autres chemins d’accès
- Avec XAMPP Accédez à la documentation via localhost/mviewer-doc (mviewer-doc étant le nom de dossier que vous avez utilisé)
Faites votre pull request
Retrouvez la procédure décrite dans la partie « Pull Request ».
Installer XAMPP (windows)¶
- Téléchargez XAMPP
- Lancez XAMPP pour afficher l’interface d’administration (GUI)
- Sur la ligne du module « Apache », à droite cliquez sur « Start » au sein des actions
- « Apache » doit passer en vert dans la colonne « Module »
- Cliquez sur « Explorer » dans la colonne tout à droite
- Une fenêtre d’exploration s’affiche (par défaut vers C:xampp)
- Rechercher « htdocs » dans la fenêtre d’exploration
- Créez un dossier « mviewer-doc »
C’est dans le dossier « mviewer-doc » que sera déployée la documentation après la phase de build (voir plus haut).
- Accédez au dossier avec votre navigateur via l’URL :
localhost/mviewer-doc
Documentation¶
Pour obtenir plus d’information sur la syntaxe et sphinx :
Créer une issue¶
Quelques règles pour proposer à la communauté vos modifications, vos nouvelles fonctionnalités et vos corrections sur mviewer.
Règle générale¶
Toute modification du cœur de mviewer doit être proposée à l’aide d’une nouvelle issue sur le Github geobretagne/mviewer..
Pourquoi créer une issue ?¶
D’abord, pour pouvoir intégrer votre modification dans le cœur et maîtriser la maintenance des sources. Si vous modifiez le cœur mviewer de votre instance et que vous souhaitez réalisez une mise à jour, vous aller devoir gérer des conflits. Ce qui ne sera pas le cas si vos modifications sont déjà dans le code de la nouvelle version.
Ensuite, pour vous éviter de réaliser une demande de contribution qui ne sera pas acceptée lors de la revue :
- Le code proposé ne respecte pas le formatage initial
- Vous avez réalisé une contribution qui existe déjà
- Vous proposez un code avec un niveau de complexité trop élevé
- Le fonctionnement ou le code doivent être optimisés
- Une partie de ce que vous proposez fonctionne mais ne peut pas être intégré (dépendances externes non maintenues, mauvaise utilisation du langage, etc…)
- Votre contribution ne peut pas être intégrée dans le cœur, car vous seul en avez l’utilisation
Il y a également d’autres bonnes raisons de créer une issue pour contribuer :
- Partager votre idée et vous aurez probablement des personnes pour la réaliser (intéressant !)
- Avertir d’autres contributeurs que vous travaillez sur un sujet et mutualiser le travail
- Eviter que plusieurs contributeurs travaillent en parallèle sur la même chose
- Permettre d’obtenir des informations pour réaliser ce que vous souhaitez
- Obtenir un avis ou de l’aide sur une idée de contribution et la manière de la réaliser
Où créer une issue ?¶
Il faudra vous rendre sur la page GitHub mviewer. Vous devez disposer d’un compte et vous connecter.
Cliquer ensuite sur « Issue » puis, « New issue ».
Comment créer une issue ?¶
1 - Donner un titre
Le titre doit être court mais explicite. Le titre doit permettre de retrouver facilement votre issue à la lecture.
- Bon : « Ajouter un boutton “Nouvelle issue” »
- Mauvais : « Ajouter un nouveau boutton pour créer une issue aujourd’hui manquant »
2 - Ajouter la description
Il sera obligatoire de formater votre texte grâce au Markdown afin de faciliter la lecture. Notamment pour citer ou mettre en évidence des morceaux de code. Autrement, votre texte risque d’être vite illisible. Voici un exemple de syntaxe Makrdown.
La description peut contenir des images, des liens, des citations ou des morceaux de code.
3 - Surveiller les réponses
Soyez animateur de votre discussion et participez dans les réponses. Sinon, elle sera vite oubliée… Pour citer une personne, utilisez @identifiant_Github. Elle sera avertie par email de votre message.
Qui peux créer une issue ?¶
Tout le monde peut créer une issue à condition de disposer d’un compte GitHub (gratuit).
Travailler avec Git et GitHub¶
Entrenez votre mviewer et facilitez vos contributions en travaillant avec les outils Git et Github.
Présentation générale¶
GitHub est incontournable pour contribuer et découvrir la communauté mviewer. C’est là où vous proposerez vos idées, obtiendrez des informations et les dernières versions mviewer.
Grâce à Git vous pourrez réaliser vos contributions ou obtenir le code source dans votre environnement de travail.
Git propose une multitude d’action pour s’interfacer avec GitHub. Ces actions vous seront plus qu’utiles pour contribuer et maintenir votre mviewer à jour. Nous expliquerons ici l’utilité et les manipulations utiles telles qu’un fork, rebase, commit, pull.
Présentation GitHub¶
GitHub est une plate-forme en ligne de contrôle de version et de collaboration pour le développement. GitHub facilite le travail en équipe via une interface web qui permet d’accéder au dépôt de code Git. GitHub fournit des outils de gestion pour la collaboration.
Présentation Git¶
Git est un outil libre de gestion de version décentralisé pour tout type de projet. Il permet de réaliser des développements sur votre propre dépôt (dépôt = répertoire). Git facilite ensuite la mise en commun du code entre les différents dépôt.
Git historise toutes les modifications afin d’identifier les nouveauté et permettre de revenir dans n’importe quel version précédente.
Présentation Git Flow¶
Qu’est-ce que c’est ?
Git Flow est un workflow (organisation) permettant d’établir une stratégie de base sur la création des branches. Git Flow permet de gérer le travail collaboratif pour gérer les issues (bugs), les features (nouvelles fonctionnalités) et les releases (versions).
C’est le workflow qui a été adopté par les contributeurs Mviewer.
Principes de base
Pour simplifier, le fonctionnement est basé sur 2 branches : master et develop.
Si plusieurs personnes travaillent sur ces deux branches, l’historiques des réalisations (commits) peut vite devenir illisible et les modifications risquent de se court-circuiter (conflits).
L’idée est donc de créer des sous-niveaux de branches :
- Les branches features-xxxx permettent de travailler sur des nouvelles fonctionnalités. Elles sont crées directement à partir de la branche develop et une fois le travail fini, fusionnées vers la branche develop.
- Les branches release-xxxx permettent de faire une mise à jour de la branche master à partir de la branche develop.
- Les branches hotfix-xxxx permettent de publier rapidement (hot) une correction (fix) depuis la branche master. Ces branches seront ensuite fusionnées vers la branche master et develop.

Voici quelques références externes pour vous aider à mieux comprendre Git-Flow:
Fork et Pull¶
Nous avons déjà montré l’utilité et l’utilisation d’un fork et d’un pull sur la page « Bien commencer avec mviewer ».
- Le fork est décrit à la section « Récupérer les sources (fork) »
- Le pull est utilisé à la section « Récupérer les nouveautés de la branche »
Rebase¶
Lorsque vous faites des modifications via des commits sur votre branche de travail d’autres contributeurs modifient le code mviewer avec de nouveaux commits.
Le code de mviewer dans le GitHub GéoBretagne n’a pas connaissance de vos modifications. Tant que vous n’avez pas mis à jour votre branche, votre code ne contient pas les modifications faites sur le GitHub mviewer GéoBretagne (upstream).
Les deux codes ont donc des nouveautés. On peut dire que les branches ont divergé.
Vous devez alors intégrer les nouveautés de mviewer dans une branche de travail contenant vos modifications. Pour rappel, cette branche ne doit pas jamais être la branche master.
Pour cela, nous allons en premier reprendre tous les nouveaux commits du mviewer natif (GéoBretagne) en mettant à jour votre fork (branche master). Ensuite, nous mettrons à jour votre branche de travail depuis la branche master de votre fork.
Dans la pratique, nous placerons les nouveaux commits de la branche master du fork dans l’arbre de commits de votre branche de travail via un rebase.
Mise à jour du fork
Reprenez dans l’ordre les étapes « Définir un upstream » et « Mettre à jour votre fork - master ».
Réalisez ensuite la procédure suivante.
Que fait un Rebase ?
- Git va reprendre le dernier commit commun entre votre branche de travail à mettre à jour et la branche qui contient les nouveautés (master)
- Git replacera ensuite vos commits et les nouveaux commits dans l’ordre chronologique
Vous disposerez donc des nouveaux commits et de vos propres commits.
Comment faire ?
- Faites une copie de votre branche (optionnel mais conseillé) en créant une nouvelle branche à partir de votre branche de travail
- Si votre branche s’appelle par exemple « RM-work », lancez la commande de rebase de la branche master (fork à jour) vers votre branche à mettre à jour (RM-work) :
git rebase origin/master RM-work

- Vous verrez la liste des commits dérouler les messages des commits un à un
- Vous aurez probablement un conflit. Le processus sera donc stoppé mais pas abandonné
- Si vous souhaitez abandonner lancer la commande(*) :
git rebase --abort
- Si vous souhaitez ignorer le conflit (déconseillé !) :
git rebase --skip
- Nous conseillons de résoudre le conflit. Git vous indique un nom de fichier en conflit (ici indiqué index.html). C’est qu’il n’a pas réussi tout seul à intégrer les modifications sans perdre votre code actuel comme indiqué :
.. image:: ../_images/contrib/filetoresolverebase.png
alt: git abort align: center
- Ouvrez ce fichier avec un éditeur classique. Vous observerez que Git a inséré des caractères spéciaux pour nous permettre d’identifier les lignes en conflit :
// je suis une pomme
var type = "Pomme"
<<< HEAD
// nouveau code
var test = "je suis rouge";
==========
// code actuel
var test = "je suis verte";
var taille = 12;
>>>>>
var region = "Normandie";
- Vous pouvez garder le nouveau code entrant entre <<< HEAD et === ou bien garder le code actuel entre ==== et >>> ou bien garder les deux.
- Pour cela, vous allez modifier à la main le fichier en supprimant les caractères <<< HEAD et ==== et >>>> ainsi que les lignes indésirables.
- Nous avons maintenant ce contenu :
// voici ma couleur
var type = "Pomme"
var test = "je suis rouge";
var taille = 12;
var region = "Normandie";
- Sauvegardez votre fichier
- Indiquez à Git que vous avez géré le conflit :
git add /chemin/vers/le/fichier/index.html

- On contrôle que le fichier est marqué comme « modified » avec la commande :
git status

- Indiquez à git de poursuivre le rebase comme décrit dans le message :
git rebase --continue

- Vous verrez d’autres commits listés et vous aurez probablement d’autres conflits. Répétez les opération précédentes pour bien tous les gérer.
- Lorsque le rebase est terminé vous n’aurez pas de message spécifique qui vous l’indiquera. Vous pourrez cependant voir que les derniers commits ont bien été appliqués.
Vérifier le résultat du rebase
Nous devons absolument vérifier que le rebase a pris en compte les commits natifs issus de GéoBretagne et vos commits de travail.
- Aller sur la page GitHub geobretagne/mviewer
- Ouvrez la page des commits
- Vérifiez dans la liste déroulante que vous êtes bien sur la branche master
- Observez les derniers commits, la date et le titre
- Nous allons maintenant vérifier que ces commits sont bien dans notre historique de commits après le rebase.
- Affichez l’historique des commits dans le terminal Git :
git logs

- Affichez la liste les commits présente sur la page des commits
- Vous devez les retrouver dans la liste des commits de la branche dans laquelle vous venez de réaliser votre rebase
- En cas de doute sur la gestion de certains conflits, vérifiez les fichiers visuellement et réalisez des tests dans vos applications
- Si tout vous semble correct, vous avez bien récupéré les modifications et votre arbre de commits est à jour (ainsi que votre code)
Transmettre du local vers la branche
Actuellement, le rebase a apporté des modifications sur votre ordinateur. Mais le code en ligne (GitHub) n’a pas changé. Vous devez pousser les modifications vers la branche distante.
- Lancez la commande suivante pour transmettre le travail du rebase à la branche distante (en ligne et visible sur GitHub) (**) :
git push -f

- Ouvrez la page des commits de votre branche de travail (ex pour la branche dev :) et vérifiez le succès de l’opération
- Supprimer ensuite la branche de sauvegarde si tout vous semble bon
(*) Avec –abort Il faudra tout reprendre tout le rebase depuis le début si vous arrêter et décidez de recommencer.
(**) Avec -f, cela indique un push forcé afin de réécrire en force l’historique des commits sur la branche distante. Il vaut mieux maîtriser ce que l’on pousse et contrôler votre code en local avant.
Pull Request¶
Une pull request ou « demande de tirage » réalise une demande pour que les modifications d’une branche intègre une autre branche.
Vous devez créer une pull request pour apporter une contribution de votre branche au sein de votre repository mviewer vers le repository geobretagne/mviewer.
Pour réaliser une pull request, dirigez-vous sur votre fork GitHub :
- Sélectionnez votre branche qui contient vos modifications à apporter en contribution
- Cliquez sur « New pull request »
- Ajouter un titre simple mais distinctif et parlant
- Ajouter un explicatif, avec de préférence le lien vers l’issue concernée
- Cliquez sur « Create pull request »
- Vous pourrez accéder à la pull request et discuter via le volet dédié du repository geobretagne/mviewer.
Votre pull request sera revue et vous aurez très certainement un retour pour réaliser des ajustements ou bien vous notifier que votre demande est acceptée.
N’hésitez-pas à laisser un message dans la pull request pour relancer la communauté si vous n’avez pas de réponse dans un délai raisonnable.
Cherry-pick¶
Si vous ne souhaitez reprendre qu’un seul commit d’une autre branche ou d’un autre repository, vous pouvez utilisez le cherry-pick. C’est un report manuel avec Git d’un commit d’une branche vers une autre branche, peu importe le repository.
Pour peu de commits, cette solution peut paraître plus simple que d’utiliser la technique de rebase.
Exemple avec un numéro de commit 235c47f à récupérer sur une branche nommée « dev » :
cd /home/user/jean/git/mviewer
git checkout dev
git cherry-pick 235c47f
Parcourez la documentation plus pas pour plus de détails.
Contribution¶
Pour contribuer, nous cous recommandons de suivre la documentation « Contribuer ».
Documentation¶
Faire une release de Mviewer & MviewerStudio¶
Les versions des projets Mviewer et MviewerStudio sont liées. Il faut donc faire une release des deux applications.
Il n’y a pas de système de build pour ces applications qui se veulent simples de mise en place. Il n’y a donc pas de commande permettant de faire la release simplement.
Vous devez avoir des droits spécifiques sur le repository pour pouvoir faire la release.
Release Mviewer¶
Commencez par vérifiez que toutes les issues et PR « closed » depuis la dernière release sont bien liées à un milestone.
Créez ensuite un nouveau milestone pour la future version et déplacez toutes les issues souhaitées et non « closed » à l’intérieur. https://github.com/geobretagne/mviewer/milestones
Puis fermez le milestone de la version releasée.
Modifiez la version de l’application sur la branch developp dans le fichier (en supprimant -snapshot) : https://github.com/geobretagne/mviewer/blob/develop/js/configuration.js#L11
Puis faire une pull request entre la branche develop et la master a un moment stabilisé. Testez le fonctionnement de l’application avec la PR et validez cette pull request.
Pour plus d’informations sur les branches, Mviewer suit ce type de modèle : https://nvie.com/posts/a-successful-git-branching-model/
Il vous faudra ensuite suivre ces indications pour créer la nouvelle release sur la page de release Mviewer.
Après la release,dans la branche developp, retournez modifier le numéro de version pour augmenter d’une version et ajouter -snapshot à la fin.
Release MviewerStudio¶
La marche à suivre devrait être la même, mais pour l’instant la branche develop n’est pas forcement à jour. A ce jour un travail est encore à faire.
Modifiez le numéro de version sur la branch master directement : https://github.com/geobretagne/mviewerstudio/blob/master/js/mviewerstudio.js#L3
Vérifiez que toutes les issues et PR « closed » depuis la dernière release sont bien liées à un milestone.
Créez ensuite un nouveau milestone pour la future version et déplacez toutes les issues souhaitées à l’intérieur : https://github.com/geobretagne/mviewerstudio/milestones
Puis fermez le milestone de la version releasée.
Il vous faudra ensuite suivre ces indications pour créer la nouvelle release sur la page de release Mviewer Studio.
Après la release retournez modifier le numéro de version pour augmenter d’une version et ajouter -snapshot à la fin.
Il n’y a pas de versionning de la documentation actuellement, c’est un élement dont il faudrait discuter.
Auteurs et licence¶
Cette documentation a été réalisée par :
- l’équipe « mviewer » (Région Bretagne)
- Gwendall Petit (Lab-STICC – CNRS UMR 6285)
Sauf indication contraire, cette documentation est sous licence Creative Commons Attribution - Non Commercial - ShareAlike 4.0 (CC-BY-NC-SA) .