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 et height).

Cette fonction devra :

  1. 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 ;
  2. 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'attribut highway).

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.

Date: 2019-11-15 ven. 00:00

Author: Sylvain B.

Created: 2022-01-12 mer. 14:49

Validate