Route Calculation with pgRouting
NOTE: There are several approaches to route calculation from a road network. You can use PostGIS’s pgRouting, a simple library like networkx, or even use Neo4j. See the example of pgRouting with a custom road network and a Flask web service https://github.com/voirinprof/gis_pgrouting_docker. If you want to see how to use networkx for route calculation, use this repo: https://github.com/voirinprof/gis_nx_docker.
Introduction to pgRouting
pgRouting is a PostGIS extension that adds route calculation and network analysis capabilities to a PostgreSQL/PostGIS database.
In geomatics, pgRouting allows:
- Calculation of the shortest routes (fastest, shortest, multimodal)
- Network analysis (accessibility, graphs, multiple routes)
- Processing of large road networks directly in the database
NOTE: The official pgRouting documentation is very useful to explore all the available features.
Installing pgRouting
On a server with PostgreSQL and PostGIS, install pgRouting:
sudo apt install postgresql-15-pgrouting
Then enable the extension in your database:
CREATE EXTENSION pgrouting;
Tip: pgRouting works on graphs stored as edge tables.
Preparing a Road Network
Your road network must be structured as an edge table:
CREATE TABLE reseau_routier (
id SERIAL PRIMARY KEY,
source BIGINT,
target BIGINT,
geom GEOMETRY(LineString, 4326),
cost DOUBLE PRECISION
);
source
: ID of the start nodetarget
: ID of the end nodecost
: Cost to traverse the edge (distance, time, etc.)
You can use
pgr_createTopology
to automatically generatesource
andtarget
fromgeom
.
SELECT pgr_createTopology('reseau_routier', 0.0001, 'geom', 'id');
Connecting to pgRouting in Python
Install dependencies:
pip install psycopg sqlalchemy shapely
Simple connection:
import psycopg
conn = psycopg.connect("dbname=geomatique user=postgres password=password host=localhost")
cur = conn.cursor()
Calculating the Shortest Path
Assuming you know the source_id
and target_id
in your network:
start = 1001
end = 1050
cur.execute("""
SELECT seq, id1 AS node, id2 AS edge, cost
FROM pgr_dijkstra(
'SELECT id, source, target, cost AS cost FROM reseau_routier',
%s, %s,
directed := true
)
""", (start, end))
path = cur.fetchall()
for line in path:
print(f"Step {line[0]}: pass through node {line[1]} via edge {line[2]} (cost {line[3]})")
pgr_dijkstra
is the classic shortest path algorithm.
Other Useful pgRouting Features
- Route to multiple destinations:
pgr_dijkstraVia
- Calculate cost matrices between multiple points:
pgr_dijkstraCostMatrix
- Isochrone search (reachable areas by distance or time):
pgr_drivingDistance
Example of driving distance:
SELECT * FROM pgr_drivingDistance(
'SELECT id, source, target, cost FROM reseau_routier',
1001,
2000 -- maximum distance
);
Best Practices
- Create indexes on
source
andtarget
to speed up calculations:CREATE INDEX ON reseau_routier(source); CREATE INDEX ON reseau_routier(target);
- Optimize your network: limit unnecessary edges, check topology.
- Use a metric projection system (e.g., EPSG:2154 for France) for accurate distances.
- Separate directed and undirected networks according to your needs.
Use Cases in Geomatics
- Vehicle route calculation (deliveries, buses, emergency services)
- Accessibility analysis (distance to hospitals, schools)
- Origin-Destination matrices for mobility flows