Carte de France en SVG
Le fichier SVG a été en partie généré par un programmme PHP.
Densité de population en France de 1975 à 2015
Les données
Les données proviennent:
- la carte SVG du site AMCHARTS Free SVG Maps - France 2016
- les données de population par région, d'un fichier excel de l'INSEE: Estimation de la population au 1 er janvier 2016
- la superficie des régions de wikipédia Classements des régions françaises
La carte
La carte provenant du site AMCHARTS est une carte au format SVG.
La viewBox
Il nous faut déterminer le plus petit rectangle (xmin, ymin, width, height)
contenant toutes les régions de la carte.
Il est possible de l'obtenir avec un éditeur de SVG tel Illustrator.
Une autre possibilité est en insérant le svg dans une page HTML, d'accéder à ces valeurs via javascript:
// Le svg est inclus dans une page HTML5 var svg = document.querySelector('svg'); var bbox = svg.getBBox(); // -Le résultat est ici
bbox = { x: 16.8203125, y: 0, width: 595.13671875, height: 583.9453125}
.
Pour afficher la “scéne” entière, il convient de définir l'attribut viewBox
du svg
avec ces valeurs (arrondies):
<svg viewBox="17 0 596 584"> <!--- etc -> </svg>
Les régions
Chaque région est définie par un path
auquel j'ai ajouté une classe spécifique à la région:
<path id="FR-A" title="Alsace-Champagne-Ardenne-Lorraine" class="land FR_A" d="M544.492,131.018l....149,0.435L544.492,131.018z"/> <!---etc...->
Projection
Très utile, pour ajouter des éléments géographiques sur la carte, la projection utilisée pour obtenir ces contours est donnée dans la balise amcharts:ammap
:
<amcharts:ammap projection="mercator" leftLongitude="-4.778054" topLatitude="51.089278" rightLongitude="9.560176" bottomLatitude="41.363005"></amcharts:ammap> <!-->
bbox
pour reconstituer la projection.Attention elle peut être modifier par l'ajout d'éléments au SVG.
Pour les calculs de projection, il est donc nécessaire d'utiliser la
bbox
de départ et de ne plus utiliser la méthode getBBox
Reconstitution de la projection de Mercator
La projection de Mercator est explicitée sur Wikipédia : Projection de Mercator.
Les formules ne sont pas hyper-explicites, elles convertiraient dans notre cas:
La position de en sa position
dans un repère centré sur la position
,
avec une largeur de
et une orientation anti-trigonométrique (comme le repère SVG) donnerait:
avec
avec
Ensuite, on change de repère en utilisant les données de la bbox
et de la projection amcharts:
on a alors à partir d'un point :
On peut ainsi ajouter par exemple un rond sur Paris après avoir converti ses coordonnées gps (48.866667, 2.333333) dans le repère du SVG :
<circle cx="312.41" cy="144.43" r="3" stroke="black" stroke-width="1" fill="red"></circle> <!-->
Insertion des données dans le SVG
Les éléments ajoutés dans le svg
Les données sont extraites du fichier excel avec la merveilleuse classe PHPExcel.
Elles sont écrites dans le svg
après les paths
comme ci-dessous:
<!-- pour la région FR_A de centre (464 = 404 + 60, 154 = 134 + 20) --> <g transform="translate(404,134)" class="FR_A"> <!-- le rectangle derrière le texte --> <rect width="120" height="40"></rect> <!-- Pour l'année 1975 --> <text class="year1975" x="5" y="9">Grand-Est - 1975 <tspan x="5" y="28">5 187 204 habs</tspan> <tspan x="5" y="37">90 hab/km2</tspan> </text> <!------....etc ----> <!-- Pour l'année 2015 --> <text class="year2015" x="5" y="9" >Grand-Est - 2015 <tspan x="5" y="28">5 559 313 habs</tspan> <tspan x="5" y="37">97 hab/km2</tspan> </text> </g>
SVG2
, il existe un attribut z-index
pour passer les éléments devant/derrière. Ce n'est pas le cas pour le SVG1
, les derniers éléments écrits sont sur le dessus. L'ordre dans lequel sont déclarés les éléments est donc important. Dans notre cas, ils sont déclarés dans l'ordre suivant:
- les
paths
des régions - les
circles
des villes - le
rectangle
suivi destextes
pour chaque région.
On peut toujours avec un peu de javascript modifier l'ordre des éléments.
Les styles
Ensuite, le CSS fait tout le travail:
→ L'opacité des régions est proportionnelle (échelle logarithmique en fait) à la densité de population,
/** la densité de population dépend de l'année sélectionnée et de la région */ svg.year1975 path.FR_A{ fill-opacity:0.373; transition: all 1s; } /** ...etc .....*/ svg.year1975 path.FR_H{ fill-opacity:0.947; transition: all 1s; }→ Sur le survol, les régions changent de couleur:
path{ fill:#616161; stroke: #f5f5f5; stroke-width:1px; transition: all 1s; } path:hover{ fill:#cb3609; }
→ Au survol des régions les données sont affichées
/** textes et rectangles sont cachés */ rect{ /* important de mettre pointer-events à none, ainsi si la souris se trouve sur le rectangle, c'est la région située en-dessous qui recevra l'événement 'hover'*/ pointer-events : none; visibility:hidden; stroke:grey; fill:#fffaf0; transition: all .6s; } text { pointer-events : none; text-anchor: start; visibility: hidden; transition: all .5s; } /** au survol de la région, le rectangle est visible et le texte de l'année sélectionnée est visible */ path.FR_A:hover ~ g.FR_A rect, svg.year1975 path.FR_A:hover ~ g.FR_A text.year1975, svg.year1980 path.FR_A:hover ~ g.FR_A text.year1980, /** ...etc .........................................*/ { visibility: visible; transition: all .5s; }
Le javascript
Il n'est utilisé que pour modifier la classe du svg
quand l'année change: year1975
, year1980
, …., year2015
.
— Elisabeth Pointal 28/06/2017 07:44