APIs, fonctions et DOM Scripting
Cartographie
Dans ce TP nous allons réaliser une application de cartographie, c’est-à-dire afficher une carte dans une page web et la contrôler via des boutons créés par un script. Le but est d’illustrer d’une part l’implémentation de fonctions, d’autre part, l’utilisation d’une API et enfin la possibilité de manipuler la structure de la page par javascript.
Mise en place
Dans un premier temps, nous allons créer une page html simple comprenant un div
ayant pour identifiant carte
qui servira à contenir la carte.
On pourra remplir la partie head
de la page pour identifier la page, créer une feuille de style simple et mettre un titre dans notre page web.
Nous devons maintenant inclure les fichiers nécessaires à l’insertion de la carte.
Nous allons utiliser la bibliothèque (API) leaflet pour afficher et configurer la carte.
Il faut donc lier les fichiers définissant les fonctions et styles utilisés : dans l’entête, ajouter l’appel de la feuille de style https://unpkg.com/leaflet@1.9.3/dist/leaflet.css.
En fin de body
, ajouter un appel au script https://unpkg.com/leaflet@1.9.3/dist/leaflet.js.
Pour l’affichage de la carte, ses dimensions doivent être précisées.
Pour cela, nous allons ajouter un nouveau fichier css
dans lequel on mettra les règles donnant via son id
, les valeurs de width et height du div précédemment défini.
Enfin, nous allons insérer la carte : après la ligne indiquant le chemin de leaflet.js
, nous allons ajouter un script directement dans le fichier html
contenant
var map = L.map('carte'); //'carte' : id du div où s'affichera la carte
.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
LmaxZoom: 19,
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
.addTo(map); //tuile de carte depuis openstreetmap
}).setView([48.6936, 6.1846], 13); //centrer la carte à Nancy, niveau de zoom 13 map
Dans le code ci-dessus, les L.*
indiquent des fonctions de Leaflet.
Nous avons maintenant une carte dynamique (on peut se déplacer avec la souris, zoomer/dézoomer avec la molette…)
Ajouter une épingle
Objectif : Mettre un marqueur sur la carte en des coordonnées prédéfinies.
À l’aide de la documentation de l’api, ajouter une épingle sur la carte (avec L.marker
).
Il faut d’abord créer le marqueur (par exemple dans une variable marque
) puis l’ajouter à la carte à l’aide de marque.addTo(map)
où map
est la variable définie plus haut.
Nous pouvons, avant d’ajouter l’épingle sur la carte, lui adjoindre un popup d’information qui apparaîtra quand on cliquera sur l’épingle.
Si marque
est une variable de type marker
, on peut utiliser marque.bindPopup(html)
où html
est une chaîne de caractère représentant du code html.
Question : L.marker
et marque.bindPopup
sont-elles des procédures ou des fonctions ?
Déplacer la carte
Objectif : Créer des boutons (input
) dont l’appui changera la vue de la carte.
Nous allons maintenant ajouter des boutons permettant de se déplacer vers des lieux précis.
Dans le fichier html, ajoutons un nouveau div
sous celui de la carte. Celui-ci aura pour identifiant boutons.
Dans ce div, créons un bouton nommé Biarritz dont le rôle est d’appeler map.panTo
avec un paramètre tableau de nombres contenant 43.4817 et -1.556111.
Créons deux autres boutons pour Nancy (coordonnées 48.6936, 6.1846) et Brest (coordonnées 48.390834, -4.485556).
Notons que nous pouvons créer une variable nancy
contenant la localisation de Nancy au lieu d’écrire en double les coordonnées et utiliser cette variable au lieu du tableau de coordonnées dans map.panTo
:
var nancy = L.latLng(48.6936, 6.1846)
.panTo(nancy) map
Ajoutons enfin un bouton qui exécutera map.fitBounds([nancy, biarritz, brest])
.
Question : map.panTo
, map.fitBounds
, L.latLng
et les attributs onclick
des boutons sont-elles des fonctions ou des procédures ?
Marquer un nouveau lieu
Objectif : Ajouter un bouton qui posera un marqueur au centre de la carte.
Il existe une fonction pour obtenir les coordonnées du centre de la carte affichée.
Elle renvoie un objet de type LatLng
, que l’on peut épingler avec L.marker
.
Ajouter un bouton Marquer qui va ajouter une épingle au centre de la carte.
Dessiner des lignes sur la carte
Objectif : Dessiner un segment entre deux points de la carte. Puis créer des boutons pour chaque paire de ville qui dessineront le segment entre les deux.
Nous allons maintenant ajouter des boutons pour tracer les chemins entre chaque paire de villes (pour l’instant, il y en a 3). Il va être intéressant de créer des variables brest et biarritz pour ne pas réécrire plusieurs fois les coordonnées. Un chemin pourra être ajouté par l’instruction suivante :
.addLayer(L.polyline([nancy, biarritz])) map
Nous voulons maintenant ajouter Dunkerque et Nice parmi nos villes. Si l’ajout des boutons pour centrer la carte en chacune des villes reste raisonnable (deux lignes à ajouter), les chemins de ville à ville sont trop nombreux pour tous les écrire (10 chemins !). Nous allons donc générer les boutons par un programmes et les ajouter automatiquement dans la page.
Pour cela, nous allons définir une fonction insereBouton
prenant 4 arguments : les noms des 2 villes à relier et les variables représentant leur position.
Cette fonction va créer un élément input
, de type button
, ayant une valeur cohérente.
On pourra fixer l’attribut onclick
en utilisant le fait que les éléments sont des dictionnaires et qu’ils peuvent avoir des fonctions comme valeurs !
"onclick"] = function () {
bouton[.addLayer(L.polyline([v1, v2]))
map }
Ensuite, nous allons mettre les noms et localisations des villes dans deux tableaux, parcourir les paires de villes différentes et pour chaque paire, appeler la fonction insereBouton
avec les bons paramètres.
Question : Serait-il possible d’améliorer le code pour ne pas manipuler deux tableaux, un pour les noms, un pour les localisations mais une seule structure ?
Colorier des zones sur la carte
Objectif : Dessiner des polygones.
Il est possible d’ajouter des polygones (c’est-à-dire des polylines fermées et coloriées) sur la carte avec du code ressemblant à ce qui suit :
var polygone = L.polygon([nancy, dunkerque, brest], {color: 'red', fillColor: '#ff5050'})
.addLayer(polygone) map
La fonction L.polygon
prend deux arguments : un tableau de L.latLng
et un dictionnaire d’options, en particulier celles définissant la couleur de la ligne et celle de l’intérieur du polygone.
Nous devons maintenant générer tous les quadrilatères composés de villes parmi Nancy, Biarritz, Nice, Brest et Dunkerque. Puis ajoutons des cases à cocher permettant d’afficher ou non chacun de ces quadrilatères.