Index de l'article

Autres exemples d'APIs

Ce chapitre est une parenthèse dans ce tutoriel, pour présenter quelques exemples d'exploitation d'APIs.

Un XML (http://mob.u-strasbg.fr/)

L'université de Strasbourg entretient une API fournissant des POIs, exemple :

La forme du XML généré est plus classique que ceux d'OSM :

<rss version="2.0">
  <poi>
    <id>1</id>
    <name>Central</name>
    <latitude>48.5803337</latitude>
    <longitude>7.7655637</longitude>
    <floor/>
    <type>campus</type>
    <description/>
    <url>http://fr.wikipedia.org/wiki/Campus_central_de_Strasbourg</url>
    <url_image/>
    <tags/>
    <capacity>0</capacity>
  </poi>
 
  <poi>
    <id>2</id>
...

Pour extraire les données de ce type d'XML :

import requests
import xml.etree.ElementTree
 
r = requests.get('http://mob.u-strasbg.fr/cgi-bin/odudsApi.py?method=search&amp;id=allpois')
root = xml.etree.ElementTree.fromstring(r.content)
for my_poi in root.findall('poi'):
    my_name = my_poi.find('name').text
    print(my_name)

Afficher les points à partir de leurs coordonnées

Le code suivant, dans un projet QGIS vide, affiche un fond de carte OSM, crée puis affiche une couche virtuelle de points, avec 2 champs, peuplée des points issus d'un XML. Toujours à partir de l'API de l'université de Strasbourg :

  1. import requests
  2. import xml.etree.ElementTree
  3.  
  4. # VIDER PROJET
  5. QgsProject.instance().removeAllMapLayers()
  6. iface.mapCanvas().refresh()
  7.  
  8. # PARAMETRES OSM
  9. urlWithParams = "type=xyz&amp;url=http://tile.openstreetmap.org/{z}/{x}/{y}.png"
  10. osm = QgsRasterLayer(urlWithParams, "OpenStreetMap", "wms")
  11.  
  12. # CREER UNE COUCHE VIRTUELLE DE POINTS
  13. point_vector = QgsVectorLayer("Point", "my_points", "memory")
  14.  
  15. # AFFICHER LES COUCHES
  16. QgsProject.instance().addMapLayer(osm)
  17. QgsProject.instance().addMapLayer(point_vector)
  18.  
  19. # AJOUTER CHAMPS DANS point_vector
  20. from qgis.PyQt.QtCore import QVariant
  21. pr = point_vector.dataProvider()
  22. pr.addAttributes([QgsField("id", QVariant.Int), QgsField("name", QVariant.String)])
  23. point_vector.updateFields()
  24.  
  25. # PARSER LE FICHIER
  26. r = requests.get('http://mob.u-strasbg.fr/cgi-bin/odudsApi.py?method=search&amp;id=allpois')
  27. root = xml.etree.ElementTree.fromstring(r.content)
  28.  
  29. for my_poi in root.findall('poi'):
  30. my_id = int(my_poi.find('id').text)
  31. my_name = str(my_poi.find('name').text)
  32. my_longitude = float(my_poi.find('longitude').text)
  33. my_latitude = float(my_poi.find('latitude').text)
  34. #print(my_id, my_name, my_longitude, my_latitude)
  35.  
  36. # EDITER COUCHE VIRTUELLE
  37. f = QgsFeature()
  38. f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(my_longitude, my_latitude)))
  39. f.setAttributes([my_id, my_name])
  40. pr.addFeature(f)
  41. point_vector.updateExtents()
  42. QgsProject.instance().addMapLayer(point_vector)
  43.  
  44. # RAFRAICHIR
  45. iface.mapCanvas().refresh()
  46.  
  47. # CRS
  48. my_crs=QgsCoordinateReferenceSystem(3857)
  49. QgsProject.instance().setCrs(my_crs)

Aller chercher l'image sous condition

...
for my_poi in root.findall('poi'):
    my_id = int(my_poi.find('id').text)
    my_name = str(my_poi.find('name').text)
 
    my_divers = str(my_poi.find('url_image').text)
 
    if my_divers == "None":
        my_divers = ""
    elif my_divers != "None":
        my_divers = "https://mob.u-strasbg.fr/geoloc/url_image/" + my_divers
 
    my_longitude = float(my_poi.find('longitude').text)
...

 

Un JSON (data.culture.gouv.fr, monuments historiques)

Le site data.culture.gouv.fr propose plusieurs APIs, dont les données sont fournis en JSON.

Exemple avec la liste des immeubles parisiens protégés au titre des monuments historiques :

Quand vous êtes confronté à ce type de fichiers, dont la visualisation en ligne n'est pas toujours aisée, il existe ce type d'outil en ligne qui vous permettra d'en comprendre la structure ou de tester votre fichier :

Sur jsonviewer utilisez le bouton Load JSON data et copiez-y l'URL (supprimez le « s » du https de votre URL si besoin). Sur geojson.io copiez vos données GEOJSON dans l'encart prévu, ou ajoutez l'adresse de votre fichier GEOJSON comme dans l'exemple ci-dessus (à la place de [URL]).

Pour parser ce type de JSON, et en extraire les données :

  1. import json
  2. import requests
  3.  
  4. response = requests.get("https://data.culture.gouv.fr/api/records/1.0/search/?dataset=liste-des-immeubles-proteges-au-titre-des-monuments-historiques&amp;q=&amp;facet=reg&amp;facet=dpt_lettre&amp;refine.dpt_lettre=Paris")
  5. my_file = json.loads(response.text)
  6.  
  7. my_json = my_file["records"]
  8.  
  9. for my_block in my_json:
  10. my_fields = my_block["fields"]
  11. print(my_fields["wadrs"])

Les lignes 4 et 5 en font un JSON lisible pour Python.

Les données qui nous intéressent sont dans le bloc records, nous l'isolons donc avec la ligne 7.

La ligne 9 boucle sur le bloc records, et pour chaque sous-blocs fields affiche les données du tag wadrs.

Un JSON (data.culture.gouv.fr, événements publics cibul)

https://public.opendatasoft.com/api/records/1.0/search/?dataset=evenements-publics-cibul&q=&rows=1354&facet=tags&facet=placename&facet=department&facet=region&facet=city&facet=date_start&facet=date_end&facet=pricing_info&facet=updated_at&facet=city_district&refine.tags=musique&refine.tags=gratuit&refine.department=Paris

Récupérer les informations :

import json
import requests
 
response = requests.get(
"https://public.opendatasoft.com/api/records/1.0/search/?dataset=evenements-publics-cibul&amp;q=&amp;rows=1354&amp;facet=tags&amp;facet=placename&amp;facet=department&amp;facet=region&amp;facet=city&amp;facet=date_start&amp;facet=date_end&amp;facet=pricing_info&amp;facet=updated_at&amp;facet=city_district&amp;refine.tags=musique&amp;refine.tags=gratuit&amp;refine.department=Paris")
 
my_file = json.loads(response.text)
my_json = my_file["records"]
 
for my_block in my_json:
    my_fields = my_block["fields"]
    my_uid = my_fields["uid"]
    my_title = my_fields["title"]
 
    my_geometry = my_block["geometry"]
    my_coordinates = my_geometry["coordinates"]
 
    print("my_uid :",my_uid, "my_coordinates :", my_coordinates, "my_title :", my_title)

Récupérer proprement les coordonnées

Pour utiliser les points, il faudra d'abord les splitter :

    my_geometry = my_block["geometry"]
    my_coordinates = my_geometry["coordinates"]
 
    my_lat = str(my_coordinates).split(", ")[0].replace("[", "")
    my_lon = str(my_coordinates).split(", ")[1].replace("]", "")

Afficher les points à partir de leurs coordonnées

import requests
import json
 
# VIDER PROJET
QgsProject.instance().removeAllMapLayers()
iface.mapCanvas().refresh()
 
# CREER UNE COUCHE VIRTUELLE DE POINTS
point_vector = QgsVectorLayer("Point", "my_points", "memory")
 
# AFFICHER LES COUCHES
QgsProject.instance().addMapLayer(point_vector)
 
# AJOUTER CHAMPS DANS point_vector
from qgis.PyQt.QtCore import QVariant
pr = point_vector.dataProvider()
pr.addAttributes([QgsField("uid", QVariant.Int), QgsField("title", QVariant.String)])
point_vector.updateFields()
 
# PARSER LE FICHIER
response = requests.get('https://public.opendatasoft.com/api/records/1.0/search/?dataset=evenements-publics-cibul&amp;q=&amp;rows=1354&amp;facet=tags&amp;facet=placename&amp;facet=department&amp;facet=region&amp;facet=city&amp;facet=date_start&amp;facet=date_end&amp;facet=pricing_info&amp;facet=updated_at&amp;facet=city_district&amp;refine.tags=musique&amp;refine.tags=gratuit&amp;refine.department=Paris')
 
my_file = json.loads(response.text)
my_json = my_file["records"]
 
for my_block in my_json:
    my_fields = my_block["fields"]
    my_uid = my_fields["uid"]
    my_title = my_fields["title"]
 
    my_geometry = my_block["geometry"]
    my_coordinates = my_geometry["coordinates"]
    my_lat = str(my_coordinates).split(", ")[0].replace("[", "")
    my_lon = str(my_coordinates).split(", ")[1].replace("]", "")
 
    print("my_uid :", my_uid,"my_coordinates :", my_coordinates,"my_lat :", my_lat,"my_lon :", my_lon,"my_title :", my_title)
 
    # EDITER COUCHE VIRTUELLE
    f = QgsFeature()
    f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(float(my_lon), float(my_lat))))
    f.setAttributes([my_uid, my_title])
    pr.addFeature(f)
    point_vector.updateExtents()
    QgsProject.instance().addMapLayer(point_vector)
 
# RAFRAICHIR
iface.mapCanvas().refresh()

 

Un GEOJSON

Pour ouvrir un fichier GEOJSON, ce ne sera pas compliqué (source : webgeodatavore) :

iface.addVectorLayer('https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_populated_places.geojson', 'Populated places', 'ogr')

Mais pour ouvrir des données GEOJSON brutes (construites à la volée par une API par exemple, ou simplement non-accessibles par URL), alors vous devrez d'abord les enregistrer dans un fichier, puis ouvir ce fichier.

Un GEOJSON (API zones isochrones https://openrouteservice.org)

Pensez à vérifier que la structure d'usage des APIs d'openrouteservice n'a pas changé ! Des exemples de codes peuvent être générés sur leur site.

Exemple avec l'excellente API de zones isochrones d'openrouteservice (votre obtiendrez une clé gratuite après une rapide inscription) :

import requests
 
body = {"locations":[[8.681495,49.41461],[8.686507,49.41943]],"range":[300,200]}
headers = {
    'Accept': 'application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8',
    'Authorization': 'VOTRE CLE API',
    'Content-Type': 'application/geo+json; charset=utf-8'
}
call = requests.post('https://api.openrouteservice.org/v2/isochrones/driving-car', json=body, headers=headers)
 
#print(call.status_code, call.reason)
#print(call.text)
 
with open('C:/Users/Georges/Downloads/myfile.geoson', 'w', encoding='utf-8') as outfile:
    outfile.write(call.text)
 
iface.addVectorLayer('C:/Users/Georges/Downloads/myfile.geoson', 'Isochrones', 'ogr')

Un autre GEOJSON (API directions https://openrouteservice.org)

import requests
 
headers = {
'Accept': 'application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8',
}
call = requests.get('https://api.openrouteservice.org/v2/directions/driving-car?api_key=VOTRE CLE API&amp;start=8.681495,49.41461&amp;end=8.686507,49.41943', headers=headers)
 
#print(call.status_code, call.reason)
#print(call.text)
 
with open('C:/Users/Georges/Downloads/trajet.geoson', 'w', encoding='utf-8') as outfile:
    outfile.write(call.text)
iface.addVectorLayer('C:/Users/Georges/Downloads/trajet.geoson', 'trajet', 'ogr')

Et pour boucler sur plusieurs mode de déplacement, et créer autant de fichier geojson, et les afficher : 

import requests
 
MesModes = ['foot-hiking', 'driving-car', 'wheelchair']
 
for i in MesModes:
 
    Chemin = 'C:/Users/Georges/Downloads/trajet_' + i + '.geoson'
 
    headers = {
    'Accept': 'application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8',
    }
    call = requests.get('https://api.openrouteservice.org/v2/directions/' + i + '?api_key=VOTRE CLE API&amp;start=2.011776,49.048384&amp;end=2.077019,49.038914', headers=headers)
 
    with open(Chemin, 'w', encoding='utf-8') as outfile:
        outfile.write(call.text)
    iface.addVectorLayer(Chemin, 'trajet', 'ogr')

 

Obsolète

Liens ou pièces jointes
Accéder à cette adresse URL (https://hg-map.fr/extern/data/shapes/france/chemin_de_fer.zip)chemin_de_fer.zip[ ]0 Ko
Télécharger ce fichier (data_BDTOPO_V3_Dep05_adresse.zip)data_BDTOPO_V3_Dep05_adresse.zip[ ]3889 Ko
Télécharger ce fichier (data_IRIS_2019.zip)data_IRIS_2019.zip[ ]45905 Ko
Télécharger ce fichier (decathlon_france.zip)decathlon_france.zip[308 magasins Décathlon français depuis OSM le 27 décembre 2020]11 Ko
Accéder à cette adresse URL (https://hg-map.fr/extern/data/shapes/france/eau.zip)eau.zip[ ]0 Ko
Télécharger ce fichier (glaciers.zip)glaciers.zip[ ]231 Ko
Télécharger ce fichier (iso_iris.zip)iso_iris.zip[Des zones isochrones à 15 minutes autour de 308 POIs.]12125 Ko
Télécharger ce fichier (Koln GML.zip)Koln gml.zip[ ]2818 Ko
Télécharger ce fichier (peaks.zip)peaks.zip[ ]14 Ko
Télécharger ce fichier (peaks_selection.zip)peaks_selection.zip[ ]1 Ko
Télécharger ce fichier (simple_countries.zip)simple_countries.zip[ ]1880 Ko
Accéder à cette adresse URL (https://hg-map.fr/extern/data/shapes/france/sol.zip)sol.zip[ ]0 Ko
Accéder à cette adresse URL (https://hg-map.fr/extern/data/shapes/france/troncons_routes.zip)troncons_routes.zip[ ]0 Ko