Introduction aux Systèmes d'Information Géographiques – TP OpenStreetMap, partie Python
Table of Contents
1 On enrobe tout ça dans un programme Python
Vous êtes désormais des experts en interrogation spatiale avec PostGIS. Il est maintenant temps d'enrober tout cela dans une couche un peu plus conviviale que le client
ligne de commande PostgreSQL. Nous allons à partir de maintenant embarquer toutes les requêtes dans un programme Python, et accéder à la base par l'intermédiaire du
module psycopg2
.
Afin de vous faciliter la tâche dans cette partie, nous vous fournissons un certain nombre de modules et de squelettes de code qu'il vous faudra compléter. Commencez donc par télécharger l'archive : python-osm.tar.gz
1.1 Connexion à la base via psycopg2
Nous allons dans un premier temps tester la connexion à la base de données OSM. Pour cela, il faudra que vous installiez les modules Python :
psycopg2
postgis
Complétez le fichier config.py
avec vos informations de connexion.
1.2 Une première requête
Grâce au module psycopg2
, vous pouvez exécuter une requête sur une base
de données Postgres, et récupérer en réponse un objet de type cursor
. Grâce à un tel objet,
vous pouvez itérer sur l'ensemble des lignes renvoyées par la requête.
Grâce au module postgis
, vous pouvez récupérer dans les lignes des valeurs
ayant pour type des géométries (points, linestrings, etc.). Voyez plutôt l'exemple
suivant :
import database as db cursor = db.execute_query("Ici ma belle requête") for row in cursor: # Pour chaque ligne ls = row[1] # On suppose que la deuxième valeur de chaque ligne est de type linestring for point in ls: # On peut itérer sur une linestring print(point.x, point.y) # et récupérer des points cursor.close() db.close_connection()
Question 10 : Écrivez un petit programme de test prenant un argument en ligne de commande, et affichant tous les noms et coordonnées géographiques des points dont le nom
ressemble à (au sens du LIKE
SQL) l'argument. À titre d'exemple, un tel programme appelé sur la chaîne
Dom__ne _niversit%
devrait renvoyer :
Domaine Universitaire | 5.7588187 | 45.1935807 Domaine Universitaire | 5.758102 | 45.1874865 Domaine Universitaire | 5.7569834 | 45.1870508 Domaine Universitaire | 5.7695911 | 45.1881104 Domaine Universitaire | 5.7611708 | 45.1898362 (3 rows)
2 Un joli affichage graphique…
Toutes ces interfaces en ligne de commande sont très pratiques, mais bien ternes. Nous allons mettre un peu d'affichage graphique là-dessous. Nous pourrions écrire notre propre interface graphique, mais nous allons faire mieux : nous allons écrire un mini serveur cartographique et profiter des standards d'échange (WMS en l'occurrence) pour déléguer la partie d'affichage à une bibliothèque Javascript dédiée : Leaflet.
Ça a l'air compliqué comme ça, mais en fait ce sera très simple. Et même, la plupart des tâches suivantes sont parallélisables, donc vous n'êtes pas tous obligés de travailler sur la même partie en même temps.
2.1 Génération d'images
Tout d'abord, nous allons nous concentrer sur la génération de cartes au format PNG
à partir de requêtes à la base de données.
Cette partie nous servira pour la génération des tuiles WMS.
L'objectif de cette partie est d'écrire une fonction python prenant en paramètres :
- les coordonnées d'un rectangle (une boîte englobante) dans un système de référence spatial particulier,
- une largeur et une hauteur d'images (
width
etheight
).
Cette fonction devra :
- récupérer dans la base de données OSM tous les chemins possédant l'attribut
highway
et contenus dans la boîte englobante passée en paramètre ; - générer une image
PNG
de taille (width
,height
) et qui trace sous forme de lignes tous les chemins récupérés par la requête précédente (NB : si vous voulez, vous pouvez utiliser une couleur ou un style différent selon la valeur de l'attributhighway
).
Vous pouvez pour cela vous aider de la classe Image
du module drawer
fourni. Un coup d'œil au code vous aidera
à comprendre comment l'utiliser. Attention, pour utiliser ce module, vous devrez installer le module pycairo
.
Question 11 : Écrivez la fonction demandée, ainsi qu'un petit programme qui la teste sur la boîte englobante de longitudes comprises entre 5.7 et 5.8, et latitudes comprises entre 45.1 et 45.2, dans le système WGS84.
2.2 Serveur WMS
Un serveur cartographique est simplement un serveur HTTP qui répond à des requêtes GET
formulées très poliment sous
un format particulier, en renvoyant par exemple des morceaux de cartes.
Dans cette partie, nous allons implanter un mini-serveur cartographique qui comprend une petite partie du protocole WMS.
Pour cela, commencez par récupérer le fichier WMSServer.py
. Ce fichier contient un mini-serveur HTTP qu'il va falloir
compléter un peu. Voici ce que doit faire votre serveur :
Chaque fois qu'il reçoit une requête GET
sur la bonne url (wms/
), il récupère les paramètres suivants :
request
(doit être égal à "GetMap")layers
(le nom du calque à récupérer – c'est vous qui fixez ce nom)height
(la hauteur de l'image renvoyée)width
(la largeur de l'image renvoyée)srs
(le système de référence spatial,EPSG:3857
dans votre cas)bbox
(les coordonnées de la boîte englobante demandée, exprimées dans le SRS spécifié).
Si l'un de ces paramètres est manquant ou incorrect, votre serveur renverra au client un message d'erreur explicite sous forme de texte.
Sinon, il devra générer une image PNG
de la zone désignée par bbox
et de la taille désignée par width
, height
, en utilisant
la fonction que vous avez écrite à la question 12. Attention ! Votre serveur ne parle que le SRS EPSG:3857
. Assurez-vous que toutes
vos coordonnées et géométries soient générées dans ce SRS.
Question 12 : Complétez le fichier WMSServer.py
pour implanter le serveur WMS tel que décrit ci-dessus.
2.3 Côté client
Maintenant, nous allons tester si votre serveur WMS fonctionne.
Question 13 : Lancez votre serveur pour qu'il écoute les connexions entrantes. Récupérez le fichier HTML fourni, ainsi que le fichier Javascript. Modifiez si besoin l'adresse de votre serveur WMS dans le fichier Javascript. Ouvrez le fichier HTML dans un navigateur Web et observez ce qu'il se passe. Si tout se passe bien, Leaflet affiche un fond de carte OSM standard, et affiche une couche contenant les tuiles que votre serveur a générées.
Ça ne fonctionne pas ? Pas de panique. La console de votre navigateur (côté client), et votre console (côté serveur) sont vos amies.
2.4 Un cache de tuiles
Votre serveur fonctionne bien, mais est très lent pour le moment. C'est normal, car il doit regénérer à la volée toutes les tuiles, et c'est inefficace. Il est possible d'optimiser un peu le processus en créant un cache de tuiles : si jamais on redemande une tuile pour une boîte englobante qui a déjà été demandée, plutôt que de regénérer la tuile, il est possible de renvoyer la tuile qui avait déjà été demandée.
Question 14 : Mettez en place un tel mécanisme de cache de tuiles.
2.5 D'autres couches
Vous avez travaillé sur l'ensemble des highways
de la base de données. Dans cette partie, vous pouvez donner libre cours
à votre imagination…
Question 15 : Créez d'autres couches (que vous pouvez rendre accessible également par le biais de votre serveur WMS) et ajoutez-les à votre client Leaflet. Quelques suggestions : ensemble des bâtiments, hydrographie (rivières, etc.), ensemble des pistes de ski autour de Grenoble, etc.