DO-cartographie/chapitres/annexe1.tex
2023-09-01 11:37:06 +02:00

452 lines
40 KiB
TeX

\chapter{Leaflet}\label{annexe:leaflet}
Umap est un logiciel particulièrement attrayant car il permet d'obtenir relativement rapidement un résultat convenable, c'est-à-dire essentiellement des marqueurs de POI (points d'intérêts) de différents types avec des bulles de texte et d'images. On peut aussi mettre des lignes et des surfaces faites de points. Il permet également de gérer différents calques.
Il permet aussi de travailler sur des sites mis à disposition par une communauté comme \emph{\url{https://umap.openstreetmap.fr}} ou \emph{\url{https://umap.osm.ch/fr/}}. Ces sites rendent la carte immédiatement disponible et il est possible, moyennant inscription, de travailler sur des cartes mises à disposition de tous tout en verrouillant les informations qui s'y trouvent.
Cependant, certains de ces sites ne disposent que d'un nombre limité de fonds de carte et surtout les éléments mis à disposition par Umap restent limités. Ce n'est pas un reproche, et même souvent un avantage rendant simple la création des cartes, mais ne permettant pas toujours de réaliser au mieux des cartes particulières, il peut devenir souhaitable de découvrir des logiciels plus développés.
Par exemple, avec Umap, la taille des icones n'est pas modifiable, il n'existe pas de formes directement circulaires \dots
\smallskip
Ainsi, pour de la cartographie orientée vers le web, des solutions plus évoluées existent. Cependant, celles-ci sont évidemment moins facile à mettre en \oe uvre. L'une de celles-ci, entre les deux extrêmes que sont Umap et le triptyque \emph{PostGIS, OpenLayers et MapServer} (voir \cite{Collado}), se nomme \emph{Leaflet}.
Différents documents d'introduction sont disponibles sur le net. Parmi ceux-ci, il faut relever \emph{Des cartes sur votre site} d'Eskimon (voir \cite{Eskimon}) qui est non seulement intéressante de part la clarté de son introduction, mais aussi par le fait que celle-ci est fourni en pdf, epub et tex sous licence libre. De même pour une utilisation avancée de Leaflet avec le même site \emph{\url{https://zestedesavoir.com/rechercher/?q=leaflet}} et l'article \emph{Leaflet - Utilisation avancée} (voir \cite{Shevek}). Ces document sont assez bien faits pour qu'il ne soit pas nécessaire de produire ici une véritable introduction à Leaflet.
\smallskip
Nous allons plutôt nous concentrer sur un exemple particulier. Il s'agit de la carte des pollutions océaniques présentée ci-dessus (voir \ref{para:pollutionsoceaniques}). L'objectif n'est certainement pas une critique de ce travail qui est pour nous excellent. Il s'agit de présenter ce que Leaflet peut apporter à un travail où, de l'aveu même des auteures, les outils proposés par Umap on montré leurs limites, tout en présentant rapidement la philosophie de Leaflet.
\section{Structure}
Leaflet est une surcouche \emph{Javascript} à un site ordinaire écrit en HTML et CSS. Il est donc nécessaire de disposer d'un serveur web pour y intégrer les pages réalisées avec lui.
Ainsi la structure de la carte sur les pollutions océaniques est-elle celle du code \ref{listing:html}.
\begin{lstlisting}[float,language=HTML5,caption={La partie HTML5 de la carte.},label={listing:html},numbers=right, numberstyle=\tiny,numbersep=6pt]
<!DOCTYPE html>
<html>
<head>
<title>Oceans de plastiques</title>
<meta http-equiv="Content-Type"content="text/html; charset=utf8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="css/moncss.css" type="text/css" rel="stylesheet">
</head>
<body id="body">
<h1>Carte des pollutions plastiques</h1>
<div id="map"></div>
<footer>Copyleft</footer>
</body>
<!-- Stamen Watercolor -->
<!--<script type="text/javascript" src="https://stamen-maps.a.ssl.fastly.net/js/tile.stamen.js?v1.3.0"></script> -->
<!-- Leaflet -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<!-- Le js -->
<script src="js/monjs.js"></script>
</html>
\end{lstlisting}
Est associée à la page HTML5, une page CSS3 et un fichier Javascript. La feuille de style associée est celle présenté dans le code \ref{listing:css}.
\begin{lstlisting}[float,language=CSS,caption={La feuille de style de la carte.},label={listing:css},numbers=left, numberstyle=\tiny,numbersep=6pt]
#map {
/* les dimensions de la carte sur tout le viewport */
/*width: 100vw;height: 100vh;*/
width: 100%;
height: 80vh;
border: solid black 1px;
}
svg {background: transparent;}
\end{lstlisting}
Quant au javascript, il se trouve dans le code \ref{listing:js}.
\begin{lstlisting}[float,language=Javascript,caption={Le javascript de la carte avec ses deux fonds.},label={listing:js}, numbers=right, numberstyle=\tiny,numbersep=1pt]
document.getElementById('body').onload = function(){
// La carte centrée et zoomée
center: [55, 0],
zoom: 2
});//.setView([0, 0], 2);
// Déclaration des fonds
var baselayers = {
osm:L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}),
stamen:L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg', {
maxZoom: 19,
attribution: 'Map tiles by <a href="https://stamen.com">Stamen Design</a>, under CC BY 4.0. Data by <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, under <a href="http://creativecommons.org/licenses/by/4.0">CC BY SA</a>.'
})
};
// Ajout du fond par défaut
baselayers.stamen.addTo(map);(*@\label{ligne:stamen}@*)
// Ajout du menu de changement de fonds
L.control.layers(baselayers, null, {position: 'topright', collapsed : false }).addTo(map);(*@\label{ligne:osm}@*)
\end{lstlisting}
Le code \ref{listing:js} permet de placer sur la page un fond de carte \emph{Watercolor} de \href{https://stamen.com/open-source/}{Stamen} sur des données \href{https://www.openstreetmap.org}{OpenStreetMap} par instanciation de l'objet \emph{map}. Cela est réalisé à la ligne \ref{ligne:stamen}. Mais il est aussi prévu la possibilité de choisir un fond de carte OpenStreetMap à la ligne \ref{ligne:osm}.
\smallskip
Le choix du fond de carte Watercolor est celui du groupe des pollutions océaniques. Il est maintenu ici, mais on se demandera par la suite s'il est possible d'en changer au profit d'un fond représentant mieux le fond océanique. En effet, c'est en partie ce dernier qui contraint les mouvement d'eau et construit ainsi les gyres.
\section{Marqueurs}
La notion de marqueurs recouvre essentiellement deux types d'éléments~:
\begin{itemize}
\item Les éléments graphiques dont la taille est indépendante de l'échelle. Il s'agit d'éléments dont la taille ne va pas varier lors d'un zoom sur la carte. Ces éléments doivent toujours conserver leur taille à l'écran. On peut dire qu'il n'ont de relation avec la carte que dans leur positionnement.
\item Les éléments graphiques dont la taille est dépendante de l'échelle. Il s'agit d'éléments d'étendue fixe sur le territoire. En zoomant vers une échelle détaillée (grande échelle), il grandissent et en dézoomant vers une vaste échelle (petite échelle), il deviennent de plus en plus petits.
\end{itemize}
\begin{figure*}[t]
\centering
\begin{subfigure}[b]{0.45\textwidth} % "0.45" donne ici la largeur de l'image
\centering \includegraphics[width=\textwidth]{LeafletMerkatorPetiteEchelle}
\caption{Petite échelle}\label{fig:merkatorpetiteechelle}
\end{subfigure}
~ % ce symbole ajoute un espacement horisontal entre les premières deux images
\begin{subfigure}[b]{0.45\textwidth}
\centering \includegraphics[width=\textwidth]{LeafletMerkatorGrandeEchelle}
\caption{Grande échelle}\label{fig:merkatorgrandeechelle}
\end{subfigure}
%
% % la ligne blanche correspond au retour à la ligne après le deuxième image
% \begin{subfigure}[b]{0.45\textwidth}
% \centering \includegraphics[width=\textwidth]{margueriteDaisy.jpg}
% \caption{Marguerite Daisy}\label{fig:daisy}
% \end{subfigure}
% ~
% \begin{subfigure}[b]{0.45\textwidth}
% \centering \includegraphics[width=\textwidth]{rose.jpg}
% \caption{Rose}\label{fig:rose}
% \end{subfigure}
\caption{Projection de Merkator}\label{fig:projmerkator}
\end{figure*}
Pour illustrer différents types de marqueurs disponibles avec Leaflet, la figure \ref{fig:projmerkator} présente deux cartes à deux échelles différentes. Essentiellement, quatre types de marqueurs sont présents~:
\begin{itemize}
\item des lignes de latitude avec des marqueurs textuels liés,
\item des rectangles dont les sommets sont donnés en coordonnées [latitude, longitude],
\item des cercles dont les centres sont en latitude-longitude, mais dont les rayons sont donnés en mètres et des rectangles pleins dont les coordonnées sont exprimés en pixels d'écran.
\end{itemize}
L'ensemble de ces marqueurs permet de se rendre compte de la variété des problèmes qu'on peut rencontrer lors du placement de figures sur un projection de Merkator dont l'emprise (la zone visible à l'écran) change en fonction du niveau de zoom.
\subsection{Lignes}
Commençons par expliciter les lignes et leurs marqueurs. Le code \ref{listing:lignes} en présente la structure.
\begin{lstlisting}[float,language=Javascript,caption={Lignes de latitude et marqueurs texte.},label={listing:lignes}, numbers=right, numberstyle=\tiny,numbersep=1pt]
var latlngs = [[80, -80],[80, 80]];(*@\label{ligne:latlngs}@*)
var polyline = L.polyline(latlngs, {color: 'green'}).addTo(map)(*@\label{ligne:polyline}@*)
.bindTooltip("Équateur : latitude 0°",(*@\label{ligne:tooltip}@*)
{permanent: true,
direction: 'right',
offset: [60,0](*@\label{ligne:offset}@*)
});
\end{lstlisting}
La variable \emph{latlngs} déclare deux points en latitude-longitude qui seront les extrémités de la ligne (ligne \ref{ligne:latlngs}). On construit ensuite dans la variable \emph{polyline} une ligne placés selon la variable latlngs et de couleur verte qu'on ajoute à la carte (ligne \ref{ligne:polyline}). À ce niveau, la ligne apparaît sur la carte.
En utilisant la méthode \emph{bindTooltip} sur cette polyline (ligne \ref{ligne:tooltip}), on peut alors définir le texte du marqueur et ses caractéristiques, dont le décalace de celui-ci par rapport au centre de la ligne (l'offset de la ligne \ref{ligne:offset}). Attention, ce dernier n'est pas spécifié en degré de latitude-longitude, mais en pixels de l'écran.
Ainsi définis, ces lignes et marqueurs auront un comportement de deux types. La ligne, ainsi que la position du marqueur, resteront parfaitement \emph{fixes sur la carte} à toutes les échelles (selon tous les facteurs de zoom). Le texte, par contre ne suivra pas le zoom. En d'autres termes, sa taille restera fixe par rapport à l'écran.
Toutes les commandes utilisées pour réaliser ces lignes font partie du jeux de commandes de Leaflet (son API, l'interface de programmation de l'application). Aucun plugin n'est nécessaire et toutes ces commandes sont décrites dans la documentation. Mais attention à l'ambiguïté de la notation [..., ...] dont les composantes peuvent s'exprimer en latitude-longitude \emph{ou} en pixelssurX-pixelssurY (notez l'inversion puisque le premier nombre n'est pas la longitude).
\subsection{Rectangles}
Les rectangles dont le fond est transparent sont aussi des éléments de l'API de Leaflet. Les paramètres nécessaires à leur construction étant les coordonnées latitude-longitude des sommets, on voit apparaître leur déformation typique de la projection de Merkator. Celle-ci se fait en latitude, mais aussi en longitude, contrairement à ce qu'on pourrait penser en raison du parallélisme équidistant des méridiens. En effet, si la déformation en latitude est évidente, la longueur réelle des côtés \og horizontaux \fg{}, sur la carte (c'est-à-dire sur la projection) d'égale longueur, est inférieure en réalité pour le côté de plus grande latitude à celle de plus faible latitude.
Les instructions permettant de tracer ces rectangles sont celles du code \ref{listing:rectangles}. Relevez que la couleur du fond transparent est celle par défaut.
\begin{lstlisting}[float,language=Javascript,caption={Les rectangles en latitude-longitude.},label={listing:rectangles}, numbers=right, numberstyle=\tiny,numbersep=1pt]
var polygon = L.polygon([
[0, 0],[20, 0],[20, -20],[0, -20]
],{color: "green"}).addTo(map);
\end{lstlisting}
\subsection{Cercles}\label{cercles}
Les cercles présentent un élément différent des rectangles, en ce sens que, si leurs centres sont positionnés en latitude-longitude (tous les 20\degres), leur rayon est identique pour chacun et donné en mètres.
Le résultat graphique sur la carte est une série de cercles dont le rayon augmente avec la latitude. Si, à l'instar des rectangles, on comprend bien que cela soit le cas avec la latitude, on pouvait s'attendre à ce qu'il n'en soit pas ainsi avec la longitude. Comment expliquer que cela ne soit pas le cas ? Dans une projection de Merkator, les méridiens sont des lignes droites équidistants. Ce qui n'est évidemment pas le cas sur le globe terrestre, puisque tous ses méridiens se rejoignent aux pôles. La distance vraie entre deux méridiens diminue donc avec la latitude. En effectuant une projection de Merkator qui \og redresse \fg{} les méridiens pour qu'il soient parallèles les uns aux autres, on augmente donc les distances sur la projection en fonction de la latitude, ce qui a pour effet d'augmenter le rayon du cercle entre deux méridiens en même proportion qu'entre deux grands cercles. Le résultat se présente donc sous la forme de cercles dont le rayon augmente avec la latitude.
Les instructions permettant de tracer ces cercles sont celles du code \ref{listing:cercles}. Relevez que la couleur du fond transparent est définie à la ligne \ref{ligne:couleurfond}.
\begin{lstlisting}[float,language=Javascript,caption={Les rectangles en latitude-longitude.},label={listing:cercles}, numbers=left, numberstyle=\tiny,numbersep=1pt]
var rayon = 1100000(*@\label{ligne:rayon}@*)
var cercle = L.circle([30, -50], {(*@\label{ligne:cercle}@*)
color: 'yellow',
fillColor: '#101010',(*@\label{ligne:couleurfond}@*)
fillOpacity: 0.5,
radius: rayon
}).addTo(map);
\end{lstlisting}
Les deux éléments principaux de ce code sont la définition du rayon (ligne \ref{ligne:rayon}), de même valeur pour tous les cercles, et la création du cercle (ligne \ref{ligne:cercle}) avec son centre latitude-longitude et ses propriétés comme le rayon.
\subsection{Rectangles SVG}
L'API de Leaflet est limitée dans les formes de base utilisables qui sont le point, la polyline (dont la droite), le polygone, le cercle et le rectangle.
Pour des formes plus complexes, on est donc naturellement amené à penser à l'utilisation du dessin vectoriel comme SVG (\href{https://developer.mozilla.org/fr/docs/Web/SVG}{Scalable Vector Graphics}), puisque les navigateurs modernes supportent maintenant bien ce langage.
\smallskip
Le problème tient dans le fait que définir une ligne droite dans un langage vectoriel ne peut se faire que sur la projection. En effet, à la surface d'une sphère, si les deux extrémités sont données en latitude et longitude, une droite n'en n'est plus une.
Leaflet utilise donc trois systèmes de coordonnées qu'il faut bien comprendre sans quoi des surprises de représentation peuvent apparaître.
\section{Pollutions}
Les problèmes posés par la carte des pollutions réalisées par Mathilde et Hélène sont nombreux~:
\begin{enumerate}
\item la petite échelle de la carte qui la déforme assez pour que la représentation des gyres en soient affectée,
\item le fond de carte qui devrait permettre de comprendre les gyres,
\item la forme des gyres qui physiquement est difficile à connaître et graphiquement difficile à bien représenter pour qu'elles correspondent au mieux à des courants océaniques,
\item le mouvement de celles-ci et
\item les informations sur celles-ci, comme leur emprise, la quantité de plastique présente, la dimension de leurs éléments, \dots
\end{enumerate}
Tous ces problèmes se traduisent par des difficultés techniques qui sont toutes caractéristiques des productions cartographiques.
\subsection{Échelle}
La petite échelle de la carte utilisée pour la carte des pollutions constitue la première interrogation. Dans quelle mesure influence-t-elle la représentation des gyres ? La réponse à cette question tient dans la connaissance du type de projection utilisée par défaut par Leaflet.
Toutes les projections cartographiques sur le web utilisent la même projection dite \emph{Webmercator}, \emph{Pseudomercator}, \emph{Mercator sphérique} et, officiellement, \emph{WGS 84 Web Mercator}\footnote{Elle est aussi dénommée Google Web Mercator, mais étant non conforme, elle n'est semble-t-il officiellement pas reconnue (voir \href{https://en.wikipedia.org/wiki/Web\_Mercator\_projection}{Wikipedia})}. Cette projection est complexe, car s'il s'agit bien d'une projection de Mercator, elle utilise des données provenant d'un géoïde non sphérique, contrairement à ce que sa dénomination peut faire penser. De plus, elle n'est ni conforme, ni équivalente, c'est-à-dire qu'elle ne conserve respectivement ni les angles, ni les surfaces, alors que la transformation de Mercator est conforme. Vous trouverez en annexe \ref{annexe:projectionmercator} une description plus détaillé de la projection de Mercator, dont notamment son indicatrice de déformation des surfaces. Car, la transformation de Mercator, comme wGS 84 Web Mercator, déforme les formes hors équateur, surtout au niveau des régions de grande latitude.
Ainsi, représenter une gyre sur une carte à petite échelle ne permettra pas de la représenter correctement de part la nature de la projection utilisée.
\subsection{Fond de carte}
Le fond de carte choisi pour cette carte des pollutions plastiques est \emph{Watercolor} (voir \cite{Stamen}). Si celui-ci est certainement très esthétique et bien choisi par contraste avec le propos du travail, il n'est pas un fond permettant de mettre en évidence la raison des gyres.
Après des recherches pour trouver un fond de carte libre de droit utilisable avec Leaflet (ou même Umap) qui représente le fond des océans, il se trouve que si de projets pour réaliser une telle carte sont en cours, il n'y a pas actuellement de fonds, c'est à dire de tuiles pour les différentes échelles, disponibles dans ces conditions. Il ne suffit pas évidemment d'une image des fonds marins.
\subsection{Forme}
À ce stade, il convient de présenter ce qu'il est possible de faire avec Leaflet pour aller plus loin que la carte des pollutions océaniques. La figure \ref{figure:cartepollutionsgenerale}, page \pageref{figure:cartepollutionsgenerale}, la présente sous une forme statique.
\begin{sidewaysfigure*}
\centering
\includegraphics[width=\textwidth]{CartePollutionsGenerale}
\caption{La carte statique des gyres océaniques.\label{figure:cartepollutionsgenerale}}
\end{sidewaysfigure*}
Cette carte comprends plusieurs éléments qui vont du plus simple au plus complexe. Commençons par la \emph{Gyre du Pacifique Sud}. Il s'agit simplement d'un cercle dont on voit la déformation en longitude relative à la projection de Mercator. Le code correspondant est celui du listing \ref{listing:cartegenecercle}.
\begin{lstlisting}[float,language=Javascript,caption={La gyre Pacifique Sud.},label={listing:cartegenecercle}, numbers=left, numberstyle=\tiny,numbersep=1pt]
var rayon = 3000000
var cercle1 = L.circle([-45, -130], rayon, {
color: 'black',
fill: 'true',
fillColor: '#101010',
fillOpacity: 0.2,
}).addTo(map)
.bindTooltip("Gyre du Pacifique Sud",
{permanent: true,
direction: 'left',
offset: [0,0]
});
\end{lstlisting}
On peut remarquer que la méthode \emph{bindTooltip} a été utilisée pour permettre de placer une étiquette de texte au centre de la gyre, étiquette affichée de manière permanente et sur la gauche de celui-ci.
\medskip
Ensuite, avec \emph{La gyre de l'océan Indien} se trouve tout d'abord un simple marqueur par défaut, ouvert sur le texte de description. Le code de ce marqueur est celui du listing \ref{listing:cartegenemarqueur}.
\begin{lstlisting}[float,language=Javascript,caption={Le marqueur de l'océan indien.},label={listing:cartegenemarqueur}, numbers=left, numberstyle=\tiny,numbersep=1pt]
var marker1 = L.marker([-42.5,69]).addTo(map)
.bindPopup("La gyre de l'océan indien.")
.openPopup();
\end{lstlisting}
Puis vient un élément bien plus intéressant. Il s'agit de l'ovale qui délimite la gyre. C'est un élément \emph{svgOverlay} de Leaflet. C'est-à-dire qu'il s'agit d'une courbe en SVG, comme le mondre le code \ref{listing:cartegeneellipse}.
\begin{lstlisting}[float,language=Javascript,caption={L'ellipse de l'océan indien.},label={listing:cartegeneellipse}, numbers=left, numberstyle=\tiny,numbersep=1pt]
var coin20_0 = L.latLng(0, 23);
var coin0_20 = L.latLng(-65, 115);
var bounds1 = L.latLngBounds(coin20_0, coin0_20);
var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svgElement.setAttribute('xmlns', "http://www.w3.org/2000/svg");
svgElement.setAttribute('viewBox', "0 0 100 100");(*@\label{ligne:geneviewbox}@*)
svgElement.innerHTML = '<ellipse transform="rotate(-40 50 60)" cx="50" cy="60" rx="45" ry="30" stroke="black" stroke-opacity="1" fill-opacity="50%"/>';(*@\label{ligne:geneellipse}@*)
var forme = L.svgOverlay(svgElement, bounds1);
forme.addTo(map);
\end{lstlisting}
Outre la définition de la boite qui va contenir la figure, définie par ses coins et la variable \emph{bounds1}, ce code est intéressant par le contenu de la variable \emph{svgElement}.
La ligne \ref{ligne:geneviewbox} déclare l'unité de la grille de représentation du schéma, ici une grille de 100x100. Vient ensuite le dessin lui-même, défini à la ligne \ref{ligne:geneellipse}, qui code en svg l'élément \emph{<ellipse />} par la position de son centre (cx et cy), la longueur de ses demi-axes (rx et ry), mais aussi par son angle de rotation (-40\degres) relativement à son centre (50 60). De plus, les éléments de couleur de la ligne et d'opacité du fond (fill-opacity) sont fournis comme attributs du code svg de l'ellipse.
\medskip
Enfin, vient un élément très intéressant. Il s'agit de la forme de la gyre de l'Atlantique Sud. Comme précédemment, c'est un élément SVG, mais celui-ci a été voulu plus complexe qu'une forme de base de l'API SVG, comme l'ellipse ou le rectangle. Il s'agit d'un chemin.
En SVG, un chemin est d'abord formé de segments constitués chacun de deux points. L'un est l'origine du segment et l'autre son arrivée. À chacun de ces deux points est associé un point supplémentaire nommé poignée de Bésier. La droite qui lie le point à sa poignée de Bésier définit la tangente de la courbe au point considéré. Il est ainsi possible de créer une courbe avec quatre points uniquement.
Pour mieux comprendre la situation, étudions le code permettant de tracer la courbe représentant la gyre de l'Atlantique Sud. Il est donné par le listing \ref{listing:cartegenebesier}.
\begin{lstlisting}[float,language=Javascript,caption={La gyre de l'Atlantique Sud.},label={listing:cartegenebesier}, numbers=left, numberstyle=\tiny,numbersep=1pt]
var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svgElement.setAttribute('xmlns', "http://www.w3.org/2000/svg");
svgElement.setAttribute('viewBox', "0 0 100 100");(*@\label{ligne:geneviewboxx}@*)
svgElement.innerHTML = '<path d="M 85,15 C 100,40 85,85 15,85 C 0,85 50,-55 85,15" stroke="black" stroke-opacity="1" fill-opacity="0%"/>\(*@\label{ligne:genepath}@*)
<image xlink:href="images/Mollweide_Cycle.gif" x="30" y="20" height="50" width="50" />';(*@\label{ligne:geneimgvect}@*)
var forme = L.svgOverlay(svgElement, bounds1);
forme.addTo(map);
\end{lstlisting}
Les premières lignes ont déjà été expliquées précédemment. Seules les lignes \ref{ligne:genepath} et \ref{ligne:geneimgvect} sont à commenter.
Et encore, la seconde donne simplement un exemple de placement d'une image animée de type GIF sur la carte. Elle n'appelle pas vraiment de commentaires.
La première quant à elle est plus complexe car elle présente un élement de type \emph{path} dont le premier paramètre est difficilement compréhensible. Les autres sont évidents. Commentons donc ce premier paramètre qui comporte les éléments suivant~:
d="M 85,15 C 100,40 85,85 15,85 C 0,85 50,-55 85,15"
Pour les comprendre, il faut au préalable se rappeler que la taille de la viewbox, précisée à la ligne \ref{ligne:geneviewboxx}, est de 100x100. Le chemin commence par un unique point (M) situé aux coordonnées x,y de la viewbox 85,15, soit en haut à droite (le système d'axes utilisés en SVG à l'origine en haut a gauche, x pointant vers la droite et y vers le bas). Viennent ensuite trois couples de nombres après la lettre C qui représentent successivement la poignée de Bésier 100,40 du point M, la poignée de Bésier du point terminal du segment et le point terminal du segment. Le point 15,85 est donc le point terminal du premier segment et 85,85 sa poignée de Bésier associée. Le second C permet de construire le second segment. Comme aucun point M n'est présent juste avant, c'est le dernier point du segment précédent qui constitue l'origine du second 15,85, dont la poignée de Bésier est 0,85. Le point final étant 85,15 et sa poignée de Bésier associée 50,-55, la courbe est fermée.
Pour vous rendre compte que ces points dessinent bien la courbe de la gyre de l'Atlantique Sud, faites un schéma avec les différents points en reliant les poignées de Bésier à leur point.
Vous pouvez aussi consulter le site de \emph{La Cascade} \cite{Path} qui vous présentera clairement d'autres commandes path SVG.
\subsection{Mouvement}
Un premier élément de mouvement se trouve dans l'image animée GIF au centre de la gyre de l'Atlantique Sud. Ce qu'on ne voit pas sur la figure \ref{figure:cartepollutionsgenerale}, page \pageref{figure:cartepollutionsgenerale}, c'est que cette image est animée. Pendant la consultation du site, elle se comporte comme un petit film.
Mais, avant de présenter comment superposer à la carte un véritable petit film, signalons, avec l'exemple de la gyre du Pacifique Nord, qu'il ne faut pas négliger la possibilité de représenter le mouvement sans mouvement, c'est à dire avec des éléments vectoriels (au sens de flèches) qui sont depuis longtemps utilisés par la cartographie. Ici, la transparence, rendue disponible par l'utilisation du format d'image PNG, permet de superposer à la carte une image présentant les courants océaniques dans cette zone. Pour autant que cette image ait été créée selon une projection de Mercator (ce qui n'est pas ici le cas), elle peut être un outil particulièrement adapté à la représentation des mouvements marins. Le code de placement de l'image est classique et est précisé dans le listing \ref{listing:cartegenevecteurs}.
\begin{lstlisting}[float=t,language=Javascript,caption={La gyre Pacifique Nord.},label={listing:cartegenevecteurs}, numbers=left,numberstyle=\tiny,numbersep=1pt]
var imageUrl = 'images/North_Pacific_Gyre.png';
var errorOverlayUrl = 'https://cdn-icons-png.flaticon.com/512/110/110686.png';
var altText = 'Wikipedia : https://commons.wikimedia.org/wiki/File:North_Pacific_Gyre.png';
var latLngBounds = L.latLngBounds([[66.6, -254.5], [-15.5, -105.2]]);
var imageOverlay = L.imageOverlay(imageUrl, latLngBounds, {
opacity: 1,
errorOverlayUrl: errorOverlayUrl,
alt: altText,
interactive: true
}).addTo(map)
.bindTooltip("Gyre du Pacifique Nord", {
permanent: true,
direction: 'right',
offset: [0,0]
});
\end{lstlisting}
Bien entendu, l'idéal serait de récupérer les données (position, sens, direction et grandeur) numériques de ces courants et de les projeter sur la carte dans une couche vectorielle et non par une image bitmap. C'est possible, mais dépasse le cadre de cette petite présentation de Leaflet.
\medskip
Encore plus intéressant est la vidéo représentant les mouvement océaniques de la gyre de l'Atlantique Nord. Les données sont celles de la NASA (voir \cite{NASA}). La vidéo qui se trouve sur la carte est une simulation du mouvement de bouées en Atlantique Nord, basée sur l'étude de bouées réelles. Comme le dit la NASA~:
\begin{quotation}
We distributed thousands of particles (virutal buoys) aroung the world, then ran a simulation based on the ECCO2 flow vectors to see where those particles would move to over time. These simulated particles were colored blue/cyan based on the paricle's speed. Notice that over time garbage patches develop in each of the ocean basins. \cite{NASA}
\end{quotation}
Pour une comparaison entre le modèle numérique et les bouées réelles, voyez la référence. Comme le propos ici n'est pas de discuter des éléments scientifiques qui expliquent les gyres, mais de montrer que Leaflet permet différentes représentations de celles-ci, d'une vidéo sur l'ensemble des gyres mondiales, seule la gyre de l'Atlantique Nord a été extraite par découpage avec le logiciel libre OpenShot et seules la partie simulation a été sélectionnée.
La manière d'introduire cette vidéo sur la carte est présentée dans le code \ref{listing:cartegenebouees}.
\begin{lstlisting}[float,language=Javascript,caption={La gyre de l'Atlantique Nord.},label={listing:cartegenebouees}, numbers=left, numberstyle=\tiny,numbersep=1pt]
var videoUrls = [
'images/GyreAtlantiqueNordPetitPetit.mp4'];(*@\label{ligne:genevideos}@*)
var errorOverlayUrl = 'https://cdn-icons-png.flaticon.com/512/110/110686.png';
var latLngBounds = L.latLngBounds([[57, -100], [3.5, 13]]);
var videoOverlay = L.videoOverlay(videoUrls, latLngBounds, {(*@\label{ligne:videooverlay}@*)
opacity: 0.6,(*@\label{ligne:videoopacity}@*)
errorOverlayUrl: errorOverlayUrl,
interactive: true,
autoplay: true,
muted: true,
playsInline: true,
keepAspectRatio: false(*@\label{ligne:videoaspectratio}@*)
}).addTo(map);
\end{lstlisting}
Plusieurs vidéos peuvent être jouées successivement, auquel cas elles doivent être spécifiées dans le tableau \emph{videoUrls} de la ligne \ref{ligne:genevideos}, séparées par une virgule.
La méthode le l'API Leaflet pour représenter la vidéo sur la carte est \emph{videoOverlay} visible à la ligne \ref{ligne:videooverlay}. Elle prend pour arguments le tableau de la/des vidéos, la boite des position supérieure-gauche et inférieure-droite de la vidéo et des propriétés comme l'opacité (ligne \ref{ligne:videoopacity}) ou le ratio d'aspect (ligne \ref{ligne:videoaspectratio}). Ce dernier est très utile dans le cas d'une carte dans la vidéo qui n'est pas conforme à Mercator pour déformer au mieux la vidéo pour que les contours des côtes colle au mieux à ceux de la carte sous-jacente.
\medskip
On constate finalement une grande simplicité à gérer des éléments dynamiques avec Leaflet, que ce soit une image comportant des vecteurs, une vidéo de type GIF ou des vidéos classiques, qui dans tous les cas supportent un réglage de l'opacité très bienvenu sur le fond de carte.
\subsection{Informations}
Notons finalement que les possibilités offertes par Leaflet en terme de présentation de l'information sont très vastes. En particulier, la gestion de l'information à l'intérieur des popups qui s'ouvrent à l'accueil sur la carte ou par un clic sur l'un de ses éléments, n'a pas été abordée ici, pas plus que la personnalisation des icônes de ceux-ci. Le site de Leaflet (voir \cite{Leaflet}) et en particulier ses onglets \emph{Tutorials} et \emph{Docs} vous en diront plus.
\smallskip
Voyons cependant comment mettre en place une légende.
Le code permettant d'obtenir la légende présentée à la figure \ref{figure:legende} est donné dans le listing \ref{listing:legende}.
\begin{figure}[ht]
\centering
\includegraphics[width=0.6\linewidth]{legende}
\caption{Une légende\label{figure:legende}}
\end{figure}
\begin{lstlisting}[float,language=Javascript,caption={Une légende.},label={listing:legende}, numbers=right, numberstyle=\tiny,numbersep=1pt]
// Définition de la légende
function getColor(d) {(*@\label{ligne:couleur}@*)
return d === 'Océaniques' ? "#5bc6da" :
d === 'Terrestres' ? "#e5c7a9" :
d === 'Polaires' ? "#dadcd2" :
d === 'Désertiques' ? "#e2ddcf" :
"#cd9474";
}
var legend = L.control({position: 'bottomleft'});(*@\label{ligne:control}@*)
legend.onAdd = function (map) {(*@\label{ligne:onadd}@*)
var div = L.DomUtil.create('div', 'info legend');(*@\label{ligne:domdiv}@*)
labels = ['<strong>Surfaces</strong>'],
categories = ['Océaniques','Terrestres','Polaires','Désertiques','Autres'];
for (var i = 0; i < categories.length; i++) {
div.innerHTML +=
labels.push('<span style="display:inline-block;width:10px;height:10px;border-radius:5px;background:'+getColor(categories[i])+';"></span> '+categories[i]);(*@\label{ligne:lignescategories}@*)
}
div.innerHTML = labels.join('<br>');(*@\label{ligne:retourligne}@*)
return div;(*@\label{ligne:retourfinal}@*)
};
legend.addTo(map);(*@\label{ligne:cartelegend}@*)
\end{lstlisting}
On voit dans ce code plusieurs éléments intéressants.
Tout d'abord, à la ligne \ref{ligne:couleur}, une fonction permettant de retourner une couleur en fonction d'une catégorie de surfaces (Océaniques, Terrestre, \dots). La grammaire utilisée est celle d'un test (?) de différents cas dont la couleur finale correspond à l'ensemble des cas non prévus.
Puis, vient la déclaration d'un élément de contrôle de Leaflet mis à la ligne \ref{ligne:control} dans la variable \emph{legend}.
Si la légende est ajoutée à la carte à la ligne \ref{ligne:cartelegend}, ses éléments sont construits précédemment dans la méthode \emph{onAdd} de la variable legend, ligne \ref{ligne:onadd}. À la même ligne, celle-ci est constituée par une fonction anonyme avec pour paramètre la carte (map).
Dans cette fonction, on crée à la ligne \ref{ligne:domdiv} un \emph{div} en y ajoutant les classes \emph{info} et \emph{legend}. Puis, on initialise la variable \emph{labels} avec l'entête de la légende et on déclare une variable \emph{categories}, qui va contenir les éléments de la légende. Enfin, on créée une boucle ajoutant à l'entête de la variable \emph{label} chaque ligne de la légende. Chacune de celles-ci est construite de la même manière, ligne \ref{ligne:lignescategories} : un \emph{span} dont les bords sont arrondis pour donner un cercle et dont la couleur correspond à celle de chaque élément des catégories, suivi du teste correspondant à la catégorie en question. Enfin, à la ligne \ref{ligne:retourligne}, on crée un retour à la ligne à la fin de chacune de celles-ci.
Finalement le \emph{div} construit est retourné à la carte à la ligne \ref{ligne:retourfinal}.
\medskip
L'exemple de cette légende permet de comprendre comment on construit une légende, mais aussi d'envisager des légendes dynamiques avec des couleurs qui changent en fonction des cas, car si la variable \emph{categories} peut contenir du texte, elle peut aussi être numérique.
\subsection{Grands cercles}
Signalons encore ici la faculté de Leaflet à utiliser très simplement des modules.
Par exemple, on peut présenter l'utilisation du module \emph{Leaflet.greatCircle.js} (voir \cite{LGreatCircle}), permettant de représenter correctement de très grands cercles dans la projection de Mercator.
L'installation du module est très simple. Elle se fait par importation du script javascript de celui-ci à la fin du fichier \emph{index.html}, après Leaflet, comme le montre le code \ref{listing:greatcircle}.
\begin{lstlisting}[float,language=HTML5,caption={Importation du module greatCircle.},label={listing:greatcircle}, numbers=right, numberstyle=\tiny,numbersep=1pt]
<script src="js/Leaflet.greatCircle.js"></script>
\end{lstlisting}
Puis, pour créer un grand cercle, on utilise la syntaxe du code \ref{listing:cerclegreat}.
\begin{lstlisting}[float,language=Javascript,caption={Une légende.},label={listing:cerclegreat}, numbers=left, numberstyle=\tiny,numbersep=1pt]
// Définition d'un grand cercle avec le plugin Leaflet.greatCircle permettant
// des grand cercles correctement définis dans la projection de Mercator.
var grandcercle = new L.greatCircle([-30, 110], {radius: 7000000});(*@\label{ligne:declargreatcircle}@*)
grandcercle.addTo(map);
\end{lstlisting}
La construction du grand cercle se fait à la ligne \ref{ligne:declargreatcircle} en spécifiant la latitude-longitude et le rayon du cercle.
\smallskip
Le résultat est donné à la figure \ref{figure:cartegreatcircle}. On y voit en bleu des cercles si déformés au pôle Sud qu'ils ne se referment pas. Évidemment, l'échelle est très petite de façon à voir le monde dans son ensemble et c'est la raison pour laquelle le cercle se répète.
%\begin{sidewaysfigure*}
\begin{figure*}
\centering
\includegraphics[width=\textwidth]{CarteGreatCircle}
\caption{De très grands cercles corrects en projection de Mercator.\label{figure:cartegreatcircle}}
\end{figure*}
\section{Conclusion}
Au terme de ce parcours des possibilités offertes par Leaflet, et plus que cela avec les cartes proposées par Mathilde et Hélène, carte des pollutions océaniques (carte de la figure \ref{carte:pollutionoceanique}, page \pageref{carte:pollutionoceanique}) ou ci-dessus la carte statique des gyres océaniques (figure \ref{figure:cartepollutionsgenerale}, page \pageref{figure:cartepollutionsgenerale}), la question est de savoir ce que nous avons appris.
Au départ, la démarche engagée par Mathilde et Hélène nous a fait découvrir (ou nous à engagé à nous rappeler) que les gyres de plastiques ou les catastrophes pétrolières sont une réalité bien peu réjouissante qui se cache dans les océans et qu'il est bon d'en tenter la localisation sur une carte à petite échelle pour mieux en comprendre l'importance en terme de surface.
Puis, aux regrets de Mathilde et Hélène de ne pas avoir pu en préciser les formes, nous nous sommes intéressés aux techniques de représentation des éléments cartographiques d'une carte sur le web. Les modes de représentation des objets sur la carte et les variations d'échelle que ce type de carte implique nous ont alors fait découvrir plusieurs langages (Javascrip, Leaflet, SVG, \dots) nécessaires à la constitution des cartes.
Mais, l'étude de ces langages, des formes mises à disposition pour la représentation, nous ont interrogés sur la pertinence de celles-ci dans le cas de gyres. De simples cercles nous sommes passés à une représentation du mouvement des particules plastiques dans les courants océaniques. Encore ne sommes-nous pas allés à une représentation en profondeur, c'est-à-dire dans la troisième dimension des couches liquides océaniques. Mais on s'est bien rendu compte que la compréhension des mouvements des masses d'eau pouvait trouver une explication graphique dans une représentation des fonds océaniques. A la recherche d'une telle représentation, on a pu voir la puissance de Leaflet pour changer à la volée le fond de carte et découvrir que malheureusement, il n'existe pas encore de représentation des fonds océaniques tuilée pour permettre le zoom des cartes web.
Au final donc, les nécessités de la représentation cartographique nous ont poussés à approfondir de manière conséquente nos connaissances sur le fond des phénomènes que la carte exemplifie. On peut ainsi citer et souligner le titre de l'avant-propos de l'ouvrage \emph{La carte invente le monde} (voir \cite{Picouet} élaboré au c\oe ur de l'Université de Lille.
\begin{quote}
\emph{\textbf{La carte pour tracer un chemin dans des mondes de connaissances.}} \cite[Avant-propos]{Picouet}
\end{quote}