umap/docs-users/fr/tutorials/10-embed-remote-data.md
2024-05-08 21:17:01 -04:00

404 lines
19 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

!!! abstract "Ce que nous allons apprendre"
- Créer un calque qui utilise des données distantes
- Produire une carte de chaleur (heatmap)
- Afficher des calques en fonction du niveau de zoom
- Afficher des données qui évoluent en temps réel
- Utiliser un portail *open data*
- Créditer la source des données pour respecter la licence
## Procédons par étapes
Jusquici toutes les cartes que nous avons créées montrent des données
gérées par uMap. Même lorsque nous avons utilisé les données dun
tableur dans le tutoriel précédent, ces données ont été *importées* sur
le serveur uMap, où elles sont *stockées*. Si ces données sont
modifiées, nous devons de nouveau les importer pour mettre à jour la
carte.
Dans ce tutoriel nous allons apprendre comment créer une carte qui
utilise des **données distantes**, cest-à-dire stockées sur un autre
serveur que le serveur uMap.
### 1. Jutilise des données distantes
Nous prenons pour ce tutoriel le thème des stations de vélo-partage à
Paris, les fameux Vélib, dont les données sont disponibles en open
data.
#### Utiliser un portail open data
Commençons par observer le jeu de données « Vélib - Localisation et
caractéristique des stations », disponible sur le portail open data de
la ville de Paris :
<https://opendata.paris.fr/explore/dataset/velib-emplacement-des-stations/>.
Longlet **Informations** explique que les données « sont actualisées
chaque minute selon la norme GBFS 1.0 ». Cette norme décrit plusieurs
fichiers, accessibles avec lAPI décrite dans longlet **API**, dont le
format nest pas compris par uMap.
Longlet **Tableau** montre les données : chaque station a un nom et une
capacité (nombre demplacements), ainsi quune position géographique.
Longlet **Export** propose plusieurs formats, dont les formats
**GeoJSON**, **KML** et **GPX**, tous trois compris par uMap. Nous
choisissons le [format GeoJSON](https://fr.wikipedia.org/wiki/GeoJSON),
qui permet dexploiter tous les attributs présents dans les données.
Une possibilité serait de télécharger le fichier puis de limporter dans
uMap, comme nous lavons fait dans le tuto précédent avec un fichier au
format CSV. Outre les manipulations, cela impliquerait de mettre à jour
ces données régulièrement. Nous allons plutôt configurer notre carte
pour accéder directement aux données mises à disposition par le portail
open data. Pour cela nous copions le lien vers le fichier : un clic
droit ouvre un menu contextuel qui permet de **copier le lien** vers le
fichier :
https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/velib-emplacement-des-stations/exports/geojson?lang=fr&timezone=Europe%2FBerlin
![umap-donnees-distantes.png](../../static/tutoriels/10-jintegre-des-donnees-distantes/umap-donnees-distantes.png)
#### Configurer les données distantes
Voyons maintenant comment utiliser ce lien dans uMap. Pour cela nous
créons un nouveau calque et ouvrons, dans les Propriétés du calque,
longlet **Données distantes**. Les informations à fournir sont les
suivantes :
- **URL** : nous collons ici le lien vers le fichier copié
précédemment.
- **Format** : nous devons sélectionner le format, ici **geojson**
- **Licence** : ODbL comme indiqué sur la page dexport du portail
open data
Le bouton **Vérifier lURL** permet de tester laccès au fichier depuis
uMap, et de vérifier que le format choisi correspond bien aux données.
Les données sont alors affichées sur la carte.
#### Proxy ou pas proxy ?
Si cela ne fonctionne pas (uMap affiche un bandeau qui indique «
Problème dans la réponse du serveur »), il est probable que le serveur
sur lequel le fichier est stocké nautorise pas laccès au fichier
depuis un service tiers.
!!! note
Il sagit du mécanisme CORS, décrit dans larticle
Wikipédia [Cross-origin ressource
sharing](https://fr.wikipedia.org/wiki/Cross-origin_resource_sharing).
uMap permet de contourner cette contrainte en faisant transiter le
fichier par le serveur uMap, grâce à loption **Avec proxy** quil
convient alors dactiver. Cette option est associée au menu déroulant
**Cacher la requête avec proxy**, qui permet au serveur uMap de
conserver le fichier afin de ne pas le récupérer à chaque affichage de
la carte. La durée la plus longue (1 jour) serait ici adaptée.
#### Au sujet de la licence
Le fichier des emplacements de stations Vélib est publié sous la
[licence ODbL](https://opendatacommons.org/licenses/odbl/). Celle-ci
exige que le producteur des données soit crédité lors de leur
utilisation. Les informations sur le portail open data indique que ce
producteur est « Autolib Velib Métropole ». Il convient donc de le citer
dans les **Crédits** de la carte, un onglet du menu *Propriétés de la
carte*.
![umap-geojson-properties.png](../../static/tutoriels/10-jintegre-des-donnees-distantes/umap-geojson-properties.png)
#### Afficher le nom et la capacité des stations
Afin dafficher le nom et la capacité de chaque station dans une
infobulle, nous devons déterminer les clefs permettant daccéder à ces
informations. Pour cela il nous faut observer le fichier GeoJSON.
Nous téléchargeons ce fichier depuis longlet Export du portail open
data, ou collons le lien copié précédemment dans la barre de navigation
du navigateur. Soit le fichier est directement affiché dans le
navigateur, soit il est téléchargé : une possibilité consiste alors à
louvrir dans un éditeur de texte, ou à le déposer dans la fenêtre du
navigateur.
Dans le bloc `properties` de chaque élément, nous observons plusieurs
associations clef-valeur : la propriété **name** contient le nom de la
station, **capacity** contient le nombre demplacements. Ces propriétés
correspondent à nos entêtes de colonnes dun fichier CSV (cf. tuto
précédent).
Nous pouvons alors configurer le **Gabarit de la popup** pour afficher
ces informations dans linfobulle de chaque station, comme nous lavons
vu dans le [tuto précédent](9-map-from-spreadsheet.md).
Par exemple :
# {name}
{capacity} emplacements
### 2. Je combine deux calques pour les mêmes données
Il y a beaucoup de stations Vélib et la carte est un peu dense à
léchelle de Paris. À cette échelle il serait plus intéressant davoir
une vue densemble de la répartition de loffre Vélib sur la capitale
et les communes voisines.
![umap-heatmap.png](../../static/tutoriels/10-jintegre-des-donnees-distantes/umap-heatmap.png)
#### Produire une carte de chaleur ou « Heatmap »
uMap permet de présenter les données dun calque sous plusieurs formes,
avec le menu déroulant **Type de calque** dans le menu *Propriétés du
calque*. Les différents types de calques sont :
- **Par défaut** : chaque donnée est affichée individuellement.
- **Avec cluster** : les points proches sont regroupés en un seul
cercle.
- **Heatmap** : les données sont représentées sous forme de *carte de
chaleur*.
- **Cloroplèthe** : cet affichage est adapté aux polygones, et permet
de graduer leur couleur.
Les types *Avec cluster* et *Heatmap* sont plutôt adaptés aux calques
contenant uniquement des points. Lorsquon choisit un de ces modes, un
onglet de configuration apparaît. Pour le type *Heatmap*, longlet
**Heatmap: paramètres** permet dajuster lintensité ou *chaleur* de
la carte (du bleu glacial au rouge brûlant), et de sélectionner une
propriété pour évaluer cette *chaleur*. Celle-ci doit correspondre à une
propriété de nos données contenant des valeurs numériques. Si aucune
propriété nest définie, chaque point a la même valeur et seule la
densité géographique des points influe sur la *heatmap*.
Notre fichier de stations contient justement la propriété `capacity`,
qui correspond au nombre demplacements de chaque station un bon
critère pour représenter loffre de vélos en libre-service. Quant au
**Rayon de heatmap**, un curseur permet de lajuster avec effet immédiat
sur la carte. Il est judicieux de tester ce rayon à différents niveaux
de zoom de la carte, afin que la carte révèle bien les données.
#### Dupliquer le calque
Le type daffichage dun calque sapplique quel que soit le niveau de
zoom. Or aux niveaux de zooms élevés, à léchelle du quartier, il est
plus intéressant de montrer les stations individuelles que la carte de
chaleur. Nous allons combiner les 2 représentations en créant 2 calques
qui utilisent les mêmes données, lun affichant les stations
individuelles, lautre sous forme de Heatmap. Lastuce consiste ensuite
à activer ou désactiver chaque calque en fonction du niveau de zoom.
Procédons par étapes :
1. Dupliquons notre calque avec lopération **Cloner** disponible dans
longlet **Opérations avancées** du panneau Propriétés du calque.
2. Le panneau Propriétés du nouveau calque est alors affiché :
renommons ce calque, par exemple « Heatmap stations Vélib ».
3. Changeons le type de calque pour **Heatmap**, longlet **Heatmap:
paramètres** apparaît.
4. Dans cet onglet, saisissons le nom de la propriété `capacity` et
ajustons le **rayon de heatmap** (une valeur autour de 30 fonctionne
bien pour ce jeu de données)
5. Dans longlet **Données distantes**, configurons le calque pour
quil saffiche **jusquau zoom** 15.
6. De la même manière, configurons le calque initial pour quil
saffiche **à partir du zoom** 15.
Nous faisons ici le choix de superposer, au zoom 15, la heatmap aux
stations individuelles. Cela produit une transition entre les 2 modes de
représentation, et permet de repérer les stations avec un grand nombre
demplacements.
Notez que nous navons pas eu besoin de préciser lURL des données
distantes et leur format : ces paramètres ont été conservés lors de la
duplication du calque.
### 3. Jutilise des données dynamiques
Un autre jeu de données du portail open data sintitule « Vélib - Vélos
et bornes - Disponibilité temps réel » :
<https://opendata.paris.fr/explore/dataset/velib-disponibilite-en-temps-reel/>.
Nous pouvons utiliser ces données *en temps réel* en réalité avec un
léger différé  pour alimenter notre carte uMap, et afficher le nombre
de places et de vélos disponibles. La procédure est la même que
ci-dessus, à une nuance près : loption **Dynamique** de longlet
**Données distantes** doit être activée. Elle indique à uMap de
récupérer les données à chaque affichage de la carte, cest-à-dire à
chaque fois que la carte est déplacée, zoomée ou dézoomée. Pour autant,
ces données ne seront pas automatiquement mises à jour par uMap à un
intervalle de temps régulier : cest à lutilisateur de rafraîchir la
page web ou de déplacer la carte.
![umap-api-properties.png](../../static/tutoriels/10-jintegre-des-donnees-distantes/umap-api-properties.png)
Il reste à
modifier notre gabarit de popup pour afficher les disponibilités en
temps réel. Pour identifier le nom des propriétés, nous pouvons utiliser
longlet **API** sur le portail open data : le panneau **Résultats**
montre un extrait des données avec toutes leurs propriétés. Ces
propriétés sont les mêmes que pour lexport GeoJSON. Voici un exemple
possible de gabarit de popup :
# {name}
{capacity} emplacements dont {numdocksavailable} libres
{numbikesavailable} vélos disponibles dont {ebike} VAE
![umap-api-parameters.png](../../static/tutoriels/10-jintegre-des-donnees-distantes/umap-api-parameters.png)
#### Filtrer les données à la source
Le panneau Résultats dans longlet **API** nous montre lexistence de la
propriété `is_installed`. Celle-ci permet de détecter des stations qui
ne sont pas en service, que nous ne souhaitons pas afficher sur notre
carte.
Le panneau **Requête pour lappel API** permet de générer une requête,
affichée sous ce panneau (**URL de lappel API**), et de visualiser les
données produites par cette requête dans le panneau **Résultats**. Il
permet également dajouter des paramètres à la requête, pour filtrer les
données produites. Le paramètre **refine** permet de filtrer les données
en fonction de la valeur dune ou plusieurs propriétés. Si nous
indiquons `is_installed` pour le nom de la propriété et `NON` pour la
valeur, nous pouvons voir le nombre de stations qui ne sont pas en
service, et que nous ne voulons pas intégrer à notre carte.
Les données produites à laide cet onglet **API** sont au format GBFS,
qui nest pas connu de uMap. Les requêtes dexport au format GeoJSON
acceptent les mêmes paramètres. Pour produire les données filtrées au
format GeoJSON, nous devons donc éditer la requête *à la main*.
Procédons par étapes *un peu geek* :
1. Saisir `is_installed` et `OUI` dans le champ **refine**
2. Supprimer la valeur du champ `limit`, car nous ne voulons pas
*limiter* la réponse de la requête à 20 stations.
3. Observons la requête générée :
`/api/explore/v2.1/catalog/datasets/velib-disponibilite-en-temps-reel/records?refine=is_installed%3AOUI`,
elle se compose de 3 sections :
- lURL de base, jusquau dernier caractère **`/`**
- le **endpoint** `records` suivi du caractère **`?`**
- le paramètre `refine=is_installed%3AOUI` (`%3A` est l*encodage*
du caractère **`:`**)
4. Prenons la requête générée pour lexport GeoJSON :
`https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/velib-disponibilite-en-temps-reel/exports/geojson?lang=fr&timezone=Europe%2FBerlin`,
elle se compose des mêmes sections :
- lURL de base :
`https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/velib-disponibilite-en-temps-reel/exports/`
- le endpoint `geojson?`
- la liste de paramètres `lang=fr&timezone=Europe%2FBerlin` (`%2F`
est lencodage du caractère **`&`** qui permet de séparer
plusieurs paramètres)
5. Nous pouvons combiner lURL et le endpoint de la requête GeoJSON,
suivi du paramètre `refine=is_installed%3AOUI` (les paramètres
`lang` et `timezone` ne sont ici pas utiles) :
`https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/velib-disponibilite-en-temps-reel/exports/geojson?refine=is_installed%3AOUI`
Utiliser cette requête comme URL des données distantes de notre calque
**Stations Vélib** permet de nafficher que les stations en service.
Notez que pouvons aussi utiliser le paramètre `exclude` pour exclure les
stations dont la propriété `is_installed` a la valeur `NON`. Nous
pouvons utiliser ce même mécanisme pour exclure les stations qui nont
aucun vélo disponible :
https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/velib-disponibilite-en-temps-reel/exports/geojson?exclude=is_installed%3ANON&exclude=numbikesavailable%3A0
### 4. Jinjecte des paramètres dans la requête
uMap permet dinjecter dans une requête des paramètres, avec la syntaxe
`{paramX}`. Ces paramètres dépendent de létat de la carte au moment de
lenvoi de la requête :
- les coordonnées du centre de la carte : {lat} et {lng}
- la *bounding_box* de la carte : {bbox} ou {west}, {south}, {east} et
{north}
- le niveau de zoom : {zoom}
Le portail open data peut prendre en compte certains de ces paramètres
pour affiner la requête. Notre objectif est ici de récupérer la
disponibilité des stations se trouvant **dans la partie visible de la
carte**, cest-à-dire dans la *bounding_box*. Cela permet de réduire le
volume de données transférées, et de les afficher plus rapidement.
#### Jutilise la console dAPI de la plateforme open data
Longlet API du jeu de données permet daccéder à la **console dAPI
complète**. Nous choisissons, dans la section Dataset, le *endpoint*
**Export a dataset**.
![umap-api-console.png](../../static/tutoriels/10-jintegre-des-donnees-distantes/umap-api-console.png)
Apparaît alors un formulaire où nous pouvons renseigner les différents
paramètres :
- **dataset_id** est lidentifiant du jeu de données :
`velib-disponibilite-en-temps-reel`
- pour le **format** nous sélectionnons `geojson`
- nous pouvons à nouveau filtrer les stations en service avec le
paramètre **refine** : `is_installed:OUI`
![umap-api-console-dataset.png](../../static/tutoriels/10-jintegre-des-donnees-distantes/umap-api-console-dataset.png)
Définissons le paramètre **where** avec la fonction `in_bbox()` (voir la
[documentation
OpenDataSoft](https://help.opendatasoft.com/apis/ods-explore-v2/#section/ODSQL-predicates/in_bbox()))
et pour linstant des latitudes et longitudes fixes (quelque part à
Paris) :
![umap-api-console-bbox.png](../../static/tutoriels/10-jintegre-des-donnees-distantes/umap-api-console-bbox.png)
**coordonnees_geo** est le nom du champ contenant la géométrie dans les
données dorigine, que lon peut trouver en les exportant dans un format
autre que GeoJSON.
Testons maintenant que la requête fonctionne en cliquant sur **Execute**
: le code de réponse 200 indique que la requête a fonctionné, et il est
possible de télécharger le fichier résultant.
![umap-api-console-execute.png](../../static/tutoriels/10-jintegre-des-donnees-distantes/umap-api-console-execute.png)
#### Je dynamise la requête
Modifions maintenant notre requête *statique* (tous les paramètres sont
fixes) pour la rendre *dynamique*, en remplaçant les coordonnées de la
bounding_box par les paramètres qui seront injectés par uMap. Nous
nutilisons pas ici le paramètre `{bbox}`, car lordre des valeurs ne
correspond pas à celui attendu par lAPI open data. La fonction sécrit
alors :
in_bbox(coordonnees_geo,{south},{west},{north},{east})
ce qui donne avec lencodage :
in_bbox%28coordonnees_geo%2C{south}%2C{west}%2C{north}9%2C{east}%29
La requête encodée complète est donc :
https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/velib-disponibilite-en-temps-reel/exports/geojson?where=in_bbox%28coordonnees_geo%2C{south}%2C{west}%2C{north}9%2C{east}%29&limit=-1&refine=is_installed%3AOUI
Il ne reste plus quà utiliser cette requête comme URL pour nos données
distantes.
Notez quil nest pas nécessaire dutiliser la forme encodée, car uMap
procédera à lencodage. LURL peut donc être plus lisible :
https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/velib-disponibilite-en-temps-reel/exports/geojson?where=in_bbox(coordonnees_geo,{south},{west},{north},{east})&limit=-1&refine=is_installed:OUI
## Faisons le point
La carte produite pour ce tuto est visible ici :
<http://u.osmfr.org/m/1051915/>
Nous avons vu comment **exploiter des données open data** sans les
télécharger, ce qui permet que notre carte reste à jour (à condition
bien sûr que les données soient actualisées par leur producteur). Nous
avons également vu comment **optimiser la requête** en injectant la
*bounding box* de la partie visible de la carte.
Dautres sites mettent à disposition des données via une API, lenjeu
est alors de sapproprier la syntaxe des requêtes en lisant la
documentation et testant les requêtes.
??? info "Licence"
Travail initié par Antoine Riche sur [CartoCité](https://wiki.cartocite.fr/doku.php?id=umap:10_-_j_integre_des_donnees_distantes) sous licence [CC-BY-SA 4](https://creativecommons.org/licenses/by-sa/4.0/deed.fr).