Makina Blog
Elections.js génère des cartes pour vous
Le travail sur les cartes pour les élections départementales a débouché sur la création d'un outil générique : elections.js.
Les cartes que nous avons réalisées pour les élections départementales 2015 ne nécessitent pas une expertise trop poussée de LeafletJS, mais elles ont tout de même constitué une occasion de mettre au point quelques techniques permettant de réutiliser un même javascript dans des contextes différents, afin d'assurer à l'avenir une réalisation de cartes de résultats d'élections très rapide.
Introduction
Une carte présentant des résultats électoraux est composée d'essentiellement 2 choses : une information géographique délimitant la zone concernée, et une présentation colorée des résultats. Mais pour assurer une ré-utilisabilité maximum, nous nous devons de prendre en compte un maximum de possibilités ou de formats de données.
Une fois les parties "métier" (calcul du résultats, informations textuelles de la légende) exportées dans un fichier de paramètres externe, nous nous retrouvons avec un fichier elections.js qui se concentre sur la cartographie, et peut gérer une palette de cas différents.
Des géométries variées
La plupart des grandes plateformes Open Data françaises diffusent la géographie de leur bureau de vote par "zone", et donc en polygones. C'est aussi la géométrie que nous préférons car c'est celle qui permet la visualisation la plus immédiatement compréhensible, puisque la plus habituelle. C'est donc notre géométrie de prédilection dans le script :
Cependant, la plupart des mairies qui diffusent (comme le veut la loi) la répartition des bureaux de vote le font en indiquant le nom des rues. Cela nous permet alors, en dessinant manuellement ces rues par exemple, de générer un fichier geojson de ces bureaux de vote composé de plusieurs lignes pour un bureau de vote. Pour prendre en compte ce type de représentation dans le script, il nous a suffit de modifier la façon de styler le geojson dans le cas de cette géométrie particulière. Le style étant appliqué sur chaque feature, par la fonction onEachFeature(), il nous suffit, dans cette fonction où d'habitude on style un polygone, de modifier le style utilisé pour l'adapter aux lignes :
if (feature.geometry.type == 'MultiLineString') { layer.setStyle({color: couleur, weight: 4, opacity: 1}); }
En affectant le poids et l'opacité de la zone, le résultat est certes différent des polygones, mais la coloration politique de chaque zone est immédiatement reconnaissable également :
Enfin, d'autres plateformes fournissent les bureaux de vote en indiquant uniquement l'adresse du bureau de vote, nous amenant alors à ruser un peu : dans la mesure où ce qui nous intéresse est de styler automatiquement la zone d'après la couleur du parti, nous utilisons une fonctionnalité de Leaflet permettant d'utiliser des cercles SVG à la place des marqueurs de point par défaut. Cette fonctionnalité est réalisable grâce à une fonction pointToLayer() passée en paramètre à la construction du GeoJSON. Par chance, cette fonction n'affecte pas les géométries lignes ou polygones, nous pouvons donc la laisser en permanence, elle ne s'appliquera qu'en cas de besoin :
$.getJSON('contours.geojson', function(data) { var layer = L.geoJson(data, { onEachFeature: onEachFeature, // fonction citée précédemment pointToLayer: function (feature, latlng) { return L.circleMarker(latlng); } }); });
Grâce à cette astuce, nous stylons les points comme les polygones, et le résultat, moins joli à mon goût que les précédents, est tout de même lisible :
Des formats géographiques plus ou moins optimisés
Beaucoup de GeoJSON sont des collections de Features, néanmoins, pour optimiser les topologies, on utilise également parfois des TopoJSON. Leaflet ne les gère pas nativement, cependant, il suffit d'y ajouter le plugin Leaflet-omnivore pour gérer ce format :
var tempLayer = L.geoJson(null, { style: {color: '#293133'} }); var realLayer = omnivore.geojson('data/source.geojson', null, tempLayer);
Une prise en compte de scrutins à 2 tours
Le script de base est conçu pour récupérer un seul fichier de résultats, l'utiliser pour styler le GeoJSON des géographies concernées par le vote, et l'afficher. Pour prendre en compte le deuxième tour, il suffit de récupérer un deuxième fichier de résultats, et, s'il est présent, de réaliser les traitements d'ergonomie sur la carte : ajouter une liste des 2 couches, retirer celle du premier tour de la carte pour que celle du deuxième tour soit affichée par défaut, et c'est tout, Leaflet et sa gestion des couches fait le reste pour nous :
var layers = L.control.layers(null, null, {collapsed: false, position: 'topleft'}); layers.addBaseLayer(tour1Layer, '1er tour'); map.removeLayer(tour1Layer); layers.addBaseLayer(tour2Layer, '2ème tour'); layers.addTo(self.map);
Les couches sont ajoutées comme baseLayer pour être rendues comme des boutons radios, et non comme des cases à cocher (on ne veut pas avoir les 2 en même temps). Leaflet fait le reste pour nous.
Quelques améliorations d'ergonomie
Ajout d'une couche supplémentaire
Nous travaillons sur des données géographiques, il peut être utile d'aider le visiteur à se retrouver, par exemples les régions sur une carte des départements, les cantons sur une carte des bureaux de vote. Pour ça, elections.js supporte un paramètre additionalLayer qui permet d'ajouter une couche géographique supplémentaire (c'est celle qui représente les limites de Fougères sur la deuxième carte de cette article, ou les limites des régions sur notre carte des départements).
Une interface épurée
Leaflet séduit dans un contexte de webmapping moderne en partie grâce à son interface épurée. Pour poursuivre cet objectif, dans la mesure où nous disposons d'un script générique, nous maintenons cette idée, par exemple en supprimant le contrôle de Zoom si le zoom minimal est égal au zoom maximal : à l'initialisation de la map, un simple
zoomControl: (options.minZoom != options.maxZoom)
fait l'affaire !
Pour profiter pleinenement de la carte, même embarquée dans une page web (de site de presse, par exemple), nous utilisons également le plugin Leaflet.fullscreen, permettant au visiteur d'agrandir la zone de carte, et ce sans aucune action nécessaire du côté du site intégrant la carte.
Un fond personnalisé
Enfin, une de nos caractéristiques est d'utiliser régulièrement des fonds personnalisés (comme sur ces cartes historiques ou sur ce fond très travaillé). Pour améliorer le contraste de nos cartes, nous utilisons cette fois encore un fond personnalisé (embarqué par défaut dans le script elections.js).
Conclusion
Il est tout à fait possible que elections.js ne soit pas directement réutilisable dans votre contexte (notamment toute la partie du code assurant la communication pour des intégrations en iframe), cependant vous y trouverez probablement une grosse base de travail pour des cartes de résultats d'élections. Et nous allons de toute façon encore y travailler, pour plus de réutilisabilité, et plus de possibilités !
N'hésitez pas d'ailleurs à nous proposer des améliorations (et même à proposer des Pull Requests ;-)).
Enfin, si vous bloquez dans la réalisation de cartes évoluées ou souhaitez vous aussi utiliser des fonds personnalisés, contactez-nous !
Actualités en lien
Mini-guide à l’usage des collectivités : l’Open Data, entre nécessité et opportunité
Tout ce que vous avez toujours voulu savoir sur l’Open Data. Petit guide à destination des collectivités pour l’appréhender et se l’approprier.
Une rentrée riche autour de la donnée et des rencontres pour Makina Corpus Territoires
Chaque rentrée apporte son lot d’opportunités pour faire avancer les projets autour de la données au service des territoires. Le calendrier de Makina Corpus en la matière a été particulièrement dense en événements.
GeoDatadays 2024 : retrouvez-nous et participez à nos conférences
Les 19 et 20 septembre, participez aux conférences animées par nos experts SIG aux GeoDataDays 2024, en Pays de la Loire à Nantes.