Python avec PostGIS
NOTE: La documentation officielle de PostGIS ainsi que la bibliothèque Python psycopg sont des ressources essentielles pour aller plus loin. Il faut parfois utiliser psycopg2 avec Python 3. Vous avez la possibilité d’utiliser ce GitHub Codespaces pour pratiquer les requêtes https://github.com/voirinprof/gis_starter_postgis_geolab. pgAdmin4 est disponible dans l’environnement. Pour mettre en place un environnement Codespaces allez voir Premiers pas avec GitHub Codespaces.
Introduction à PostGIS
PostGIS est une extension spatiale pour la base de données relationnelle PostgreSQL.
Elle permet de :
- Stocker des géométries (points, lignes, polygones) au format SQL standard
- Faire des calculs spatiaux complexes (distances, intersections, buffers)
- Réaliser des requêtes spatiales optimisées grâce aux index
En géomatique, PostGIS est utilisé pour :
- Gérer de grands volumes de données géospatiales (cadastres, réseaux, capteurs)
- Effectuer des analyses spatiales avancées (zonage, accessibilité)
- Servir de backend pour des applications SIG et web cartographiques
Installation de PostGIS et bibliothèques Python
Installez PostgreSQL et ajoutez l’extension PostGIS.
Côté Python, installez :
pip install psycopg[binary] geoalchemy2 sqlalchemy
psycopg
: connexion PostgreSQLSQLAlchemy
+GeoAlchemy2
: ORM pour les objets spatiaux
Conseil : Utilisez
Docker
pour lancer rapidement une instance PostgreSQL + PostGIS en local.
Connexion à PostGIS en Python
Connexion simple avec psycopg
import psycopg
conn = psycopg.connect("dbname=geomatique user=postgres password=motdepasse host=localhost")
cur = conn.cursor()
Connexion avancée avec SQLAlchemy
from sqlalchemy import create_engine
engine = create_engine("postgresql+psycopg://postgres:motdepasse@localhost/geomatique")
Créer une table spatiale
Exemple : stocker des points d’intérêt géographiques.
CREATE TABLE points_interet (
id SERIAL PRIMARY KEY,
nom TEXT,
geom GEOMETRY(Point, 4326)
);
4326
est le code EPSG pour WGS84 (latitude/longitude standard GPS).
Insérer des données spatiales en Python
cur.execute("""
INSERT INTO points_interet (nom, geom)
VALUES (%s, ST_SetSRID(ST_MakePoint(%s, %s), 4326))
""", ("Tour Eiffel", 2.2945, 48.8584))
conn.commit()
ST_SetSRID
définit le système de référence spatiale (ici WGS84).
Effectuer des requêtes spatiales
Trouver des points proches d’un lieu
Exemple : tous les points à moins de 500 mètres de la Tour Eiffel.
cur.execute("""
SELECT nom
FROM points_interet
WHERE ST_DWithin(
geom::geography,
ST_SetSRID(ST_MakePoint(%s, %s), 4326)::geography,
%s
)
""", (2.2945, 48.8584, 500))
resultats = cur.fetchall()
for row in resultats:
print(row[0])
ST_DWithin
permet de filtrer selon une distance en mètres si vous convertissez engeography
.
Cas d’usage en géomatique
1. Stockage de trajets ou de réseaux
Vous pouvez utiliser le type LINESTRING
pour des routes ou des trajets GPS :
CREATE TABLE trajets (
id SERIAL PRIMARY KEY,
vehicule_id TEXT,
geom GEOMETRY(LineString, 4326)
);
Insertion Python :
trajet_coords = [(2.2945, 48.8584), (2.2950, 48.8585), (2.2960, 48.8586)]
linestring = "LINESTRING({})".format(
", ".join(f"{lon} {lat}" for lon, lat in trajet_coords)
)
cur.execute("""
INSERT INTO trajets (vehicule_id, geom)
VALUES (%s, ST_SetSRID(ST_GeomFromText(%s), 4326))
""", ("bus_42", linestring))
conn.commit()
2. Analyse d’intersections ou de recoupements
Trouver tous les trajets qui croisent une zone donnée :
zone = "POLYGON((2.293 48.857, 2.296 48.857, 2.296 48.860, 2.293 48.860, 2.293 48.857))"
cur.execute("""
SELECT vehicule_id
FROM trajets
WHERE ST_Intersects(
geom,
ST_SetSRID(ST_GeomFromText(%s), 4326)
)
""", (zone,))
resultats = cur.fetchall()
for row in resultats:
print(row[0])
Bonnes pratiques
- Créez des index spatiaux pour accélérer vos requêtes :
CREATE INDEX idx_points_geom ON points_interet USING GIST (geom);
- Utilisez
geography
si vous travaillez sur de grandes distances terrestres (calculs précis sur une sphère). - Toujours préciser le SRID (code EPSG) pour éviter des erreurs de référence spatiale.
- Séparez les rôles : utilisez des utilisateurs Postgres avec des droits limités en production.