Upload
duongthien
View
219
Download
2
Embed Size (px)
Citation preview
École Centrale Marseille
Rapport de stage 3A
Projet de géportailschez Ioda-Net sàrl
Julien EnselmePromo 2015
Maître de stage : M. Bruno FriedmannTuteur école : M. François Brucker
7 avril 2015 — 2 octobre 2015
Table des matières
1 Remerciements 1
2 Résumé et abstract 32.1 Résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3 Glossaire 5
4 Introduction 7
5 Présentation de Ioda-Net sàrl 9
6 Le projet de géportails 116.1 Une solution à bout de sou�e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
6.2 Les solutions alternatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
6.2.1 GeoMapFish . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
6.2.2 ngeo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
6.3 La solution retenue : mf-geoadmin3 . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
7 Travail réalisé 217.1 Organisation du projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
7.1.1 Réalisation des tâches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
7.1.2 Test driven development . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
7.2 Analyse du projet existant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
7.3 Liens avec upstream et développements spéci�ques . . . . . . . . . . . . . . . . . . 24
7.3.1 Collaboration avec swisstopo . . . . . . . . . . . . . . . . . . . . . . . . . . 24
7.3.2 Divergences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
8 Contributions Open Source 478.1 Fedora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
8.2 Plugin nbpython . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
9 Conclusion 51
10 Annexes 5310.1 Schémas d’interaction des composants . . . . . . . . . . . . . . . . . . . . . . . . . 53
Index 55
i
ii
1 Remerciements
Je tiens à remercier toutes les personnes qui m’ont permis de faire ce stage de �n d’étude chez Ioda-Net sàrl, Suisse, et qui ont contribué à son bon déroulement.
Je remercie tout d’abord Thomas Berger, élève à l’école Centrale Marseille, pour m’avoir transmis
les coordonnées de Ioda-Net sàrl.
Mes parents pour la relecture de ce rapport et leur soutien.
Je remercie le directeur et les collaborateurs de l’entreprise sigeom sa, de m’avoir accueilli dans
l’entreprise, notamment M. Waelti, M. Brahier, M. Ewald et M. Spinosi.
Je remercie l’o�ce fédéral suisse de topographie (swisstopo), et particulièrement Cédric Moullet, chef
du projet de géoportail pour la confédération suisse, ainsi que Gilbert Jeiziner et Olivier Terral, tous
deux développeurs chez swisstopo, pour leurs réponses rapides et utiles à nos questions techniques
et à nos propositions d’amélioration.
Je remercie également Véronique Herzl, responsable chez sigeom sa du projet géoportail ainsi que
des saisies de données pour le géoportail, tâche laborieuse mais indispensable au succès du projet.
Mme Herzl était donc notre interlocutrice principale pour le retour client durant ce projet.
Je remercie Françoise Wybrecht qui s’est occupée des aspects organisationnels et humains (plani�-
cation, aide à la collaboration, organisation des démos clients) du projet.
Je remercie en�n Bruno Friedmann qui a accepté d’être mon maître de stage et qui avait la responsa-
bilité du projet géoportail (estimation du temps et des priorités, choix stratégiques, installation des
serveurs, formation et interactions avec les clients).
1
Rapport de stage, Projet de géoportail, Release 1.0
2 Chapitre 1. Remerciements
2 Résumé et abstract
2.1 Résumé
Du 7 avril au 2 octobre 2015, j’ai réalisé mon stage de �n d’étude chez Ioda-Net sàrl une SARL suisse
de deux personnes. Cette entreprise propose des solutions de conseils, d’hébergement, de sauvegarde
et de géoportails basées sur des logiciels libres.
Durant ce stage, j’ai participé à la réalisation d’un projet de géoportails pour un client de Ioda-Netsàrl, la société de géomètres sigeom sa. Ce projet est basé sur celui créé par swisstopo pour l’état
fédéral suisse. En e�et, swisstopo (nom de l’o�ce fédéral suisse de topographie) a développé sa propre
solutions de géoportails et a dû placer son logiciel sous licence libre. De plus, il respecte les pratiques
de développement agile et a été récompensé par de nombreux prix pour sa qualité. Il est également
utilisé par le Land de Bavière en Allemagne et par l’o�ce national des forêts de Suède. Ce projet
constitue donc une très bonne base pour des développements spéci�ques.
Ce stage a consisté en une partie informatique avec du développement en python pour le backend et
javascript avec AngularJS pour le frontend. Celle-ci comprend également une partie infrastructure
avec la gestion des données et de plusieurs portails. Tout ce stage s’est déroulé en étroite collabora-
tion avec mon tuteur en suivant au maximum les préceptes agiles.
Mots clés géoportail, géomatique, cartes, géographie, python, javascript, angular, swisstopo, WMS,
IT, développement, Web, PostGis, PostgreSQL, map.geoadmin.ch, OpenSource
2.2 Abstract
In 2015, from April the 7th to October the 2nd, I made my internship in Ioda-Net sàrl a company
based in Swisstzerland. This internship is an integral part of my cursus in Centrale Marseille, a
French engineering school. Ioda-Net sàrl propose hosting, backups and geoportal solutions based on
Open Source software.
During this internship, I took part in the development of a geoportal for a client of Ioda-Net sàrl.This project is based on map.geo.admin.ch the geoportal developed for the Swiss confederation and
placed under an Open Source license. This project is developed according the best standards in the
industry and was awarded multiple times for its quality. It is also used by the forest o�ce in Sweden
and the Land of Bayern in Germany.
During this project, I developed in python and in AngularJS and was able to design in collaboration
with my mentor the infrastructure part of the projet.
Keywords geportal, maps, geography, python, javascript, angular, swisstopo, WMS, IT, develop-
ment, Web, PostGis, PostgreSQL, OpenSource
3
Rapport de stage, Projet de géoportail, Release 1.0
4 Chapitre 2. Résumé et abstract
3 Glossaire
Angular Voir AngularJS.
AngularJS Bibliothèque javascript créée par l’entreprise américaine Google dans le but de faci-
liter le développement d’application web sur une seule page. Un exemple de ce genre d’appli-
cations est un webmail moderne : il permet la rédaction, l’envoi et la consultation de courriels
sur une unique page sans rechargement. De même, les nouveaux courriels sont a�chés dès
réception sans que l’utilisateur n’ait à rafraîchir la page.
A�n de rendre cela possible facilement, AngularJS porte le principe du modèle-vue-contrôleur
dans le navigateur. La page HTML est la vue et contient des éléments de markup où les don-
nées seront insérées et présentées. Le contrôleur contient la logique de l’application et met à
jour les données en fonction des actions de l’utilisateur. Ces mises à jour sont automatique-
ment répercutées sur la vue.
Parmi les sites écrits avec AngularJS, on trouve notamment :
— Plunker un site d’échange de code autour de Javascript ;
— Vevo une platforme de vidéo musicale ;
— l’application Youtube pour PS3 ;
— la page présentant les trailers de Net�ix, un service de streaming vidéos.
Backend Partie non visible par l’utilisateur d’un site web. S’oppose au frontend qui est l’inter-
face utilisée par l’utilisateur. Cette partie est exécutée sur un serveur, contient la logique de
l’application et fait le lien avec les données. Elle répond aux requêtes du frontend et lui donne
les éléments nécessaires à l’a�chage d’une page.
closure compiler Outil développé par google pour optimiser du code javascript. Il fournit
également un gestionnaire automatique de dépendances en javascript.
ES6 Nom de la sixième norme du langage Javascript. Aussi appelée ES2015. Cette norme �nali-
sée mi-2015 va être amenée à remplacer ES5 dès que les navigateurs la respecteront complè-
tement. Il est déjà possible d’utiliser certains points de la norme soit parce que les navigateurs
en supportent déjà certaines parties, soit à l’aide d’outils appelés transpilateurs qui peuvent
transformer du code écrit avec la norme ES6 vers du code conforme à la norme ES5.
Framework Abstraction logicielle permettant de réaliser certaines fonctionnalités plus faci-
lement et plus rapidement en fournissant des fonctions réutilisables. Ce traduit souvent en
français par « cadre logiciel ».
Frontend Partie visible par l’utilisateur d’un site web. Elle s’exécute dans le navigateur de
l’utilisateur. S’oppose au backend qui correspond à la partie serveur du site.
Géoportail Permet de visualiser des cartes dans un navigateur web. Un système de couche
permet de choisir les informations a�chées (par exemple les routes et les voies ferrées). Il
permet aussi de faire de nombreuses actions associées à des cartes informatique comme des
recherches (une ville par exemple) ou des dessins. Deux exemples de géoportails : celui de
l’IGN ou celui de la Suisse.
Géoportails Pluriel de géoportail.
5
Rapport de stage, Projet de géoportail, Release 1.0
git Logiciel de gestion de version décentralisé créé pour le développement du noyau Linux et
qui a fait le succès de la platforme Github. Ce type de logiciel permet de partager le code
entre plusieurs développeurs ainsi que de garder une trace de l’historique du développement
avec la possibilité de revenir à une version précédente du code si besoin. L’atout majeur de git
réside dans le concept de branche qui permet de facilement travailler sur plusieurs versions
d’un projet en parallèle.
Javascript Langage de programmation utilisé notamment dans les navigateurs Web a�n d’ap-
porter de l’interactivité à une page web. C’est le seul langage de programmation disponible
dans les navigateurs aujourd’hui.
JSON Javascript Object Notation. Format d’échange de données courant sur le web, très facile
à utiliser en Javascript.
KML Keyhole Markup Language (traduction possible : langage à base de balises géolocales) :
format de données permettant d’échanger et d’a�cher des données géospatiales.
Make�le Fichier associant des tâches à des commandes à exécuter via la commande make. Par
exemple, on peut avoir une tâche documentation dans le Make�le qui va lancer toutes
les commandes nécessaires pour construire (make en anglais) la documentation. Cette tâche
est lancée par make documentation. Le Make�le est l’un des systèmes les plus utilisé
pour aider le programmeur à transformer du code source en un produit �ni utilisable.
Open Source Se dit d’un logiciel distribué sous l’une des licences reconnues par l’OSI (Open
Source Initiative) ou la Free Software Fondation. Ces licences ont la particularité d’autoriser la
copie et la modi�cation d’un logiciel sans l’accord de l’auteur original à condition de respecter
les éventuelles conditions imposées par la licence. Une condition courante est l’obligation de
redistribuer ses modi�cations sous la même licence. La licence est alors dite copyleft. De
façon plus générale, ce terme englobe le mouvement qui pousse à proposer des logiciels sous
de telles licences.
Python Langage de script très connu, réputé comme étant puissant, facile à utiliser et particu-
lièrement �exible. Il peut être utilisé pour écrire de petits logiciels simples réalisant une seule
tâche comme de grosses applications Web.
Pyramid Framework de développement d’applications Web en python.
Sourcemaps Fichier faisant le lien entre le code source écrit par le programmeur et le code
Javascript ou CSS interprété par un navigateur web. Ces �chiers sont très utiles lors de la
phase de débuggage si les �chiers subissent des modi�cations avant d’être interprétés. Par
exemple : concaténation en un seul �chier de tous les �chiers Javascript.
upstream Ce terme est commun dans le logiciel libre et Open Source. Lorsqu’un logiciel est
copié (forké dans le jargon Open Source), upstream désigne le projet à partir duquel la copie
a été faite.
WMS WebMapServer, il s’agit d’un protocole dé�ni par l’Open Geographic Consortium (OGC).
Ce protocole dé�nit les requêtes possibles pour accéder aux images des cartes, aux légendes et
aux métadonnées d’un serveur de géodonnées. Les images de cartes fournies par ce protocole
sont générées dynamiquement à chaque requête.
6 Chapitre 3. Glossaire
4 Introduction
En tant qu’élève en dernière année à l’École Centrale Marseille, j’ai réalisé mon stage de �n d’étude
du 7 avril au 2 octobre 2015 chez Ioda-Net sàrl, une société de service en informatique installée en
Suisse. Ce stage s’inscrit dans la formation centralienne a�n d’approfondir le métier d’ingénieur, de
nous immerger dans une entreprise pendant six mois et de faciliter notre entrée sur le marché du
travail.
Lors de ce stage, mon but principal était de comprendre et d’adapter le géoportail fédéral suisse,
développé par l’o�ce fédéral suisse de topographie (swisstopo) sous licence Open Source BSD pour
le gouvernement Suisse. Ce portail visible sur le site https://map.geo.admin.ch/ gère un très grand
nombre de fonctionnalités communes à tous les géoportails. Il se distingue des solutions concur-
rentes par son interface épurée et sa simplicité d’utilisation. De plus, il est très complet en terme de
fonctionnalités. Ses sources sont disponibles sur la plateforme de collaboration github.
Ioda-Net sàrl développe actuellement sa solution de géoportails pour l’entreprise de géomètres sigeomsa. sigeom sa vend ensuite cette solution à ses clients, des communes notamment. Comme ce client
a des besoins particuliers, il a été nécessaire d’adapter le backend à l’infrastructure de Ioda-Net sàrlet cette dernière de façon à pouvoir supporter plusieurs géoportails. De même, le frontend a dû être
modi�é de façon à prendre en compte ces besoins spéci�ques. Si certaines adaptations sont propres à
sigeom sa, certaines ont permis d’améliorer ou de généraliser le code de swisstopo. Ces modi�cations
leur ont été proposées et ont dans une grande mesure été acceptées.
Lors de ce stage, j’ai également pu faire des contributions à des projets Open Source en plus des
contributions e�ectuées dans le cadre du projet de géoportails. En e�et, Ioda-Net sàrl étant très atta-
ché à l’Open Source, j’ai eu du temps disponible certains vendredis pour prendre part à ces projets.
J’ai notamment participé :
— à la compatibilité Python 3 de OWSLib une bibliothèque python très utilisée en géomatique
et qui permet notamment de communiquer avec des serveur WMS ;
— à la validation et la proposition de paquets dans la distribution GNU/Linux Fedora ;
— au développement du plugin Python pour l’environnement de développement intégré (IDE)
Netbeans. Le développement de ce plugin a été arrêté en 2013 par Oracle l’entreprise qui
soutient le développement de Netbeans. Il a été repris par une équipe de bénévoles �n 2014
que j’ai rejointe �n avril 2015.
7
Rapport de stage, Projet de géoportail, Release 1.0
8 Chapitre 4. Introduction
5 Présentation de Ioda-Net sàrl
Ioda-Net sàrl est une SARL fondée par Bruno Friedmann et Françoise Wybrecht en 1998. Elle compte
comme uniques employés ses deux fondateurs. En créant la société en Suisse, leur intention était de
proposer une synergie de compétences et de services, allant du conseil informatique très technique à
la communication avec les clients en passant aussi par la conception et l’hébergement de sites Web.
Elle propose notamment :
— des services d’administration système : migrations de serveurs, installation de PC, réseaux et
parcs informatiques ;
— des conseils ponctuels (choix de matériels et logiciels) ;
— de l’hébergement ;
— des solutions de sauvegardes de données Open Source ;
— la conception et l’hébergement de sites Web ;
— du développement d’application.
La société embrasse l’engagement de ses fondateurs pour le logiciel libre et sponsorise ou participe
à de nombreux événements tel que les journées de développement de KDE à Randa et divers événe-
ments liés à openSUSE, la distribution GNU/Linux utilisée par l’entreprise. Cet engagement passe
également par l’implication de mon tuteur au sein de la communauté openSUSE : après 8 années
de contributions intensives, tant pour que pour aider les utilisateurs que pour améliorer technique-
ment la distribution, il a été élu pour deux ans en 2013 au conseil openSUSE. Ce conseil, d’après le
descriptif de leurs tâches a pour objectifs :
— d’agir comme un point de contact central ;
— d’aider à résoudre les con�its ;
— de communiquer les intérêts de la communauté à Novell1
;
— de faciliter la communication entre tous les secteurs de la communauté ;
— de faciliter le processus de prise de décision en cas de besoin.
C’est un élément important de la communauté openSUSE.
L’entreprise propose également des géoportails. Les revenus de cette activité proviennent plus de
l’administration système que de l’ajout de fonctionnalités, les portails proposés étant très matures.
Ces géoportails permettent d’a�cher dans un navigateur web des cartes. Ces cartes sont généra-
lement constituées d’une couche de fond (photos aériennes par exemple) sur laquelle l’utilisateur
ajoute les couches de données qui l’intéressent (le cadastre, les rues, . . . ).
Son principal client pour les géoportails est la société de géomètres sigeom sa. Par exemple, cette en-
treprise réalise des relevés pour mettre à jour le cadastre. Les données récupérées sont ensuite mises
dans une base de données et accessibles via un géoportail. Ces géoportails sont ensuite proposés aux
communes concernées. Ils permettent par exemple à un cabinet d’architectes faire plus facilement
des plans conformes à la réalité du terrain.
Les géoportails actuels, basés sur CartoWeb un logicielOpen Source, sont anciens et demandent à être
modernisés. Par exemple, on ne peut pas zoomer avec la molette de la souris : il faut sélectionner la
1. L’entreprise qui sponsorise openSUSE et commercialise SLES (Suse Linux Enterprise Server), la version d’open-
SUSE pour les entreprises qui dispose d’une durée de vie étendue et d’un support technique.
9
Rapport de stage, Projet de géoportail, Release 1.0
zone sur laquelle on veut zoomer avec l’outil de zoom et valider. L’entreprise a donc lancé un projet
de modernisation de ces géoportails en collaboration avec sigeom sa en se basant sur celui de l’état
suisse, lui aussi Open Source.
10 Chapitre 5. Présentation de Ioda-Net sàrl
6 Le projet de géportails
Le but de mon stage est de partir du portail fédéral suisse et de l’adapter aux besoins des clients de
la société. Cela consiste en :
— l’analyse et le décodage du géoportail fédéral Open Source : l’o�ce fédéral de topographie
suisse, swisstopo, a développé un géoportail pour ses propres besoins. Celui-ci est accessible à
tous et le code est librement réutilisable. Il a notamment été réutilisé par le Land de Bavière
en Allemagne. Avant de pouvoir utiliser ce projet à son plein potentiel, il est impératif de
comprendre son fonctionnement ;
— l’architecture et l’ingénierie de la production : c’est-à-dire comment adapter l’architecture
existante pour qu’elle fonctionne correctement avec le nouveau géoportail et comment faire
en sorte que le passage en production d’un géoportail se passe rapidement et correctement ;
— l’implémentation des besoins spéci�ques des clients concernés ;
— l’étude des intégrations proposées au projet parent : certaines des fonctionnalités que nous
allons développer pour les clients seront peut être intéressantes pour d’autres projets et pour-
raient donc rejoindre le projet parent. Ces intégrations sont à étudier au cas par cas et à dis-
cuter avec les mainteneurs du projet parent.
Cependant, avant de proposer ce stage avec ces objectifs, mon tuteur est partie du constat que la
solution de géoportails actuelle, âgée d’environ 10 ans, est en bout de course et doit être remplacée. Il
a donc étudié les autres solutions possibles avant de retenir mf-geoadmin3, le géoportail développé
pour la confédération suisse. C’est cette étape d’avant projet que nous allons étudier dans cette
partie.
6.1 Une solution à bout de sou�le
Depuis 2005, Ioda-Net sàrl propose des solutions de géoportails basées sur CartoWeb 3. Ce logiciel
était développé par la société suisse Camptocamp basée à Lausanne avec des antennes à Chambéry
et Vienne. Il est écrit en PHP, le langage de développement serveur le plus utilisé actuellement sur
Internet, et utilise le serveur WMS mapserver pour la génération des cartes. La première version de
CartoWeb 3 est sortie en avril 2005.
Ce logiciel a été conçu pour fonctionner avec la version 5.0 de PHP. PHP évoluant et intégrant des
correctifs de sécurité, il est nécessaire de pouvoir mettre à jour la version de PHP utilisée. Cependant,
les mises à jour provoquent parfois des incompatibilités et impliquent donc de modi�er plus ou
moins profondément le code source. A�n de suivre les évolutions du langage, Bruno Friedmann,
mon maître de stage, a dû faire ces modi�cations. Il les a proposées à Camptocamp qui ne les a
acceptées que plusieurs années après leur soumission lorsqu’un de leur client en a eu besoin. De
plus, ce logiciel datant de 2005, les paradigmes de programmation utilisés ne sont plus au goût du
jour et pour passer le code sur des bases modernes, il faudrait intégralement le réécrire.
De plus, même si la dernière version de CartoWeb est sortie en 2013, la dernière grosse mise à jour
date elle de 2008. En outre, ce logiciel n’est actuellement plus développé. En�n, il n’est plus capable
11
Rapport de stage, Projet de géoportail, Release 1.0
de fournir une qualité de service su�sante : ses bases anciennes impliquent un redémarrage fréquent
(environ une fois par semaine) du serveur web, faute de quoi les portails ne sont plus accessibles.
Comme les technologies utilisées ont atteint leurs limites, il est urgent de trouver une nouvelle
solution pour assurer la pérennité du produit. Cela permettrait en outre de proposer une interface
plus récente et conforme avec les standards et les attentes actuels.
Quoi qu’il en soit, CartoWeb a pu répondre aux usages des communes ces dix dernières années. Ce
logiciel fonctionnait bien et avait les fonctionnalités attendues :
— Navigation sur la carte : zoom et déplacement. Voir �gure 6.2.
— Sélection des couches à a�cher, c’est-à-dire la possibilité de choisir les informations à a�cher.
Par exemple, a�cher les photos aériennes en couche de fond et par dessus les délimitations des
communes. Tout changement de la liste des couches implique un clic sur le bouton Actualiserpour que les modi�cations soient prises en compte. Voir �gure 6.3.
— Des possibilités de dessiner sur la carte. Voir �gure 6.6.
— La possibilité d’interroger la carte pour récupérer des attributs. Par exemple, en sélectionnant
l’outil approprié et en cliquant sur un bâtiment avec la couche bâtiments activée, on peut
accéder à l’adresse, la surface et le type de bâtiment (maison d’habitation, bâtiment industriel,
. . . ). Voir �gure 6.4.
— Recherche d’un lieu par son adresse ou son identi�ant. Voir �gure 6.5.
— Impression des cartes
Figure 6.1 – La page d’accueil de CartoWeb sur geojb.ch
Toutes les données sont la propriété de sigeom sa
6.2 Les solutions alternatives
6.2.1 GeoMapFish
Il existe peu d’alternatives. La plus répandue en Suisse à l’heure actuelle est certainement GeoMap-
Fish (anciennement MapFish). Ce logiciel est écrit en Python avec le Framework Pyramid pour le
backend et utilise le framework Javascript ExtJS pour le frontend. Le but de ce framework est de
permettre la création d’applications très proches des applications de bureau classiques mais dans un
navigateur. L’a�chage des cartes est assuré par la bibliothèque OpenLayers.
12 Chapitre 6. Le projet de géportails
Rapport de stage, Projet de géoportail, Release 1.0
Figure 6.2 – Le zoom sous CartoWeb
Il faut sélectionner l’outil puis dessiner un rectangle autour de la zone sur laquelle on veut zoomer. Toutes
les données sont la propriété de sigeom sa.
Figure 6.3 – La sélection des couches sous CartoWeb
Une fois la sélection faîte, il faut cliquer sur Actualiser. On est alors ramené au niveau de zoom initial avec
les nouvelles couches a�chées.
6.2. Les solutions alternatives 13
Rapport de stage, Projet de géoportail, Release 1.0
Figure 6.4 – L’interrogation des couches sous CartoWeb
Toutes les données sont la propriété de sigeom sa
Figure 6.5 – La recherche sous CartoWeb
Il faut commencer par sélectionner le type de recherche dans le menu déroulant (ici adresse de bâtiment),
puis la commune et en�n la rue.
14 Chapitre 6. Le projet de géportails
Rapport de stage, Projet de géoportail, Release 1.0
Figure 6.6 – Le dessin sous CartoWeb
On ne peut faire qu’un dessin à la fois. Pas de possibilité d’export. Toutes les données sont la propriété de
sigeom sa.
Ce projet est Open Source et est distribué sous une licence permissive, la Berkeley Software Dis-
tribution License (BSD). Il fait partie des projets de l’OSGeo Fundation (Open Source Geospatial
Foundation – Fondation Géospatiale Open Source) dont le but est de promouvoir et de soutenir
le développement de logiciels géomatiques Open Source. Le développement est assuré par l’entre-
prise Camptocamp et les frais de développement sont répartis au sein du GeoMapFish User group,
groupe constitué des utilisateurs de GeoMapFish. Ce groupe se réunit régulièrement pour décider
des fonctionnalités à intégrer dans GeoMapFish et se répartir les frais de développement.
Bien que toutes les fonctionnalités de CartoWeb soient présentes, GeoMapFish commence à être
assez ancien et repose sur des technologies qui ne sont plus tout à fait au goût du jour. En�n, même
si GeoMapFish est Open Source, il est très di�cile de le faire fonctionner sans l’aide et l’infrastructure
de Camptocamp.
6.2.2 ngeo
Une autre alternative possible est ngeo, le projet de Camptocamp pour moderniser l’interface de
GeoMapFish créé courant novembre 2013 mais dont l’évolution n’a vraiment commencé qu’en 2014.
Le but du projet ngeo est de faciliter le développement d’applications basées sur Open Layers 3, une
bibliothèque Javascript complète pour l’a�chage de cartes, et AngularJS un framework de dévelop-
pement créé par Google en 2009.
ngeo est donc un projet récent et basé sur des technologies modernes. Il est de plus conçu pour être
modulaire. Cependant, il n’y a actuellement à ma connaissance aucune utilisation en production de
ngeo. De plus, même si le prochain géoportail du Luxembourg, en cours de développement par la
sociétéCamptocamp, sera basé sur cette technologie, le projet n’évolue pas aussi vite qu’il le pourrait.
Ainsi au 17 août 2015, si on compare les évolutions de ngeo et de mf-geoadmin3 (le projet retenu) :
6.2. Les solutions alternatives 15
Rapport de stage, Projet de géoportail, Release 1.0
2013 2014 20150
500
1000
1500
2000
2500
Nom
bre
de c
om
mit
sNombres de commits dans ngeo et mf-geoadmin3 au 17 août 2015
ngeomf-geoadmin3
Cela est d’autant plus inquiétant qu’il est censé constituer un remplacement à l’interface de Geo-
MapFish.
6.3 La solution retenue : mf-geoadmin3
swisstopo, l’o�ce fédéral suisse de topographie, est obligé par la constitution suisse de mettre à
disposition les données topographiques (photos aériennes, points �xes, données utiles à l’aviation,
. . . ) aux citoyens suisses. N’ayant pas trouvé de solutions de géoportail répondant à leur besoin,
swisstopo a démarré en 2013 les projets mf-geoadmin3 (le frontend) et mf-chsdi3 (le backend). Ces
deux projets sont publiés sous la licence Open Source BSD. Cette licence a l’avantage d’être très
permissive pour l’utilisateur qui n’a pas l’obligation de placer ses versions modi�ées sous licence
Open Source.
De plus, swisstopo utilise les dernières technologies disponibles et développe suivant les meilleures
pratiques actuelles de développement :
— utilisations d’AngularJS pour le frontend ce qui facilite le développement et permet de faire
une application qui se met facilement à jour avec les interactions utilisateurs ;
— backend écrit en python avec le framework Pyramid ;
— code découpé en petits modules qui peuvent être injectés comme dépendance dans n’importe
quel autre module grâce à AngularJS. En développement, ils sont chargés en fonction des
besoins grâce au closure compiler un utilitaire javascript développé par google ;
— code mini�é et optimisé par le closure compiler . swisstopo ne fait qu’utiliser les optimisations
simples du code. Les optimisations avancées nécessitant que tout le code soit entièrement
16 Chapitre 6. Le projet de géportails
Rapport de stage, Projet de géoportail, Release 1.0
typé via des annotations Javascript. Cela complexi�e et alourdit le code et le processus de
déploiement. Notons que les optimisations avancées sont utilisées par le projet ngeo ;
— tests unitaires : presque toutes les fonctionnalités ont des tests unitaires associés et ceux ci
sont lancés automatiquement à chaque commit poussés dans leur projet ;
— développement agile : des fonctionnalités sont régulièrement ajoutées et l’équipe de dévelop-
pement est très attentive aux retours des utilisateurs via l’outilAnnoncer un problème intégré à
l’application. Des tests d’utilisations sont également régulièrement réalisés a�n de permettre
à l’équipe d’améliorer l’ergonomie de ces outils. Une version est publiée en production envi-
ron tous les mois ;
— interface sobre et fonctionnelle : elle est à la fois complète et simple à utiliser. Voir 6.7.
Toutes ces qualités leur ont values de nombreuses récompenses, notamment :
— United Nations Public Service Awards en 2012 pour l’e�cacité, l’e�cience et la qualité pour
les prestations de service dans l’administration publique ;
— Euro Cloud Award en 2013 pour leur utilisation des services de cloud computing ;
— Geospatial World Award en 2013 pour la mise en œuvre exemplaire d’infrastructures pour les
géodonnées basées sur des normes ouvertes ;
— Best of swiss web Awards en 2014 (trois fois au total) pour l’innovation dans les domaines :
— de la technologie
— des services publics
— des technologies internet mobiles
— eGovernment Weltbewerb (en 2015, 2ième place) : concours international de eGovernment
dans la catégorie « Meilleur projet de cyberadministration 2015 ».
Concernant les fonctionnalités, toutes celles de CartoWeb sont présentes et sont améliorées :
— navigation sur la carte : zoom en temps réel à la molette et déplacement sur la carte grâce au
clic gauche et au mouvement de la souris ;
— sélection des couches à a�cher, c’est-à-dire la possibilité de choisir les informations à a�cher.
Par exemple, a�cher les photos aériennes en couche de fond et par dessus les délimitations
des communes. L’ordre des couches peut être changé à la volée. On peut ajouter et retirer des
couches facilement, le passage du curseur sur le nom d’une couche active la pré-visualisation.
L’utilisateur peut changer l’opacité de chaque couche. Les couches sont regroupées en sujet
et catégorie pour une meilleure présentation. Voir �gure 6.8 ;
— des possibilités de dessiner sur la carte. Voir �gure 6.11 ;
— la possibilité d’interroger la carte pour récupérer des attributs. Par exemple, en sélectionnant
l’outil approprié et en cliquant sur un bâtiment avec la couche « bâtiments » activée, on peut
accéder à l’adresse, la surface et le type de bâtiment (maison d’habitation, bâtiment industriel,
. . . ). Voir �gure 6.9 ;
— recherche d’un lieu par son adresse, son identi�ant ou ses coordonnées. On peut également
chercher les couches par leur nom. Voir �gure 6.10 ;
— impression des cartes.
Elle comprend aussi de nouvelles fonctionnalités, notamment :
— une interface mobile ;
— la possibilité d’utiliser des couches depuis un serveur externe ;
— la possibilité d’utiliser les cartes hors ligne : l’utilisateur choisit le centre de la carte à exporter
et les informations sur toutes les couches sélectionnées sont téléchargées dans la mémoire du
téléphone ou de la tablette sur un carré de 10km de côté.
6.3. La solution retenue : mf-geoadmin3 17
Rapport de stage, Projet de géoportail, Release 1.0
Figure 6.7 – La page d’accueil de map.geo.admin.ch
Toutes les données sont la propriété de swisstopo.
18 Chapitre 6. Le projet de géportails
Rapport de stage, Projet de géoportail, Release 1.0
Figure 6.8 – La sélection des couches sous map-geoadmin
Lorsque l’utilisateur passe la souris sur une couche, elle est immédiatement a�chée en mode aperçu sur la
carte. S’il la sélectionne, la couche est immédiatement visible et est ajoutée à la liste des couches
sélectionnées. Toutes les données sont la propriété de swisstopo.
Figure 6.9 – L’interrogation des couches sous map-geoadmin
Lorsqu’on interroge une couche sous map-geodamin, une popup apparaît avec les attributs disponibles.
Lorsqu’on passe la souris sur un identi�ant, l’objet concerné est mis en évidence sur la carte (à gauche). Si
on clique sur l’identi�ant, une nouvelle popup apparaît avec les informations sur l’objet (à droite). Toutes les
données sont la propriété de swisstopo.
6.3. La solution retenue : mf-geoadmin3 19
Rapport de stage, Projet de géoportail, Release 1.0
Figure 6.10 – La recherche sous map-geoadmin
Dès que l’utilisateur tape son texte de recherche, les résultats apparaissent. Ils sont groupés par adresse (en
haut) et par couche (en bas). Toutes les données sont la propriété de swisstopo.
Figure 6.11 – Le dessin sous map-geoadmin
L’utilisateur peut faire autant de dessin qu’il le désire et peut en importer. Il est également possible de faire
des mesures de distance et de surface. Lorsqu’on trace une ligne de mesure, le pro�l du terrain sous celle-ci
est automatiquement a�ché. Si on modi�e la ligne, le pro�l est mis à jour dynamiquement. Toutes les
données sont la propriété de swisstopo.
20 Chapitre 6. Le projet de géportails
7 Travail réalisé
Le temps nécessaire pour mener le projet à bien a été initialement estimé par mon tuteur comme
étant de 900 heures sur six mois. Il a réparti ces 900 heures en environ 600 heures pour moi et les
300 restantes pour lui.
Cette estimation est basée sur le temps mis par les employés de l’o�ce des forêts de Suède qui ont
adapté map.geo.admin pour leurs besoins avant que nous ne commencions et qui ont accepté
de partager avec nous cette information. Ils ont estimé y avoir passé entre 1500 et 1600 heures
dont entre 500 et 600 pour adapter les données. Comme nous devons faire un travail similaire et que
l’adaptation des données est réalisée par le client, cette estimation de 900 heures semble raisonnable.
Sur mes « 600 heures » passées sur le projet géoportail, le travail que j’ai réalisé peut se décomposer
en plusieurs parties distinctes :
— analyse du projet existant ;
— analyse des besoins du client ;
— implémentation des demandes spéci�ques ;
— liens avec le projet parent (dit upstream).
Si j’ai bien évidemment commencé par analyser le projet, toutes ces parties ne sont pas étanches
entre elles. Par exemple, pour implémenter un besoin spéci�que, il est souvent nécessaire d’a�ner
l’analyse du projet ou de proposer une modi�cation à swisstopo.
L’analyse des besoins du client et l’implémentation des demandes spéci�ques ont été regroupées
dans la partie liens avec upstream et développements spéci�ques.
7.1 Organisation du projet
Avant de démarrer la partie technique, quelques mots sur l’organisation du projet.
Le projet tente de respecter au mieux les méthodes agiles. Toutes les semaines, nous (mon tuteur,
Madame Wybrecht responsable de l’organisation du projet et moi même) faisons le point sur le tra-
vail réalisé pendant la semaine écoulée : tâches terminées avec succès, en cours, à revoir, . . . Pendant
cette réunion, en générale assez courte, nous dé�nissons également les tâches à faire pour les se-
maines à venir. À chacune d’elles, nous dé�nissons sa priorité et estimons le temps nécessaire pour
la mener à bien.
Généralement, c’est après cette réunion que mon tuteur et moi même mettons à jour, si besoin, la
maquette de présentation avec les nouveaux développements.
Au début du projet, nous avions l’intention de faire des points réguliers (au moins une fois par mois)
avec les principaux utilisateurs du géoportail chez sigeom sa ainsi que le directeur de l’entreprise
a�n de leur montrer notre avancé et de pouvoir plus facilement déterminer les prochains objectifs
à atteindre. Ces points d’étape sont très classiques dans la méthodologie agile mais doivent être
su�samment courts pour ne pas impacter les autres activités des personnes concernées qui doivent
pouvoir continuer leur travail habituel normalement.
21
Rapport de stage, Projet de géoportail, Release 1.0
Cependant, dans notre cas, personne chez le client n’est vraiment sensibilisé aux méthodes agiles.
De plus, le budget et le temps impartit au projet ne permettaient pas d’y inclure cette sensibilisation.
Ces réunions intermédiaires prenaient beaucoup trop de temps (plusieurs heures même si la réunion
était prévue pour durer entre 30 et 45 minutes). Les participants ont en e�et tendance à s’oublier
dans les détails. À cela s’ajoute les congés ou les problèmes de disponibilités des participants. Tous
ces éléments font que notre veux initial d’une réunion par mois n’a pas pu être réalisé.
Il aurait aussi été béné�que de pouvoir faire, a minima, des points réguliers (toutes les semaines
ou toutes les deux semaines par exemple) avec Madame Herzl qui gère le projet géoportail au sein
de sigeom sa. Ces points auraient permis de mieux dialoguer et de mieux comprendre les attentes
du client vis à vis du nouveau géoportail. Malheureusement, par manque de temps, cela n’a pas été
possible.
7.1.1 Réalisation des tâches
En règle générale, j’ai réalisé les tâches qui m’étaient a�ectées suite à la réunion hebdomadaire en
autonomie. J’ai toutefois fait régulièrement le point avec mon tuteur sur mon avancement et les
éventuels problèmes rencontrés. Nous avons également pu, lors des trajets chez le client e�ectués
deux fois par semaine, échanger autour du géoportail et des fonctionnalités attendues.
De plus, avec mon tuteur, nous avions environ une journée de « pair programming » (littéralement
programmation par paire) par semaine. Durant ces sessions nous travaillons ensemble sur un même
problème. Cela permet à la fois de partager les connaissances sur le projet et de découvrir d’autres
façons de raisonner. Cela permet également d’échanger autour des problèmes et de béné�cier des
compétences de l’autre pour s’améliorer.
7.1.2 Test driven development
On associe souvent avec les méthodes agiles le test driven development (TDD en abrégé pour dé-
veloppement orienté par les tests). Cette pratique a pour but de faciliter l’écriture du code et d’en
améliorer l’organisation. Pour cela, on commence par écrire les tests qui utilisent le code tel qu’on ai-
merait l’employer par la suite. Ensuite, on écrit le code associé jusqu’à ce que tous les tests passent.
Ces tests permettent également de s’assurer facilement que tous les composants de l’application
fonctionne comme attendus. Cela est extrêmement utile après des grandes modi�cations du code.
Il peut cependant être assez di�cile de prendre l’habitude de développer en TDD. Si swisstopo utilise
de nombreux tests unitaires dans son projet, leur écriture n’est pas systématique, de larges portions
de code restant non testées unitairement. Cela complique l’écriture de tests après coup car le code n’a
pas été écrit dans l’optique d’être testé. Cela n’est pas forcément très dommageable pour swisstopocar leur infrastructure leur permet également de faire des tests dit « end to end » c’est-à-dire de
lancer l’application dans un navigateur et d’y faire de façon automatique des actions. Il est ainsi
possible de véri�er que l’application fonctionne comme attendue tant au niveau de l’interface que
des liens entre l’interface et l’API. De plus, tous ces tests sont lancés automatiquement à chaque fois
qu’un développeur propose une fonctionnalité ou une correction de bug via l’interface de Github.
La di�culté dans notre cas est que ni moi ni mon tuteur n’avons l’habitude de fonctionner en TDD.
Par conséquent nous avons tendance à écrire la fonctionnalité et à la tester après. Cela est accentué
par le fait que nous ne connaissons pas intégralement le programme et qu’il nous semble plus facile
d’aller modi�er le code de l’application puis de tester directement dans le navigateur. En outre, le
pourcentage de code couvert par les tests n’étant pas aussi élevé qu’il pourrait l’être, cela ne nous
incite pas à prendre l’habitude de faire du TDD.
22 Chapitre 7. Travail réalisé
Rapport de stage, Projet de géoportail, Release 1.0
De plus, nous ne disposons pas d’infrastructure permettant de lancer automatiquement les tests a�n
de parer à nos oublis. Au moment où j’écris ces lignes, une ré�exion est en cours a�n de les amé-
liorer et de disposer de celle-ci. Cela nous facilitera le travail futur, notamment lors des mises à jour
depuis le code de Swisstopo : cela permettra de véri�er que nos modi�cations fonctionnent encore
correctement et que nous n’avons pas « cassé » par inadvertance une fonctionnalité de swisstopo.
En�n, certains points sont beaucoup plus faciles à véri�er avec des tests d’intégration que des tests
unitaires. Par exemple, dans l’API, véri�er que l’interrogation des couches fonctionne correctement
(bonne communication avec la base de données et retour des informations au bon format) est simple
à réaliser si on dispose de ladite base de données. Sans elle, le travail nécessaire pour imiter ses
réponses est conséquent. Or cette base de données évolue souvent en fonction des besoins et des
actions du client. Il est donc di�cile de pouvoir s’appuyer sur celle-ci pour tester l’API.
7.2 Analyse du projet existant
Le projet est basé sur le géoportail réalisé par swisstopo, l’o�ce fédéral suisse de topographie, sous
licence Open Source. Le but de cette analyse initiale était de comprendre comment les di�érentes
parties du projet s’articulent entre elles a�n de pouvoir les adapter plus facilement par la suite.
Notons que le projet est en fait constitué de deux sous-projet distincts mais intiment liés :
— le frontend qui contient l’interface du projet. Il est réalisé avec le framework Javascript An-gularJS. Ce framework facilite la création d’application web complexe sur une seule page. Il
repose également sur la bibliothèque javascript OpenLayer 3 pour l’a�chage des cartes ;
— le backend est lui réalisé en python à l’aide du framework Pyramid. Le backend est en charge
de recevoir les requêtes du client (par exemple recevoir un texte de recherche) et de les traiter
(par exemple en utilisant les index de recherche) avant de donner une réponse au client. La
réponse est ensuite a�chée par le frontend.
L’analyse du projet consiste donc à :
— analyser chaque des parties ;
— déterminer leurs interactions.
A�n de mener cette partie à bien, je me suis �xé comme premier objectif de comprendre comment
s’a�che une couche puis d’utiliser l’interface et l’API sur mon ordinateur a�n d’a�cher une couche
utilisant les données du client.
Pour cela, j’ai commencé par aller sur le site http://map.geo.admin.ch/ et j’ai étudié les requêtes faites
par un navigateur web. Cela m’a permis de comprendre quels sont les besoins de l’interface (données
de con�guration des couches, listes des couches de fond possible, traductions). Pour récupérer ces
données, l’interface fait dès son chargement des requêtes vers l’API qui lui répond au format JSON .
J’ai ensuite étudié le code du frontend a�n de comprendre comment ces données étaient e�ective-
ment utilisées pour a�cher une couche.
J’ai en�n mis ma compréhension à l’épreuve en a�chant les données du client à partir d’une inter-
face et d’une API fonctionnant sur mon ordinateur. Pour cela, j’ai modi�é l’API pour qu’elle donne
des con�gurations �xes pour les couches (au lieu d’aller les chercher en base de données, base qui
n’existait pas encore) et le frontend pour qu’il se connecte à mon API.
Une fois cette étape validée, je me suis �xé pour objectif d’utiliser les données du client de façon
dynamique avec une base de données. Pour cela, j’ai rempli la base de l’API avec les données géo-
graphiques réelles fournies par sigeom sa. J’ai également entré les informations complémentaires
nécessaires à l’API pour fournir la liste des couches (couches de fond, organisation des couches en
topic, . . . ). Lors de cette étape de remplissage, il est apparu que le modèle de données de swisstopo
7.2. Analyse du projet existant 23
Rapport de stage, Projet de géoportail, Release 1.0
n’était pas adapté à nos besoins. Pour plus de détails, voir Base de données de la section Liens avecupstream et développements spéci�ques.
Cette étape a également permis de réaliser les schémas d’interaction des composants disponibles en
annexe.
7.3 Liens avec upstream et développements spécifiques
7.3.1 Collaboration avec swisstopo
La collaboration avec upstream est indispensable et se compose de trois parties :
— la récupération des modi�cations du projet source : le projet mené par swisstopo évolue régu-
lièrement et propose des modi�cations intéressantes tant pour de nouvelles fonctionnalités
que des corrections de bugs ;
— la soumission d’améliorations ou de modi�cations : lors du développement de notre projet,
nous avons été amenés à faire des modi�cations pourvues d’intérêt pour le projet de départ
(amélioration du code, mise en variable, fonctionnalité, . . . ). Nous avons soumis ces modi�-
cations à swisstopo via un processus nommé pull request sur la platforme Github qui héberge
le projet. Ce processus permet de soumettre des modi�cations à projet pour en discuter et
éventuellement fusionner les modi�cations dans le projet initial. Ce processus est donc très
souvent itératif : on propose une modi�cation, le projet fait des remarques, on modi�e la re-
quête pour en tenir compte, le projet fait des remarques, . . . et ainsi de suite jusqu’à ce que le
projet parent accepte ou rejette les modi�cations ;
— les divergences : notre projet comporte également certaines modi�cations qui ne peuvent pas
être soumises à upstream mais qui sont nécessaires au client �nal. Le but est de garder ces
modi�cations aussi réduites que possible a�n de faciliter les mises à jour de notre projet à
partir du projet source.
Cette nécessité de travailler avec upstream a in�uencé l’organisation du travail et la gestion du code
source. Le code est géré par git qui organise le code en dépôt. On travaille sur un dépôt dit local. Les
modi�cations du code sont enregistrées dans celui-ci et peuvent être poussées vers un ou plusieurs
dépôts distants. C’est le développeur qui choisit vers quel dépôt pousser ces modi�cations. De la
même façon, pour récupérer les modi�cations d’un autre développeur, il peut « tirer » les modi�ca-
tions depuis le dépôt de son choix. A�n de faciliter la synchronisation, on utilise souvent un dépôt
central qui recense toutes les modi�cations. C’est alors vers ce dépôt que les développeurs poussent
et tirent les modi�cations.
A�n de pouvoir assurer les liens avec upstream, nous avons créé deux dépôts organisés comme suit :
— un dépôt central public qui permet de faire les liens avec le projet source : récupération des
mises à jour et soumission de nos modi�cations ;
— un dépôt central privé qui contient nos modi�cations.
Pour mettre à jour le dépôt central privé, il faut :
1. mettre à jour le dépôt central public. Pour cela, un développeur doit sur sa copie locale du
dépôt :
(a) tirer les modi�cations du dépôt upstream ;
(b) pousser les modi�cations vers le dépôt central public ;
2. mettre à jour le dépôt central privé par le même processus que précédemment.
Voir la �gure 7.1 pour plus de détails.
La soumission de modi�cations se fait avec un processus analogue, seul le sens change. Voir �gure
7.2.
24 Chapitre 7. Travail réalisé
Rapport de stage, Projet de géoportail, Release 1.0
Figure 7.1 – Mise à jour du projet
Figure 7.2 – Soumission de modi�cations
7.3. Liens avec upstream et développements spécifiques 25
Rapport de stage, Projet de géoportail, Release 1.0
Note : Il serait tout à fait possible de se passer du dépôt central public pour les mises à jour . La mise
à jour se ferait alors en tirant directement les modi�cations du dépôt public de upstream. Cependant,
ce dépôt est indispensable pour proposer les modi�cations. Par souci de simplicité et de cohérence,
nous avons donc choisi de procéder ainsi.
Il reste encore une question : comment choisir les modi�cations que l’on veut soumettre et celles
que l’on veut garder ? Sous git, chaque modi�cation est identi�ée de façon unique par un identi�ant
de 40 caractères appelé « hash ». À partir de cet identi�ant, il reste à choisir et grouper ceux à
soumettre. C’est là qu’intervient une des forces de git, le concept de branche.
Un dépôt git peut être considéré comme un arbre. Il existe une modi�cation d’origine qui constitue
la racine et les modi�cations �lles sur une ou plusieurs branches di�érentes. On peut créer une
branche à partir de n’importe quelle modi�cation. On peut copier les modi�cations d’une branche
à l’autre. Le développeur choisit avec quel dépôt distant il veut partager une branche. Voir la �gure
7.3.
Par conséquent, pour soumettre une modi�cation on :
1. travaille normalement sur une branche privée ;
2. identi�e les modi�cations intéressantes pour upstream
3. crée une nouvelle branche à partir d’une modi�cation commune à upstream et nous ;
4. copie les modi�cations intéressantes à l’aide de leur identi�ant. Les modi�cations copiées
n’étant pas les mêmes que les modi�cations d’origines (les parents notamment sont di�é-
rents), elles se voient a�ectées un nouvel identi�ant à la copie. Si git ne peut pas copier une
modi�cation automatiquement, il donne la main au développeur pour faire les modi�cations
nécessaires ;
5. pousse la branche sur le dépôt ;
6. crée une pull request, c’est-à-dire que l’on propose nos modi�cations au projet source.
Le projet source peut alors faire des remarques, nous en tenons compte et modi�ons notre branche
a�n que celle-ci soit fusionnée avec la branche principale du projet source : master.
De même, lors de la récupération des mises à jour, nous synchronisons la branche de travail de
upstream nommée master avec la branche master de notre dépôt central public. Ensuite, nous
synchronisons la branche master de notre dépôt central privé avec la branche master de notre
dépôt central public. Nous fusionnons alors notre branchemaster privée dans la branchesigeomqui contient les modi�cations spéci�ques à notre client. Le processus global est donc bien celui décrit
par la �gure 7.1, mais en pratique, il faut ajouter quelques détails importants.
7.3.1.1 Soumissions d’améliorations
Bien que swisstopo ait publié son code sous licence libre, il développe son géoportail pour leurs be-
soins et ne se préoccupent pas forcément de la réutilisation du code. Par conséquent, de nombreuses
variables de con�guration étaient écrites en dur dans le code et empêchaient une réutilisation facile
de géoportail. Par exemple :
— le nom du modèle d’élévation utilisé pour les pro�ls de terrain ;
— la liste des URLs autorisées à utiliser certains services ;
— le point sur lequel centrer le géoportail ;
— le niveau de zoom initial ;
— l’étendue de la carte.
26 Chapitre 7. Travail réalisé
Rapport de stage, Projet de géoportail, Release 1.0
Figure 7.3 – Les branches sous git.
7.3. Liens avec upstream et développements spécifiques 27
Rapport de stage, Projet de géoportail, Release 1.0
J’ai dès le début de mon stage identi�é de tels points et modi�é le code de façon à ce que des variables
issues de la con�gurations soient utilisées, tant dans le frontend que dans l’API. Bien que le code
du géoportail ait été réutilisé, personne n’avait encore proposé de telles modi�cations à swisstopo.
Comme nous tenons à pouvoir récupérer leurs nouveautés facilement, nous tenons à leur propo-
ser un maximum de nos modi�cations : plus les deux projets vont diverger, plus il sera di�cile de
réintégrer les modi�cations de upstream. En e�et, lors de la fusion de la branche master de swiss-topo dans notre branche sigeom, git ne peut pas intégralement et automatiquement fusionner
les �chiers qui ont été modi�és aux mêmes lignes dans les deux branches. Plus les divergences sont
nombreuses, plus le temps nécessaire à la mise à jour est donc élevé. Nous faisons donc attention lors
du développement de fonctionnalités spéci�ques à impacter le moins possible le code de Swisstopo.
Un exemple complet de collaboration
Si pour l’ajout de fonctionnalités ou la modi�cation de fonctionnalités existantes, les développeurs
de swisstopo n’ont pas encore accepté nos soumissions et doutent de le faire dans le futur pour ne
pas avoir du code en plus à maintenir de leur côté, celles qui contribuent à améliorer le code sont
les bienvenues.
Si ces modi�cations restent faciles, j’ai également participé en collaboration avec swisstopo à des
modi�cations plus complexes. Par exemple, il est possible sur le géoportail de choisir la couche de
fond grâce à un sélecteur visible sur la �gure 7.4. Avant que ce composant ne soit opérationnel, il
faut :
1. charger la liste des thèmes : chaque thème a une liste de couches de fond bien dé�nie. C’est
à partir de cette liste que les vignettes représentant les couches de fond disponibles vont être
créées ;
2. charger les dé�nitions des couches de fond : à chaque nom couche de la liste précédente, il
faut faire correspondre la couche qui sera utilisée pour l’a�chage.
Figure 7.4 – Le composant permettant de changer de couches de fond.
Plié à gauche et déplié à droite.
swisstopo utilise toujours les mêmes couches de fond quelque soit le thème et a donc écrit en dur
la liste des couches possibles, quand bien même le code est capable, par ailleurs, de supporter une
liste dynamique provenant d’un �chier JSON de con�guration. Lors de ma première tentative d’uti-
lisation de ce �chier JSON pour charger la liste des couches de fond possible, j’ai rencontré un bug
étrange : la liste des thèmes étaient bien récupérée mais la liste des couches de fond dans l’interface
n’était jamais mise à jour.
Peu avant, j’avais constaté le même problème lors d’une mise à jour depuis le code de swisstopo : la
liste des thèmes était bien récupérée mais l’interface n’était jamais mise à jour. Mais si j’utilisais la
version de production du code (donc mini�ée et optimisée), le problème disparaissait.
Voici mon analyse du problème. Le géoportail utilise le framework AngularJS qui se divise le code
en plusieurs composants distincts :
— les constantes qui servent à fournir la con�guration de l’application ;
28 Chapitre 7. Travail réalisé
Rapport de stage, Projet de géoportail, Release 1.0
— les services qui permettent d’organiser et de partager du code à travers l’application. Contrai-
rement aux autres composants, un service ne peut exister qu’une seule fois. Tous les contrô-
leurs et toutes les directives partagent donc la même instance d’un service ;
— les contrôleurs qui contiennent la logique et les données ;
— les directives qui sont en charge de l’a�chage des éléments sur la page. Elles sont constituées :
— d’un élément HTML ou d’un attribut qui modi�e le comportement d’un élément existant
ou d’une autre directive ;
— de javascript qui dé�nit les actions associées à cet élément ou attribut.
Lorsqu’une application AngularJS est chargée, elle initialise d’abord les constantes, puis les services,
puis les contrôleurs et en�n les directives.
Dans le cadre de la sélection des couches de fond, voici ce qui devait se passer :
1. le service en charge des thèmes gaTopics est initialisé et fait une requête HTTP pour
obtenir la liste des thèmes ;
2. une partie de l’application est initialisée mais pas la directive en charge de la sélection des
couches de fond gaBackgroundSelectorDirective ;
3. le service gaTopics envoie un signal à tous les composants de l’application pour leur si-
gnaler que la liste des thèmes est prête ;
4. gaBackgroundSelectorDirective est initialisée et attend de recevoir le message
disant que la liste des thèmes est prête pour pouvoir présenter celle-ci à l’utilisateur ;
5. sauf que le message est déjà parti. . .
Le code de production fonctionnait car il est exécuté plus rapidement par le navigateur. De même,
swisstopo ne s’est jamais aperçu du problème car leur liste de thèmes est toujours chargée depuis la
base de données située sur un autre serveur ce qui ajoute su�samment de latence pour que l’ap-
plication soit complètement initialisée avant que la liste des thèmes n’arrive et que gaTopicsn’émette son signal.
J’ai signalé ce problème à swisstopo avec une proposition de correction : attendre le chargement
complet de l’application avant d’envoyer le signal annonçant que la liste des thèmes est prête. Ce-
pendant, cette solution n’a pas été retenue par swisstopo car comme on me l’a fait remarquer, cela
ralentit le chargement de l’application dans tous les cas, y compris ceux qui ne sont pas concernés
par ce problème. Comme il s’agissait d’une erreur de conception, les développeurs de swisstopo se
sont proposés pour la corriger.
La solution implémentée a�n de corriger cette erreur de conception est d’utiliser des promises pour le
chargement initial des con�gurations. Qu’est-ce qu’une promise ? Une promise représente le résultat
futur d’une opération asynchrone (une requête HTTP par exemple) et dispose de trois états :
— en cours : la promise est dans cet état tant que l’opération asynchrone est en cours ;
— résolu : la promise va dans cet état une fois que l’opération s’est terminée avec succès. On
peut alors accéder à sa valeur ;
— rejeté : la promise va dans cet état si l’opération rate.
Dès qu’une promise est dans l’état résolu ou rejeté, elle ne peut plus changer d’état et sa valeur ne
peut pas être modi�ée. Les promises peuvent être chaînées pour exécuter une action dès qu’elles
entrent dans l’état résolu. Par exemple :
// crée une promise qui sera résolue lorsque la requête vers// 'google.com' sera terminée. Sa valeur sera le contenu de la page.p = $http.get('google.com');// On affiche le contenu de la page lorsqu'elle a finit.p.then(function(data) {
console.log(data);});
7.3. Liens avec upstream et développements spécifiques 29
Rapport de stage, Projet de géoportail, Release 1.0
On peut aussi créer une promise qui sera résolue lorsqu’une liste de promises sera résolue. Dans
le cas d’angular, il su�t d’utiliser $q.all([promise1, promise2]). Les promises sont
disponibles depuis quelques années grâce à des bibliothèques javascript (comme $q dans angular)
et sont standardisées dans ES6.
Dans notre cas, les services gaTopics (qui récupère la con�guration des topics) et gaLayers(qui récupère la con�guration des couches) ont été modi�és de façon à utiliser et rendre accessibles
ces promises. Le code de sélection des couches attend alors qu’elles soient toutes les deux résolues
avant d’initialiser sa liste des couches.
swisstopo a pris soin de modi�er les autres services a�n que tout chargement de con�guration utilise
les promises et non plus l’envoi de messages pour d’éviter que ce bug ne se reproduise à l’avenir.
Les messages restent utilisés une fois que l’application est complètement chargée pour noti�er les
composants des actions utilisateurs. Par exemple, lorsque l’utilisateur change de thème, un signal
est émis ce qui permet à tous les composants qui écoutent de faire les actions en conséquence, par
exemple, mettre à jour la liste des couches de fond.
Une fois cette correction e�ectuée, j’ai pu reprendre mon travail sur la sélection des couches de fond
et le proposer à swisstopo.
Mes contributions
À titre d’information, j’ai ouvert :
1. 20 soumissions d’amélioration dans le frontend au 24 août 2015 dont 2 en attente et 12 accep-
tées. Sur les 6 refusées :
— 2 modi�aient la façon dont le projet fonctionnait et avaient donc peu de chance d’être
acceptées ;
— 1 a été ré-ouverte car modi�er l’existante pour prendre en compte les remarques et les
modi�cations de swisstopo aurait demandé plus de temps que de repartir de zéro ;
— 1 ne corrigeait pas un bug d’une façon satisfaisante. La vraie correction nécessitait des
modi�cations plus profondes que ce que j’avais envisagé et ont été faîtes par swisstopo ;
— 1 ajoutait une fonctionnalité qui n’intéressait pas swisstopo.
2. 8 dans l’API.
On peut donc constater que swisstopo accepte volontiers les améliorations proposées par des tiers si
elles correspondent à leur standard de qualité. La durée avant acceptation d’une soumission dépend
de sa taille et du temps que peuvent y consacrer les développeurs de swisstopo qui ont parfois d’autres
priorités.
7.3.2 Divergences
Bien que nous tentons de rester le plus proche possible du code de swisstopo a�n de faciliter les mises
à jour, certaines fonctionnalités spéci�ques nécessitent de s’en éloigner. Dans la mesure du possible,
ces modi�cations sont faîtes dans leur propre module pour limiter l’impact sur le code de Swisstopo.
7.3.2.1 Frontend
MapFish Print
A�n de répondre entièrement aux besoins des clients, le frontend présente quelques divergences
avec swisstopo. La première que nous avons introduite est l’utilisation de MapFish Print v3. MapFish
30 Chapitre 7. Travail réalisé
Rapport de stage, Projet de géoportail, Release 1.0
Print est une application serveur écrite en Java par la société Camptocamp a�n de créer des rapports
contenant des cartes. Le frontend lui passe :
— le centre de la carte ;
— l’échelle ;
— la liste des couches à imprimer avec l’adresse du serveur WMS qui les produit ;
— les dessins éventuels au format GeoJSON, format d’échange de données géographiques basées
sur JSON ;
— le titre de la carte.
À partir de ces informations et d’un template, MapFish Print va créer un rapport contenant la carte.
Voir la �gure 7.5.
swisstopo utilise actuellement la version 2. Néanmoins, nous avons décidé d’utiliser directement la
version 3 pour éviter d’avoir à déployer la version 2 pendant a priori peu de temps avant de basculer
sur la version 3. Le problème avec cette nouvelle version est qu’elle utilise un protocole de commu-
nication di�érent de la version 2. Par conséquent, le code actuel de swisstopo doit être grandement
modi�é pour fonctionner. Heureusement, l’intégration de MapFish Print v3 a été facilité car le projet
ngeo (un concurrent de map.geo.admin.ch également développé par Camptocamp) utilise MapFish
Print v3. Comme il est également écrit en AngularJS, il a été très facile de remplacer le module en
charge de l’impression écrit par swisstopo par celui de ngeo.
Cependant, ce module n’était pas encore tout à fait prêt au moment où nous l’avons intégré. J’ai
donc participé au développement a�n de l’améliorer. J’ai notamment :
— ajouté le support de la rotation de la carte : il s’agissait juste d’ajouter un paramètre rota-tion pour MapFish Print ;
— fait en sorte que l’on puisse imprimer du texte provenant de dessins de type KML ;
— corrigé divers problèmes : impression de lignes en pointillés, impression des images, . . .
Devant ces petits désagréments et la documentation pas toujours très claire ni complète de MapFish
Print, nous avons ré�échi à la possibilité d’utiliser une autre solution. Nous avons été de plus inca-
pable de le compiler sur Java 8, la dernière version en date de Java et la seule version supportée (le
logiciel fonctionne sans problème sur cette version cependant). Sur Java 7, nous sommes incapables
de lancer correctement tous les tests. Nous utilisons donc la version compilée pour le Grand Duché
du Luxembourg.
Malheureusement, malgré tous ces défauts, MapFish Print est la seule solution convenable. S’il existe
des bibliothèques de qualité en Python et en Javascript pour créer des PDFs, elles sont toutes de très
bas niveau et elles demanderaient de développer un équivalent à MapFish Print dans ces langages
pour permettre au client d’utiliser un template et d’imprimer correctement les cartes. De plus, Map-
�sh Print v3 étant basé sur la bibliothèque Jasper Reports, les utilisateurs peuvent utiliser le logiciel
Jasper Studio pour créer facilement leur template.
Nous avons également trouvé la bibliothèque javascript jsPDF qui permet de transformer en PDF
une page web rendu dans le navigateur client. Cependant, cette solution ne gère pas les images ce qui
est discriminant pour nous. Une autre solution aurait pu être d’utiliser jsreport qui permet d’écrire
un template avec le langage Handelbars. Ce template est rendu en HTML avant d’être transformé
en PDF. Ce logiciel peut fonctionner soit sur le serveur soit dans le navigateur du client. Cependant,
le positionnement des éléments n’était pas assez précis pour nos besoins. Compte tenu du budget et
du temps imparti pour le projet, nous avons décidé d’utiliser MapFish Print.
Présentation des a�ributs
Comme on peut le voir sur la �gure 7.6, l’utilisation des attributs des couches sur map.geo.admin.ch
est assez fastidieux :
7.3. Liens avec upstream et développements spécifiques 31
Rapport de stage, Projet de géoportail, Release 1.0
Figure 7.5 – Un exemple de rapport généré par MapFish Print
32 Chapitre 7. Travail réalisé
Rapport de stage, Projet de géoportail, Release 1.0
— on ne peut connaître qu’un attribut à la fois ;
— pas d’export CSV ;
— l’impression PDF se fait pour toutes les couches sur un seul document.
Figure 7.6 – La présentation des attributs sur map.geo.admin.ch
On ne connaît les éléments que par leur identi�ant, la navigation entre les di�érentes couches est laborieuse.
Cette solution n’est pas satisfaisante dans nos cas d’usage où de nombreuses couches retournant
beaucoup d’attributs sont fréquemment interrogées. Par conséquent, nous avons ré�échi à une autre
présentation possible. Sur les portails actuels, c’est une présentation par tableau par couche qui
existe (voir �gure 6.4). Nous avons décidé de reprendre cette idée et d’améliorer son rendu grâce à
AngularJS.
Notre solution utilise ui-grid un composant AngularJS permettant de réaliser des tableaux dyna-
miques. Il permet de créer des tableaux facilement à partir d’une liste. Cette liste doit contenir des
objets Javascript avec comme clé le nom de la colonne et comme valeur le contenu de la case du
tableau. Chaque élément de la liste va alors former une ligne du tableau.
L’implémentation de cette fonctionnalité a nécessité une réécriture complète du composant Angu-larJS gérant l’a�chage des attributs. En revanche, l’API n’a pas eu besoin d’être modi�ée.
À partir de cette implémentation, en se reposant sur les possibilités de ui-grid, il a été facile
de traduire les titres et le contenu des colonnes. De plus, il est possible de modi�er l’a�chage de
certaines cases : celles-ci peuvent en e�et contenir des liens vers d’autres pages et ces liens doivent
être cliquables. Grâce à la possibilité de templating de ui-grid, il su�t de stocker dans un objet
le nom de la colonne et le template associé pour aboutir à cette fonctionnalité.
Des possibilités de �ltre sur les attributs est également possible. Cette fonctionnalité n’est pas intégré
actuellement.
Plugins
Certains portails comme le portail régional du Jura Bernois (geojb) demandent des fonctionnalités
spéci�ques qui n’ont pas à être présentes sur les autres portails. Actuellement seule la possibilité de
7.3. Liens avec upstream et développements spécifiques 33
Rapport de stage, Projet de géoportail, Release 1.0
Figure 7.7 – Notre présentation des features.
Tableau dynamique dans lequel on peut déplacer les colonnes, les masquer, trié par n’importe laquelle. On
peut également exporter ce tableau au format PDF ou CSV.
connaître le nom de la commune lors de l’impression est requise sur geojb, le régional portail du
Jura Bernois.
A�n de fournir ces fonctionnalités uniquement sur le portail qui en a besoin et pour éviter de faire
télécharger du code inutile à l’utilisateur, j’ai développé un système de plugin. Ce système pourra
être réutilisé pour d’autres fonctionnalités dans le futur.
Le système fonctionne de la façon suivante :
— on enregistre les plugins utilisés dans un portail par leur nom dans le �chier de con�guration
du-dit portail ;
— à la racine du projet, il existe un �chier de template SigeomPlugins.nunjucks.js.
C’est dans ce �chier template que va être mis le code des plugins. Il faut faire attention à ce
que toutes les dépendances nécessaires aux plugins soient bien injectées dans le service dé�ni
dans ce template.
1 {#2 This is a template file which will contain the code for all3 activated plugins.4 If a plugin is available but not activated, it is replaced5 by a function that returns undefined. This way, the call6 to a not activated plugin will not fail.7 #}8 // We use gaGlobalOptions but we don't explicitely require9 // goog.require('ga'); because closure-compiler will crash due
10 // to circular dependencies.11 goog.require('sigeom');12
13 goog.provide('sigeom_plugins');14 (function() {15 sigeomModule.factory('sgPlugins', function($http, gaGlobalOptions) {16 var plugins = {};17 {% for pluginName in activatedPlugins %}18 plugins['${pluginName}'] = ${availablePlugins[pluginName]}19 {% endfor %}20
21 return plugins;22 });23 })();
1. le script de construction va lire le �chier contenant le code des plugins activés. Le code
de ces plugins est mis dans un objet activatedPlugins avec comme clé le nom du
plugin ;
2. chaque plugin actif est enregistré dans l’objet plugins du service AngularJS ;
34 Chapitre 7. Travail réalisé
Rapport de stage, Projet de géoportail, Release 1.0
3. on retourne cet objet a�n qu’il puisse être utilisé.
— on crée un �chier Javascript avec le nom du plugin dans un sous dossier plugins ;
— on écrit le code du plugin dans ce �chier. Ce �chier ne peut contenir qu’une seule fonction
a�n d’être correctement enregistré dans l’objet plugins évoqué précédemment ;
— pour utiliser un plugin, on commence par véri�er qu’il est bien actif pour ce portail. Par
exemple pour le plugin communes :
if (sgPlugins.communes) {sgPlugins.communes(mapCenter)
.success(doPrint)// If we cannot get the commune name,// launch the print anyway
.error(doPrint);} else {
doPrint();}
Ce code fonctionne car :
1. si le plugin n’est pas actif, alors la clé communes n’est pas dans l’objet sgPlugins.
sgPlugins.communes renvoie alors undefined ce qui est évalué comme étant
faux dans la condition ;
2. s’il est actif, sgPlugins.communes est une fonction ce qui est évalué à vrai ;
3. on peut alors utiliser le plugin sans problème.
Ce système est donc à la fois simple à utiliser et puissant. Il convient pour notre usage et pourra
remplir sans problème son o�ce dans des cas plus complexes.
Sauvegarde des dessins via WebDav
Dernière grosse fonctionnalité en plus dans nos portails : la possibilité de sauvegarder un dessin sur
un serveur WebDav (par exemple Owncloud). swisstopo sauvegarde automatiquement les dessins
fait par les utilisateurs dans une instance Amazon. L’utilisateur dispose de deux liens pour partager
son dessin :
— le lien d’administration qui permet d’éditer ce dessin plus tard ;
— le lien de partage qui permet d’importer automatiquement le dessin sur la carte. Si un uti-
lisateur édite le dessin via ce lien, une copie sera réalisée et il disposera d’un nouveau lien
d’administration.
Si cette fonctionnalité permet de partager des dessins rapidement, il nous semblait intéressant de
permettre à l’utilisateur de ne sauvegarder le dessin que s’il le souhaitait.
Le client nous a également demandé d’avoir la possibilité de sauvegarder le dessin dans le Owncloud
(logiciel de partage de �chier, calendrier et contact) de l’entreprise. Cette fonctionnalité permettrait :
— d’avoir des dessins privés, l’accès à Owncloud étant protégé par un mot de passe ;
— de pouvoir éditer facilement des dessins depuis un autre logiciel et de les importer aisément
sur le géoportail ;
— de synchroniser le dessin entre plusieurs machines/utilisateurs grâce au client de synchroni-
sation.
Pour implémenter cette fonctionnalité, j’ai commencé en modi�ant les outils de dessin de swisstopo.
Cela m’a permis d’aboutir rapidement à un prototype utilisable. J’ai ensuite déplacé cette fonction-
nalité dans son propre module a�n de pouvoir plus facilement la faire évoluer indépendemment du
code de swisstopo. En e�et, nous leur avons proposé cette fonctionnalité mais elle a été rejetée car
7.3. Liens avec upstream et développements spécifiques 35
Rapport de stage, Projet de géoportail, Release 1.0
swisstopo n’est pas convaincu de son intérêt et ne veut pas de code « inutile » à maintenir. Peut-être
cette opinion changera-t-elle dans le futur ?
Ce qui a posé le plus de problème ici n’est pas tant la fonctionnalité en elle même : il su�t de
faire une requête PUT avec les bons entêtes à l’URL fournie mais l’impossibilité pour un navigateur
de faire une requête vers un autre domaine que celui sur lequel il est sans les bons entêtes. Par
exemple, je visite http://ioda.net et je fais une requête en javascript vers http://centrale-marseille.fr.
Si http://centrale-marseille.fr ne répond pas avec l’entête HTTP Access-Control-Allow-Origin: "*", la requête est annulée. Le nom de cette interdiction est CORS pour Cross Origin
Resources Sharing (partage de ressources de provenances di�érentes). Elle est présente dans tous les
navigateurs récents pour des raisons de sécurité : cela empêche d’utiliser une ressource provenant
d’un site qui ne l’autorise pas explicitement. Cela permet d’éviter certains cas de cross site script
(XSS).
La con�guration correcte du serveur Webdav est donc le point clé de cette fonctionnalité et elle a
demandé un peu de temps avant d’être correcte.
L’autre point important est la gestion des erreurs : si l’utilisateur ne peut pas faire une action, il
faut réussir à l’informer correctement grâce à un message explicatif : dessin non trouvé, accès non
autorisé, . . . La détection d’un problème CORS et l’a�chage d’un message utile à l’utilisateur est
également indispensable. Cette gestion des erreurs est assez aisée à réaliser : chaque requête a un
statut associé qui indique son état (réussie, page non trouvée, accès non autorisé, . . . ). À partir de
statut, il est donc facile de trouver le message à a�cher.
Cette fonctionnalité peut encore être améliorée :
— la présentation des champs URL, �chier, nom d’utilisateur et mot de passe prend beaucoup
de place ce qui est dommageable notamment sur les petits écrans. Il faudrait soit avoir la
possibilité de réduire ces champs, soit les mettre dans une « boîte » qui s’ouvrirait sur le côté.
Voir la �gure 7.8 ;
— le dessin ainsi sauvegardé ne peut pas être importé automatiquement. Il faudrait si un tel
dessin est détecté permettre à l’utilisateur de s’authenti�er et charger le dessin sans repasser
par l’outil ;
— il faudrait également permettre à l’utilisateur de charger un dessin via Webdav en passant
non pas uniquement par l’outil de dessin mais également par l’outil permettant d’importer
des KML.
Dès que les retours utilisateurs auront été su�sants, nous comptons mettre en place ces améliora-
tions.
7.3.2.2 API
L’API qui a pour but de fournir les services nécessaires au fonctionnement du frontend comme le
raccourcisseur de liens, la recherche ou les pro�ls altimétriques, est de loin le programme qui di�ère
le plus avec swisstopo. Ce programme est en e�et très lié à leurs données :
— il contient toutes les informations et la description d’une partie du schéma de la base de
données. Cette partie de la base de données est principalement utilisée pour donner la con�-
guration des couches et l’organisation du catalogue. Ces parties ne nous sont pas utiles, voir
Infrastructure ;
— il contient des templates pour certaines popups comme celles activées lorsqu’on demande
des informations sur les couches. Ces templates ne nous sont pas utiles car ils sont liées aux
couches de swisstopo. De plus, nous avons modi�é le fonctionnement du frontend a�n qu’il
utilise un �chier JSON créé via l’infrastructure pour a�cher ces informations au lieu d’utiliser
des templates HTML. Voir Infrastructure ;
36 Chapitre 7. Travail réalisé
Rapport de stage, Projet de géoportail, Release 1.0
Figure 7.8 – Les options de sauvegardes de dessin
7.3. Liens avec upstream et développements spécifiques 37
Rapport de stage, Projet de géoportail, Release 1.0
— il contient un �chier Python permettant au programme d’interroger la base de données pour
récupérer les attributs de chaque couche. Ces �chiers décrivent pour chaque table ses co-
lonnes. Cela permet de récupérer les informations dans la base puis de créer une page HTML à
partir d’un template. Ce fonctionnement est acceptable pour swisstopo car même s’ils ajoutent
régulièrement des couches, une fois ajoutées les couches ne bougent que très peu. En e�et,
avant d’être ajoutées, elles doivent passer un processus de validation assez lourd. Elles sont
également publiées dans un catalogue européen regroupant les couches de divers o�ces de
topographie. Les couches de notre client, sigeom sa, sont en revanche modi�ées régulière-
ment. Ce modèle d’interrogation très �gé n’est donc pas adapté et demande à être modi�é ;
— il utilise certaines dépendances pour gérer les traductions qui ne nous sont pas utiles car nous
avons décidé de gérer toutes les traductions dans le frontend ;
— swisstopo n’a qu’un seul géoportail alors que sigeom sa en a une vingtaine. A�n de simpli�er
la maintenance, nous avons décidé de n’utiliser qu’une seule API pour tous les géoportails ce
qui implique de pouvoir discerner les di�érents géoportails pour certaines actions telle que
la recherche. Voir multiportails pour plus de détails ;
— Il fonctionne avec Python 2 et swisstopo n’a pas l’intention de passer sous Python 3 dans un
futur proche : Python 3 n’est actuellement pas déployé sur leur serveur et demanderait une
longue phase de test avant d’y être accepté. Or a�n d’assurer au maximum la pérennité du
projet et d’éviter une phase de transition, nous avons décidé d’utiliser directement la version
3 de python :
— Python 2 n’est supporté que jusqu’en 2020 ;
— Python 3 est la version de python qui apporte de nouvelles fonctionnalités et corrige ou
améliorent les fonctionnalités existantes ;
Malheureusement, les versions python 2 et Python 3 ne sont pas tout à fait compatibles ce qui de-
mande un travail d’adaptation. Certaines modi�cations ont été faciles à réaliser. Par exemple, la
suppression des templates ou la description des tables. D’autres comme le passage en Python 3 ont
demandé un peu plus de travail.
Python 3
Du code écrit pour Python 2 n’est pas intégralement compatible avec Python 3. Cependant, si comme
l’API de swisstopo, le projet est assez récent et écrit pour Python 2.7 (la dernière version de Python
2), a priori peu de changements sont nécessaires. Dans notre cas, cela consistait principalement en :
— la modi�cation d’imports de certains modules ayant été réorganisés en Python 3
— l’utilisation du mot clé print qui est une fonction en Python 3
— la suppression de dépendances qui n’existaient que pour ajouter des fonctionnalités présentes
dans Python 3 à Python 2.
J’ai également pro�té de cette migration pour ajouter des tests automatiques sur les fonctionnalités
de l’API.
Si cette migration s’est bien passée, elle a demandé un peu de préparation :
— j’ai commencé par mettre à jour toutes les dépendances du projet a�n de pro�ter des dernières
fonctionnalités et de correction de bugs. De plus, certains projets comme OWSLib (biblio-
thèque python permettant d’utiliser le protocol WMS) n’étaient pas encore compatibles avec
Python 3. J’ai donc participé au portage du code pour que cette bibliothèque soit compatible
avec les deux versions de Python ;
— j’ai ensuite modi�é le système de construction. Le système utilisé par swisstopo repose en
e�et sur un programme appelé buildout et de nombreuses dépendances disponibles en
Python 2 uniquement. Je suis donc passé à un Make�le, système classique de construc-
tion sur Unix. Les dépendances du projet sont installées dans un virtualenv. Un virtua-
38 Chapitre 7. Travail réalisé
Rapport de stage, Projet de géoportail, Release 1.0
lenv (pour environnement virtuel) est un outil classique en python pour installer des pa-
quets python en dehors du système. Par exemple, sous Linux, par défaut les paquets Py-
thon 3.4 sont installés dans /usr/lib/python3.4/site-packages ce qui néces-
site les droits administrateurs d’une part et d’autre part, il est considéré comme étant une
mauvaise pratique que d’installer des paquets non fournis par la distribution dans les em-
placements systèmes. En revanche, si on crée un virtualenv dans un dossier (par exemple
/home/jenselme/api/.venv), on peut, en activant ce virtualenv, installer et utiliser
les dépendances dans /home/jenselme/api/.venv/lib/python3.4/site-packages. L’installation se fait alors avec les droits utilisateurs. De plus, cela permet d’avoir
des dépendances dans des versions di�érentes pour chaque projet.
A�ributs des couches
La modi�cation la plus intéressante que j’ai faite dans l’API est sur l’interrogation des attributs
des couches. Certaines couches sont marquées comme étant interrogeables dans le frontend. Par
exemple, la couche bâtiment : si l’utilisateur clique sur un bâtiment, il peut récupérer son adresse.
Il existe plusieurs façons de réaliser cette fonctionnalité. La première est d’utiliser le protocole WMSque nous utilisons pour générer les images des cartes. Ce protocole peut également servir à récupé-
rer les informations sur les couches. Cependant, par défaut ce protocole formatte les attributs soit
en texte brut soit en XML alors que nous désirons du JSON. De plus, la sélection de tous les attributs
contenu dans un rectangle n’est pas possible. La seconde solution est d’utiliser l’API pour aller cher-
cher les informations directement en base de données. Celle-ci doit alors contenir les informations
qui peuvent être récupérées par interrogation ainsi qu’un identi�ant et la géométrie des objets. La
géométrie est indispensable pour ne retourner que les objets situés à l’endroit du clic utilisateur ou
contenu dans un rectangle précis. C’est la solution choisie par swisstopo que nous avons adaptée.
Dans notre solution, toutes les données géographiques sont dans un schéma (sorte de sous-dossier
pour le moteur de base de données PostgreSQL) appelé userdata. Ce schéma contient une table
par couche. Comme toutes les couches n’ont pas à être interrogées et que seules certaines colonnes
de ces tables présentent un intérêt pour l’interrogation des couches, nous avons décidé de faire une
vue par couches interrogeables regroupant les informations à renvoyer à l’utilisateur. Une vue cor-
respond à une sélection SQL sauvegardée. Une sélection SQL permet de récupérer les informations
contenues dans une table. Ces vues contiennent les attributs à renvoyer dans l’ordre dans lequel
l’utilisateur doit les voir et sont stockées dans le schéma features.
Si swisstopo utilise un �chier python par couche interrogeable pour accéder à ces données, cela n’est
pas envisageable dans notre cas :
— les couches sont souvent sujettes à modi�cation avec des attributs en plus ou en moins ;
— des couches sont régulièrement ajoutées ;
— le client n’a pas accès au code de l’API.
Par conséquent, il nous faut une solution automatique permettant à partir de ces vues de créer les
classes Python (il faut bien une classe par table ou vue pour et pas un objet) permettant l’interroga-
tion des couches. Il nous faut également un moyen de faire correspondre :
— à chaque nom de couche le nom de la vue à utiliser. Il faut également noter qu’une vue « fea-
ture » peut être associée à plusieurs couches. Par exemple, l’utilisateur a à sa disposition
plusieurs couches de points �xes qu’il peut a�cher à sa guise mais toutes ces couches inter-
rogent la même vue ;
— la liste des portails pour lesquels une vue « feature » est disponible.
Cette correspondance est assurée par la tablemap_layers_features du schémafeatures.
Cette table est constituée par le nom de la vue feature et par deux tableaux :
— le tableau des noms des portails pour lesquels cette vue est disponible ;
7.3. Liens avec upstream et développements spécifiques 39
Rapport de stage, Projet de géoportail, Release 1.0
— le tableau des noms des couches pour lesquelles cette vue est disponible.
Cette table est décrite par la classe MapLayersFeatures en python.
1 class MapLayersFeatures(Base):2 __tablename__ = 'map_layers_features'3 __table_args__ = ({'schema': 'features', 'autoload': False})4 feature = Column(Text(200), primary_key=True)5 portal_names = Column(ARRAY(Text(200)))6 layer_names = Column(ARRAY(Text(200)))
L’aspect création de classes de façon dynamique pour permettre l’interrogation des vues est pos-
sible grâce aux fonctionnalités de ré�ection de SQLAlchemy, la bibliothèque que nous utilisons pour
communiquer avec les bases de données et les capacités de python pour la méta-programmation,
c’est-à-dire les capacités pour un programme de s’écrire lui même. Regardons de plus près comment
fonctionne la fonction register_features qui est en charge de cette création.
9 def register_features():10 for engine in engines.values():11 features_names = _get_feature_names(engine)12 session = Session(bind=engine)13 meta = MetaData(bind=engine, schema='features')14 for feature in features_names:15 try:16 map_layers_features = session.query(MapLayersFeatures)\17 .filter(MapLayersFeatures.feature == feature)\18 .one()19 except NoResultFound:20 # We may encounter view that exist but for which the21 # mapping has not been created yet.22 continue23 FeatureModel = \24 _get_feature_model(meta, map_layers_features, feature)25 _register(26 map_layers_features.portal_names,27 map_layers_features.layer_names,28 FeatureModel)
1. Comme swisstopo a plusieurs bases de données, à la ligne 10, on boucle sur l’ensemble des
bases disponibles. Cette fonctionnalité ne nous est pas utile actuellement mais comme elle
impacte peu le code, nous l’avons laissée.
2. À la ligne 11, nous récupérons la liste des vues. Pour ce faire, nous créons un « inspecteur » à
partir du moteur de la base de données. Celui-ci nous permet ensuite facilement de récupérer
la liste des vues
31 def _get_feature_names(engine):32 insp = inspect(engine)33 return insp.get_view_names(schema='features')
3. Nous pouvons ensuite boucler sur chaque vue à la ligne 14 après avoir créé un objet Ses-sion qui permet de faire des requêtes sur la base de données et un objet MetaData qui
contient diverses informations nécessaires à la création d’un objet de type Table. Cet objet
est l’un des attributs de la classe que nous désirons créer.
40 Chapitre 7. Travail réalisé
Rapport de stage, Projet de géoportail, Release 1.0
4. Aux lignes 15-22, on tente de récupérer l’enregistrement de la table
map_layers_features qui correspond à la vue que l’on est en train de traiter.
Il est possible qu’une vue existe mais ne soit pas encore activée et donc non présente dans
cette table. D’où l’utilisation du try/catch pour l’exception NoResultFound.
5. À la ligne 23, nous faisons appel à la fonction qui va créer la classe dynamiquement :
36 def _get_feature_model(meta, map_layers_features, feature):37 feature_table = Table(38 feature,39 meta,40 Column('gid', BigInteger, primary_key=True, key='id'),41 autoload=True)42 return type(43 feature,44 (Base, Feature),45 {46 '__table__': feature_table,47 '__bodId__': ','.join(map_layers_features.layer_names)48 })
1. On crée l’objet Table qui décrit la table de la base de données avec les paramètres
suivants :
(a) Le nom de la table (ici de la vue).
(b) Les métadonnées que l’on a créées précédemment
(c) On spéci�e explicitement la colonne qui sert de clé primaire. Sans cette informa-
tion, SQLAlchemy ne peut pas fonctionner. De plus, dans le cas d’une vue, SQ-
LAlchemy ne peut pas détecter seul quelle colonne utiliser car cette information
bien que présente dans la table de départ n’est pas transmise à la vue.
(d) On spéci�e le paramètre autoload à vrai ce qui autorise à SQLAlchemy à char-
ger les descriptions des colonnes restantes automatiquement.
2. On peut en�n créer le type. Cela se fait avec la fonction type de python. Cette
fonction a deux utilisations :
— Donner le type d’un objet si elle est appelée avec un seul paramètre.
— Créer des types, c’est-à-dire des classes, de façon dynamique. On lui passe 3 para-
mètres :
(a) Le nom du type à créer. Ce doit être une chaîne de caractères.
(b) La liste des classes dont la nouvelle classe doit hériter. IciBase qui contient des
informations génériques sur notre base de données et Feature qui contient
toutes les méthodes facilitant l’interrogation et la mise en forme des attributs.
(c) Le dictionnaire des méthodes et attributs. Ici nous injectons l’objet décrivant
la table créée précédemment qui est commun à toutes les instances de notre
nouvelle classe. De même, nous donnons un identi�ant __bodId__ à cette
classe. Cet identi�ant est constitué de la liste des couches qui peuvent utiliser
cette vue séparée par des virgules. Cet identi�ant est utilisé pour l’a�chage
des features.
6. En�n, nous enregistrons la classe créée dans le dictionnaire global qui fait la correspondance
entre le portail, le nom de la couche et la classe d’interrogation de la vue :
7.3. Liens avec upstream et développements spécifiques 41
Rapport de stage, Projet de géoportail, Release 1.0
51 def _register(portal_names, layer_names, feature_class):52 for portal_name in portal_names:53 for layer_name in layer_names:54 registered_features.setdefault(portal_name, {})\55 .setdefault(layer_name, [])\56 .append(feature_class)
7.3.2.3 Infrastructure
L’infrastructure qui soutient notre projet de géoportail doit nous permettre :
— de gérer plusieurs portails :
— chaque portail a une con�guration spéci�que : chacun a son jeu de couches (certaines
couches peuvent être communes à plusieurs géportails), sa liste de sujet, son catalogue,
son serveur WMS, . . . ;
— chaque portail existe en version de production et en version de développement : la version
de développement utilise notamment des �chiers non mini�és pour simpli�er le débog-
gage. L’utilisation de sourcemaps, qui permettent d’utiliser les �chiers de production en dé-
veloppement, a été exclue car jugée trop complexe à intégrer dans le processus de construc-
tion. En e�et, certains �chiers sont mini�és par le closure compiler , d’autres comme Open
Layers ont une version de développement et une version de production. Il est donc très
di�cile d’aboutir à une version convenant à la production et au développement. De plus,
la nécessité d’utiliser le closure compiler pour le code de production donne des temps de
construction d’environ 2 minutes (hors rechargement de la page) ce qui est dommageable
car le retour d’informations sur les changements e�ectués est trop long.
— de gérer les traductions des di�érents portails : les éléments de l’interface sont traduits en 5
langues par swisstopo (français, allemand, italien, romanche et anglais). Cependant, certains
de nos développements spéci�ques vont ajouter des chaînes à traduire communes à tous les
portails dans l’interface (traduction en français et anglais uniquement). De plus, certaines
chaînes sont spéci�ques à chaque géoportail : par exemple, le titre de la page est géré comme
une traduction et doit être surchargé pour chaque géoportail ;
— de gérer la con�guration de sphinx-search un logiciel permettant de faire des re-
cherches dans du texte de façon très e�cace ;
— de gérer la con�guration et les patrons de l’impression ;
— de remplacer une partie de la base de données de swisstopo ;
— de gérer l’apparence de chaque géoportail. Cela inclus les feuilles de style CSS ainsi que les
images.
Tous ces éléments sont gérés dans un dépôt git à part, ceux-ci ne faisant ni partie du frontend, ni du
backend.
L’aspect multi portails a également une in�uence sur l’organisation du frontend et de l’API.
Pour le frontend, cela implique de pouvoir créer pour chaque géoportail une copie de développe-
ment et une copie de production. En e�et, chaque géoportail a une con�guration spéci�que. Cette
con�guration permet de générer le �chier index.html qui est servi à l’utilisateur lorsqu’il de-
mande la page du géoportail. De plus, les géoportails ne seront pas forcément tous exactement dans
la même version. Il est donc par conséquent nécessaire de pouvoir travailler de façon indépendante
sur chaque portail.
A�n de remplir cet objectif, nous avons dû nous éloigner du fonctionnement de swisstopo. swisstopon’a qu’un seul géoportail à gérer (en version de développement et de production). Pour générer
sa version de développement, swisstopo utilise un Make�le qui va générer les �chiers à partir de la
42 Chapitre 7. Travail réalisé
Rapport de stage, Projet de géoportail, Release 1.0
con�guration et des patrons directement dans le dossier source. La version de production est générée
à l’aide du même Make�le mais dans un sous dossier prd. La con�guration du projet est faite dans
le Make�le via des variables qui peuvent être remplacées par celle de l’environnement.
Les problèmes avec cette méthode sont :
— de charger les bonnes variables d’environnement avant le premier lancement duMake�le. Ces
variables d’environnement sont spéci�ques à chaque développeur et sont di�érentes suivant
que l’on déploie en développement ou en production. Certaines varient également d’un portail
à l’autre ;
— la fragmentation des outils utilisés : la génération des �chiers à partir des patrons est réalisée
en python, de même que la mini�cation du html. En revanche, la génération du thème et le
lancement des tests reposent sur des technologies javascript.L’avantage principal réside dans la facilité avec laquelle il est possible d’utiliser des commandes.
A�n de décomposer le code en module et de pouvoir utiliser ces modules correctement, swisstopoutilise le closure compiler de Google. Cette suite d’outils, écrite en Java et en Python, permet :
— d’utiliser un système de modules en Javascripts (qui en était dépourvu jusqu’à la récente
norme ES6 supportée partiellement par les navigateurs) ;
— de compiler le code javascript en javascript optimisé a�n d’améliorer le temps de chargement
et d’exécution.
Cette suite d’outil ne peut s’utiliser qu’en ligne de commande.
Nous avons décidé de changer d’outil et d’utiliser gulp un lanceur de tâche javascript. Cela nous a
permis de :
— réduire le nombre de technologies di�érentes utilisées ;
— d’utiliser plus facilement un �chier de con�guration ;
— de conserver la souplesse d’un Make�le grâce au gulpfile, le �chier de con�guration de
gulp qui permet en outre d’avoir la puissance du javascript ;
— de pouvoir dès qu’une mise à jour est e�ectuée sur le code source, de mettre à jour la copie
de développement en quelques dizaines de milli-secondes.
Cet outil nous permet également de lancer des commandes même s’il est un peu moins pratique pour
cela qu’un Make�le. Ces commandes sont alors écrites dans des chaînes de caractères javascript au
lieu d’être identi�ées comme de vraies commandes shell par l’éditeur de texte.
Concernant l’API, nous nous sommes posés la question de savoir s’il fallait une API par géoportail ou
si une API commune pouvait convenir. Ce deuxième choix ayant bien évidement l’avantage d’être
plus simple et nous éviterait d’avoir à maintenir plusieurs API. Après ré�exion, il se trouve qu’une
seule API est su�sante : si dans sa communication avec l’API, le frontend transmet le nom du portail,
il est possible sans trop de di�culté de fournir des résultats correspondants à chaque portail.
Base de données
De part le nombre de couches disponibles et la durée du projet, les données géographiques de swiss-topo sont réparties dans plusieurs bases de données. A�n de fournir les informations sur les couches
disponibles et sur leur organisation en sujet et catalogue, swisstopo utilise une base de données spé-
ci�que qui contient di�érentes tables décrivant les sujets et le catalogue.
Comme nous n’avons pas accès à l’organisation véritable de la base de données, il nous a semblé
di�cile d’utiliser directement leur schéma :
— le nom de certaines tables semble indiquer que ce sont en réalité des vues, ie un SELECTsauvegardé ;
— swisstopo ne veut pas donner l’organisation de ces bases de données car cette organisation est
susceptible de changer.
7.3. Liens avec upstream et développements spécifiques 43
Rapport de stage, Projet de géoportail, Release 1.0
Ces tables ont pour seule raison d’exister de permettre à l’API de générer les JSON de con�guration
du frontend. Or pour les générer, nous avons besoin de :
— la liste des couches disponibles : cette liste peut être donnée par le serveur WMS en charge
de générer les images PNG à partir des données géographiques présentes en base. En plus de
la liste des couches, pour chacune d’entre elles, ce serveur sait si elles ont une légende, sont
interrogeables, quelle est leur description, . . . Par conséquent, les informations présentes dans
la base de données de swisstopo sur les couches viennent en redondance de ce que le serveur
WMS doit être capable de fournir à partir ;
— la liste des couches externes disponibles : en plus des couches fournies à partir des géodonnées
du client, certains portails ont besoin de couches externes par exemple fournies par le canton.
Ces couches peuvent être décrites dans des �chiers et n’ont pas besoin d’être en base de
données ;
— l’organisation des couches dans le catalogue et en thèmes : cette organisation peut être décrite
dans des �chiers de con�guration.
Suite à cette analyse, nous avons décidé de nous passer de cette partie de la base de données. Les
informations nécessaires sont écrites dans des �chiers JSON suivis par git dans notre dépôt d’in-
frastructure. Les JSON nécessaires au frontend sont ensuite générés à partir de ces données. Nous
avons ensuite con�guré le serveur web pour qu’il prenne ces �chiers directement dans le dossier où
ils ont été générés plutôt que de transmettre cette requête à l’API. Un ensemble de scripts Python et
Javascript lancé avec gulp, le lanceur de tâche javascript également utilisé dans le frontend, nous
permet de créer ces �chiers facilement.
7.3.2.4 Multiportails
Un des aspects les plus importants de notre projet est la gestion du multiportail. En e�et, à l’heure
actuelle, sigeom sa a besoin d’environ 20 portails pour des communes principalement. Comme swiss-topo ne gère que le portail fédéral, c’est un problème qui n’est pas présent pour eux. Cet aspect a
déjà été succinctement évoqué dans les sections précédentes. Nous donnons ici plus de détails.
Chaque frontend doit être spéci�que à un portail. En e�et, le logo, le nom du portail et la con�gu-
ration des couches ne sont pas génériques. A�n de remplir cet objectif, nous utilisons deux choses :
— nous construisons chaque frontend dans un dossier dédié : prod/portal_name. Dans ce
dossier se trouve tout le code javascript ainsi que le HTML. Une distinction similaire existe
pour le développement a�n de pouvoir tester les di�érents portails facilement ;
— nous créons les �chiers de con�guration des couches via notre infrastructure. Celle-ci
contient également les traductions et les images. Le résultat est comme précédemment écrit
dans un dossier spéci�que à chaque portail.
Une fois les deux parties générées, elles sont regroupées dans le même dossier dans l’infrastructure.
Ce regroupement a pour but de faciliter le déploiement en production sur le serveur : on a un seul
dossier à gérer au lieu de deux.
A�n de faciliter le déploiement en production et d’avoir la capacité de revenir à une version an-
térieure de l’application facilement, nous avons décidé de placer le résultat de la construction de
chaque portail dans un dépôt git dédié. Lorsqu’un portail est prêt pour un déploiement en produc-
tion, on le génère, on enregistre le résultat dans git, on étiquette ce résultat avec la date du jour au
format aaaa-mm-jj-hh-MM puis on pousse le résultat sur le serveur de production. Ainsi, si on a
besoin de revenir en arrière, il su�t de :
1. lister toutes les étiquettes du dépôt ;
2. de les trier par date ;
3. de choisir l’avant dernière date ;
44 Chapitre 7. Travail réalisé
Rapport de stage, Projet de géoportail, Release 1.0
4. de se placer sur la version étiquetée par cette date.
Cela se réalise facilement en ligne de commande :
git checkout $(git tag | sort -nr | head -n 2 | tail -n 1)
Concernant l’API cependant, la plupart des fonctionnalités sont communes à tous les géoportails
telles que le raccourcisseur d’URL, le qrcode ou les pro�ls de terrains. D’autres sont légèrement
di�érentes suivant les portails : la recherche notamment qui permet de rechercher parmi les adresses
disponibles sur un portail et les couches activables sur celui-ci. D’autres en�n comme la possibilité
de donner le nom de la commune à un point donné n’ont d’utilité que sur le portail régional geojb
et ne sont d’aucune utilité sur un portail communal.
Il pourrait donc être tentant de créer une API par portail a�n de choisir quelle fonctionnalité activer
et comment ces fonctionnalités doivent se comporter. Cependant, cela complexi�e la mise en pro-
duction et la maintenance. Avoir une seule API pour tous les portails serait donc préférable. Cela est
réalisable sans trop di�culté :
— les fonctionnalités communes ne posent évidemment pas de problème ;
— pour les fonctionnalités qui di�èrent par portail (à savoir la recherche et l’interrogation d’at-
tributs), il est facile si le portail passe un identi�ant (son nom dans notre cas) de modi�er le
comportement de ces fonctionnalités d’autant plus que les comportements spéci�ques n’ont
pas besoin de code particulier :
— la recherche repose sur sphinxsearch un moteur de recherche de texte écrit en C++ et
publié par Sphinx Techonologies Inc. sous licence GPLv2. Pour fonctionner correctement,
sphinx doit construire des index à partir des données à chercher. Dans notre cas, il se
connecte à la base de données et lit une vue search.communes pour les recherches
de lieu. Comme la récupération des données utilise une requête SQL, il est facile d’utiliser
des �ltres pour indexer uniquement les résultats qui doivent être accessibles sur un portail
donné. La liste des couches disponibles est quant à elle écrite dans un �chier que sphinx
peut lire pour construire son index. On construit ainsi un index par portail. Le frontend
n’a plus qu’à envoyer le nom du portail lors de sa requête de recherche pour que l’API
choisisse le bon index ;
— la recherche par attribut utilise une table spéci�que pour faire les liens entre les couches
interrogeables, les tables dans lesquelles se trouvent l’information et le nom du portail.
Voir API pour plus de détails.
— les fonctionnalités très spéci�ques à un géoportail sont activées dans le frontend grâce à un
système de plugins. Voir Frontend pour plus de détails.
7.3. Liens avec upstream et développements spécifiques 45
Rapport de stage, Projet de géoportail, Release 1.0
46 Chapitre 7. Travail réalisé
8 Contributions Open Source
Lors de mon stage, j’ai eu l’occasion de participer à des projets Open Source en plus de mes contribu-
tions au projet de géoportail de swisstopo. Ces contributions peuvent être divisées en deux grandes
parties :
— participation au packaging pour la distribution fedora ;
— participation au développement du plugin Python pour l’environnement de développement
netbeans.
8.1 Fedora
Chaque distribution linux utilise un système de paquets pour installer ses logiciels : au lieu de cher-
cher et télécharger les logiciels soit même, on passe par un gestionnaire de paquets. Ce gestionnaire
a deux fonctions principales :
— faciliter la création du paquet par un utilisateur appelé packageur. C’est cet utilisateur qui
écrit dans un �chier dédié la suite des étapes à réaliser pour obtenir un paquet qui peut être
installé : comment et où récupérer les sources, quels patches appliquer, comment construire
le logiciel (c’est-à-dire comment passer des sources compréhensibles par un être humain à un
programme compréhensible par l’ordinateur) et comment installer le paquet ;
— faciliter l’installation et la mise à jour des logiciels pour l’utilisateur.
La distribution Fedora que j’utilise depuis plusieurs années utilise l’un des deux formats de paquets
les plus répandu : RPM (acronyme de RPM Package Manager). Les paquets sont réalisés par des
membres de la communauté d’utilisateurs qui s’engagent à maintenir le paquet. Avant d’être dispo-
nible, chaque paquet est validé par un autre packageur.
Cette partie de la contribution se divise donc en deux possibilités :
— proposer de nouveaux paquets ;
— valider des paquets proposés par d’autres.
Ces deux tâches sont essentielles pour qu’une distribution Linux soit agréable à utiliser : cela aug-
mente le nombre de logiciels disponibles et permet aux utilisateurs d’avoir con�ance dans les paquets
qu’ils installent parmi ceux o�ciellement mis à disposition.
Participer au packaging permet donc d’aider la communauté et d’améliorer la qualité d’une distri-
bution que j’a�ectionne.
8.2 Plugin nbpython
Comme signalé dans l’introduction, le développement de ce plugin qui ajoute à l’IDE Netbeans le
support de Python a été arrêté en 2013 par Oracle l’entreprise qui soutient le développement de Net-
beans. Il a été repris par une équipe de bénévoles �n 2014. Étant moi même utilisateur de Netbeans
et amateur du langage python, cela faisait quelque temps je désirais contribuer à ce plugin. Grâce
47
Rapport de stage, Projet de géoportail, Release 1.0
aux heures disponibles via ce stage, j’ai pu rejoindre l’équipe de 8 personnes qui s’est constituée
depuis �n 2014 pour faire revivre ce plugin.
À mon avis, Netbeans est un très bon environnement de développement car :
— il est libre, publié sous license GPLv2 et CDDL ;
— il est multi-platforme ;
— il supporte les langages du web par défaut (HTML5, CSS, Javascript) et a un bon support
d’AngularJS.
D’un point de vue expérience utilisateur, j’ai eu moins de problème à l’utilisation de Netbeans que de
son concurrent Eclipse que j’ai trouvé inutilisable lors de l’écriture de javascript. De plus, je trouve
l’interface plus claire et mieux organisée. En�n, il requiert moins de con�guration qu’un éditeur de
texte avancé comme Emacs pour être vraiment opérationnel ce qui est un gain de temps considérable.
Dès le début de mon stage, j’ai contacté le chef du projet a�n de savoir comment contribuer. Il m’a
suggéré de travailler sur le support de framework web tel que Django ou Pyramid. Pyramid étant le
framework utilisé par le projet de géoportails, je me suis naturellement intéressé à l’intégration de
celui-ci. Cette intégration se divise en plusieurs parties :
1. ré�exion autour des fonctionnalités à intégrer : quelles sont les fonctionnalités qu’un déve-
loppeur Pyramid attend et comment doivent-elles être présentées ?
2. comment et dans quel ordre intégrer ces fonctionnalités ? Certaines sont très conséquentes et
peuvent être réalisées en plusieurs fois. Par exemple, le support des langages de templating
qui permettent notamment de générer une page HTML personnalisée (par exemple avec le
nom de l’utilisateur) nécessitent :
(a) d’avoir un support du HTML et du CSS dans ces �chiers tel que fourni par netbeans ;
(b) d’avoir un support des fonctionnalités spéci�ques comme la mise en couleur des mots clés
du langage de template.
Si le support du HTML standard est facile et rapide à ajouter, un support complet de langage
de templating est plus long et complexe. Cette fonctionnalité va donc être réalisée en plusieurs
étapes. L’ordre permet de cibler les fonctionnalités les plus importantes pour les développer
en premier.
3. réalisation si nécessaire d’un visuel de l’interface utilisateur requise par la fonctionnalité. Voir
la �gure 8.1 pour un exemple ;
4. écriture du code implémentant la fonctionnalité.
A�n de faciliter l’organisation du projet, en plus du bug tracker de Netbeans, nous utilisons aussi
l’application web Jira pour lister et organiser le développement de nouvelles fonctionnalités. Ce
logiciel est normalement payant mais son éditeur, Atlassian, peut o�rir des licences gratuites aux
projets Open Source qui en font la demande. En�n, nous utilisons la partie chat de HipChat un
service de chat et de visio-conférence en ligne a�n de nous organiser et de discuter entre nous. Nous
n’utilisons pas la visio-conférence car elle est payante et nous n’en avons pas vraiment l’utilité.
J’ai également participé à la correction de certains bugs gênants et aidé à mettre à jour jython la
bibliothèque java permettant d’exécuter du code python sur la JVM. Cette bibliothèque est utilisée
par le plugin pour mettre en évidence les erreurs dans le code écrit par le développeur.
La participation à ce projet est intéressante pour plusieurs raisons. Elle me permet en e�et :
— d’améliorer un logiciel que j’utilise quotidiennement ;
— de travailler avec des développeurs étrangers (américain essentiellement) ;
— de travailler sur un gros projet (le plugin python est divisé en 15 sous-modules pour un peu
moins de 25.000 lignes de code en java) un peu ancien dont la qualité du code est très variable.
De plus, le projet comprend peu de tests unitaires et la plupart des fonctions demandent des
objets qu’il est très di�cile de créer juste pour un test. L’équipe étant intégralement bénévole,
48 Chapitre 8. Contributions Open Source
Rapport de stage, Projet de géoportail, Release 1.0
Figure 8.1 – L’organisation d’un projet Pyramid sous netbeans telle que je l’ai suggérée
8.2. Plugin nbpython 49
Rapport de stage, Projet de géoportail, Release 1.0
nous ne prenons pas vraiment le temps d’écrire ces tests ni de corriger ceux présents. Cela
constitue une expérience intéressante et met en avant l’utilité de se préoccuper des tests tout
au long du développement. Il faut en revanche noter que nous écrivons des tests fonctionnels.
Ces tests sont constitués par une suite d’étapes rédigée en anglais et d’un résultat bien iden-
ti�é qui doit être atteint à la �n de ces étapes. Ces tests doivent être exécutés manuellement.
Par exemple, pour le support du HTML, un test basique pourrait être :
1. ouvrir un projet web ;
2. ouvrir un �chier HTML de ce projet ;
3. résultat : la syntaxe HTML est mise en avant grâce à des couleurs.
50 Chapitre 8. Contributions Open Source
9 Conclusion
Ce stage a été très intéressant d’un point de vue technique grâce à la variété des sujets abordés. Il a
couvert :
— du développement côté serveur en Python avec le framework Pyramid pour adapter l’API
de swisstopo à notre utilisation et pour pouvoir utiliser une seule API pour gérer tous nos
portails ;
— du développement pour navigateurs en Javascript avec AngularJS pour adapter certaines
fonctionnalités aux besoins de sigeom sa et en ajouter ;
— des ré�exions sur l’infrastructure du projet en étroite collaboration avec mon tuteur a�n no-
tamment de déployer facilement et rapidement le projet de swisstopo pour gérer plusieurs
géoportails.
Il m’a également été l’occasion de mettre en application de nombreux outils et connaissances appris
tant durant les cours que durant les projets menés à l’école.
La collaboration avec swisstopo a elle aussi été très enrichissante. En e�et, certaines de nos modi�-
cations leur ont permis d’améliorer https://map.geo.admin.ch notamment par la mise en variables
de certaines options et certaines corrections de bug. De notre côté, elle nous permet :
— de réduire les di�érences entre les deux versions des programmes a�n de faciliter les mises à
jour ;
— d’entretenir des liens avec les développeurs principaux du projet ;
— de suivre l’évolution du projet plus facilement et de pouvoir l’aborder avec eux.
Il m’a aussi permis de mesurer les avantages et les inconvénients des méthodes agiles. Elles peuvent
être un vrai plus pour s’organiser et le processus itératif qu’elles recommandent pour développer
une fonctionnalité (développement, test, . . . ) est à mon avis une clé du succès pour tout projet infor-
matique. Elles peuvent également faciliter la transmission de connaissances et l’échange à travers le
pair programming. Elles peuvent aussi malheureusement être di�ciles à mettre en place. Pour les
employés d’une entreprise informatique, cela peut être rapide car ceux-ci peuvent en comprendre
rapidement les enjeux et les avantages. Pour certains clients en revanche, cela demande un change-
ment de culture qui n’est pas forcément évidemment ni facile à mettre en œuvre : chaque employé
ayant son travail et ses préoccupations, passer du temps avec les développeurs pour tester, faire des
retours rapides et réguliers et collaborer pour dé�nir les objectifs n’est pas nécessairement ressenti
comme étant prioritaire. Cela dit, si comme durant ce stage, un membre de l’équipe connaît déjà bien
les attentes du client (mon tuteur en l’occurrence) et que le prestataire fonctionne en mode agile,
le développement, bien que non optimum par manque d’une présence client, reste très e�cace et
proche d’une bonne expérience avec les méthodes agiles.
Concernant le projet géoportail à l’issue de ces six mois, il s’annonce comme une réussite. Si à l’heure
où j’écris ces lignes, ni mon stage ni le projet ne sont encore terminés (ils vont continuer pendant
encore un peu moins d’un mois), la présentation du projet, réalisée le 3 septembre 2015, a remporté
un franc succès. Celle-ci a été réalisée en présence des principaux utilisateurs du portail au sein
de sigeom sa ainsi que des collaborateurs les plus importants issus des deux bureaux de géomètres
partenaires. À la �n de celle-ci, les personnes présentes ont pu tester par elles-mêmes le portail à
51
Rapport de stage, Projet de géoportail, Release 1.0
travers de petits exercices proches de situations réelles. Ce test leur a permis de mesurer l’ampleur
du travail accompli et de se familiariser avec ce nouvel outil. Il a également été l’occasion, pour mon
tuteur et moi même, d’observer comment le portail est utilisé. Cette observation nous a permis de
trouver quelques bugs et de constater quels sont les points les plus problématiques avec la version
actuelle du portail, à savoir :
— le nombre de couches activées par défaut sur les topics qui est trop élevé ;
— le manque d’ergonomie de la zone listant les couches sélectionnées lorsque le nombre de
couche devient grand. Cette zone permet également de choisir l’ordre d’a�chage des couches
ainsi que la transparence de chacune.
Des ré�exions pour améliorer ces deux points sont en cours.
De plus, l’engagement de Ioda-Net sàrl pour l’Open Source m’a permis, grâce à des journées libé-
rées (environ une par semaine), de participer plus qu’auparavant à des projets Open Source qui me
tiennent à cœur comme Fedora ou Netbeans. En tant que développeur et utilisateur convaincu par
le modèle du logiciel libre et de l’Open Source, je trouve important de contribuer un maximum à ces
projets a�n de les améliorer et de remercier les membres de la communauté pour leurs e�orts, leur
persévérance et la qualité de leur travail.
Pour �nir, ce stage s’est déroulé dans une bonne ambiance et a été enrichissant tant techniquement
que personnellement. À l’issue de celui-ci, je suis embauché par Ioda-Net sàrl pour une durée initiale
de sept mois pour à la fois :
— continuer ce projet et en assurer la maintenance ;
— développer, en collaboration avec les parties prenantes de ce projet, l’o�re autour des géopor-
tails proposée par Ioda-Net sàrl. Le but est de partir de la base développée pendant le stage,
de l’améliorer et de trouver de nouveaux clients et utilisateurs pour cet outil.
52 Chapitre 9. Conclusion
10 Annexes
10.1 Schémas d’interaction des composants
Ces schémas ont été réalisés avec la bibliothèque javascript Cytoscape. Dans leur version web, des
informations complémentaires sont a�chées lors du clic sur un élément du graphe.
Figure 10.1 – Schéma d’interactions des composants du frontend
53
Rapport de stage, Projet de géoportail, Release 1.0
Figure 10.2 – Schéma d’interactions des composants de l’API, leur status (à jour ou non) et leur
compatibilité avec python 3.
Figure 10.3 – Schéma d’interactions des composants de l’API après le nettoyage de l’API et le passage
à python3.
54 Chapitre 10. Annexes
Index
AAngular, 5AngularJS, 5
BBackend, 5
Cclosure compiler, 5
EES6, 5
FFramework, 5Frontend, 5
GGéoportail, 5Géoportails, 5git, 6
JJavascript, 6JSON, 6
KKML, 6
MMake�le, 6
OOpen Source, 6
PPyramid, 6Python, 6
SSourcemaps, 6
Uupstream, 6
WWMS, 6
55