Analisi delle rotte geospaziali con pgRouting su ServBay
pgRouting
è un potente modulo di estensione per i database PostgreSQL e PostGIS, progettato per fornire funzionalità ricche di routing e analisi delle reti su dati geospaziali. Con pgRouting
, gli sviluppatori possono eseguire query complesse sulla rete stradale, come trovare il percorso più breve tra due punti, risolvere il problema del commesso viaggiatore (TSP) o condurre analisi di aree di servizio. Queste funzionalità sono particolarmente utili nello sviluppo di applicazioni cartografiche, pianificazione logistica, analisi del traffico e molto altro.
Questo articolo spiega nel dettaglio come abilitare facilmente l'estensione pgRouting
nel database PostgreSQL utilizzato in ServBay, l'ambiente locale di sviluppo web, e come effettuare le configurazioni di base e le analisi di routing.
Panoramica
ServBay offre agli sviluppatori su macOS un pratico ambiente di sviluppo locale all-in-one, pre-integrando diversi server web, database e linguaggi di programmazione. Il pacchetto PostgreSQL fornito da ServBay include già le estensioni pgRouting
e PostGIS
. Questo significa che non è necessario scaricare o compilare manualmente queste estensioni: basta abilitarle con un semplice comando SQL nel proprio database per iniziare a utilizzarle immediatamente.
Prerequisiti
Prima di iniziare con pgRouting
, assicurati di soddisfare questi requisiti:
- ServBay installato e in esecuzione: Se non hai ancora ServBay, visita il sito ufficiale di ServBay per scaricare e installare l'ultima versione.
- Pacchetto PostgreSQL installato e avviato in ServBay: Nell'interfaccia di ServBay, verifica che il pacchetto PostgreSQL sia installato e attivo.
- Familiarità con SQL e operazioni di base su PostgreSQL: La guida presume che tu abbia conoscenze di base sull'utilizzo di database PostgreSQL e SQL.
- Conoscenza di base di PostGIS:
pgRouting
si appoggia aPostGIS
per la gestione dei tipi di dati e funzioni geospaziali. Assicurati che l'estensionePostGIS
sia abilitata nel tuo database; il pacchetto PostgreSQL fornito con ServBay solitamente la include di default.
Installazione e abilitazione dell'estensione pgRouting
ServBay mette già a disposizione i file necessari per pgRouting
: bisogna solo abilitare l'estensione nel database interessato.
Connettersi al database PostgreSQL:
Puoi collegarti a PostgreSQL tramite diversi strumenti: da riga di comando con
psql
, con strumenti grafici (come pgAdmin, DBeaver), oppure tramite le librerie cliente dei linguaggi di programmazione.Il metodo più diretto è l'uso della CLI
psql
fornita da ServBay. Puoi avviare una finestra terminale già configurata tramite il pulsante “Terminale” in ServBay, oppure aggiungere manualmente la cartella bin di ServBay alla tua variabile PATH.Da terminale, usa questo comando per connetterti al database di destinazione (ad esempio
servbay_geo_db
con utente predefinitoservbay
):bashpsql -U servbay -d servbay_geo_db
1Modifica il comando in base al nome del database, utente o password utilizzati.
Controllare e abilitare PostGIS (se non già presente):
pgRouting
richiedePostGIS
attivo. Dal prompt dipsql
:sqlCREATE EXTENSION IF NOT EXISTS postgis;
1Questo comando crea (o conferma l’esistenza di)
PostGIS
nel database.Abilitare l'estensione pgRouting:
Nella stessa sessione, esegui il comando SQL per creare l'estensione
pgRouting
:sqlCREATE EXTENSION pgrouting;
1Se va a buon fine, riceverai un messaggio tipo
CREATE EXTENSION
.Verificare l'installazione:
Elenca le estensioni installate per confermare l’attivazione di
pgRouting
:sql\dx
1Dovresti vedere sia
postgis
siapgrouting
nella lista.
Configurazione di pgRouting: preparare i dati della rete e creare la topologia
Gli algoritmi di pgRouting
lavorano su una tabella che rappresenta la struttura della rete (ad esempio la rete stradale). Di solito, questa tabella contiene segmenti (tratti) con identificativi di nodo iniziale e finale e un "peso" (ad esempio distanza o tempo). Inoltre, per calcoli efficienti è necessario creare una "topologia", ovvero la definizione delle connessioni tra i vari tratti tramite i nodi.
Creazione della tabella dei dati di rete
Segue un esempio di come creare la tabella ways
che archivia i dati dei tratti stradali, con le colonne necessarie:
-- Crea una tabella per i segmenti della rete stradale
CREATE TABLE ways (
id SERIAL PRIMARY KEY, -- Identificativo unico del segmento
source INTEGER, -- ID del nodo di partenza
target INTEGER, -- ID del nodo di arrivo
cost DOUBLE PRECISION, -- Costo di percorrenza (es. distanza, tempo) in un verso
reverse_cost DOUBLE PRECISION, -- Costo opposto (per senso contrario)
geom GEOMETRY(LineString, 4326) -- Geometria del tratto, tipo LineString con SRID 4326 (WGS 84)
);
2
3
4
5
6
7
8
9
Spiegazione:
SERIAL PRIMARY KEY
: assegna identificativi unici e incrementali ai segmenti.source
,target
: identificano i nodi di inizio e fine del segmento, creati/riempiti durante la generazione della topologia.cost
,reverse_cost
: definiscono il peso di attraversamento. Per sensi unici, ad esempio, si può impostarereverse_cost
aNULL
o un valore molto alto.geom
: archivia la geometria del segmento tramite il tipoGEOMETRY
di PostGIS;LineString
indica una linea,4326
è il codice SRID più utilizzato per coordinate geografiche (WGS 84).
Inserimento dei dati di esempio
Aggiungi alcuni tratti di esempio nella tabella ways
:
-- Inserisci segmenti di esempio nella tabella ways
INSERT INTO ways (source, target, cost, reverse_cost, geom) VALUES
(1, 2, 1.0, 1.0, ST_SetSRID(ST_MakeLine(ST_MakePoint(116.4074, 39.9042), ST_MakePoint(116.4084, 39.9052)), 4326)),
(2, 3, 1.0, 1.0, ST_SetSRID(ST_MakeLine(ST_MakePoint(116.4084, 39.9052), ST_MakePoint(116.4094, 39.9062)), 4326)),
(3, 4, 1.0, 1.0, ST_SetSRID(ST_MakeLine(ST_MakePoint(116.4094, 39.9062), ST_MakePoint(116.4104, 39.9072)), 4326));
2
3
4
5
Spiegazione:
ST_MakePoint(x, y)
: crea un punto PostGIS dati latitudine e longitudine.ST_MakeLine(point1, point2)
: crea una linea tra due punti.ST_SetSRID(geometry, srid)
: assegna il riferimento spaziale (sistema di coordinate).- I dati di esempio rappresentano tre tratti connessi, tutti di costo 1.0, con coordinate di un’area esemplificativa di Pechino.
Creazione della topologia
Dopo aver preparato la tabella, usa la funzione pgr_createTopology
per generare la topologia:
-- Crea la topologia sui dati ways
-- Parametri:
-- 'ways': nome tabella
-- 0.00001: tolleranza (tolerance) per considerare due punti come lo stesso nodo
-- 'geom': nome colonna della geometria
-- 'id': nome colonna identificatore segmento
SELECT pgr_createTopology('ways', 0.00001, 'geom', 'id');
2
3
4
5
6
7
Spiegazione:
pgr_createTopology
: funzione centrale di pgRouting per identificare nodi (connessioni) e segmenti.- Il valore di tolleranza è fondamentale: regola la distanza max per cui due punti sono considerati lo stesso incrocio/nodo.
Dopo l’esecuzione, le colonne source
e target
saranno popolate, e sarà creata la tabella ways_vertices_pgr
con tutti i nodi rilevati.
Analisi di routing con pgRouting
Dopo la creazione della topologia, puoi usare i diversi algoritmi di pgRouting
per le analisi di routing. Ecco alcuni esempi comuni.
Analisi del percorso più breve (Dijkstra)
Trovare il percorso più breve tra due nodi è una delle richieste più frequenti nelle analisi di routing. pgRouting
implementa l'algoritmo di Dijkstra come segue:
-- Ricerca del percorso più breve dal nodo 1 al nodo 4
-- Parametri:
-- 'SELECT id, source, target, cost FROM ways': query graph base
-- 1: nodo di partenza
-- 4: nodo di arrivo
-- directed := true: specifica se il grafo è diretto (diverso cost/reverse_cost)
SELECT seq, id1 AS node, id2 AS edge, cost, geom
FROM pgr_dijkstra(
'SELECT id, source, target, cost FROM ways',
1, -- ID nodo iniziale
4, -- ID nodo finale
directed := true -- Se vuoi considerare i costi inversi, usa false o ometti
)
JOIN ways ON edge = ways.id; -- Unisce ai dati originali per usare la geometria
2
3
4
5
6
7
8
9
10
11
12
13
14
Spiegazione:
pgr_dijkstra
: applica l’algoritmo di percorso più breve.- Il primo parametro è una query che restituisce almeno
id
,source
,target
,cost
(ereverse_cost
se necessario). - JOIN con la tabella ways per ottenere la geometria utile alla visualizzazione.
Problema del commesso viaggiatore (Traveling Salesperson Problem - TSP)
TSP trova il circuito di costo minimo che visiti una serie di nodi specificati.
-- Risoluzione del problema TSP per i nodi 1, 2, 3, 4, partendo dal nodo 1
-- Parametri:
-- 'SELECT id, x::float8 AS x, y::float8 AS y FROM ways_vertices_pgr': nodi da visitare
-- start_id := 1: nodo di inizio
SELECT seq, node, edge, cost
FROM pgr_tsp(
'SELECT id, ST_X(the_geom)::float8 AS x, ST_Y(the_geom)::float8 AS y FROM ways_vertices_pgr WHERE id IN (1, 2, 3, 4)', -- Nodi e coordinate
start_id := 1 -- Nodo di partenza
);
2
3
4
5
6
7
8
9
Spiegazione:
pgr_tsp
: risolve il TSP sui nodi selezionati.- Il primo parametro dev’essere una query che restituisce per ogni nodo almeno
id
,x
,y
.
Analisi dell’area di servizio (Driving Distance / Driving Time)
L’analisi delle aree di servizio trova tutte le aree raggiungibili da uno o più punti dato un costo massimo (es. tempo, chilometri).
-- Ricerca di tutte le tratte raggiungibili dal nodo 1 entro un costo massimo di 2
-- Parametri:
-- 'SELECT id, source, target, cost FROM ways': query per il grafo
-- 1: nodo iniziale
-- 2: costo massimo consentito
-- directed := true: indica se il grafo è diretto
SELECT seq, id1 AS node, id2 AS edge, cost, geom
FROM pgr_drivingDistance(
'SELECT id, source, target, cost FROM ways',
1, -- ID nodo iniziale
2, -- Costo massimo
directed := true
)
JOIN ways ON edge = ways.id; -- Unisce ai dati originali per la geometria
2
3
4
5
6
7
8
9
10
11
12
13
14
Spiegazione:
pgr_drivingDistance
: trova i segmenti raggiungibili entro il limite di costo stabilito.- Permette la visualizzazione delle aree di servizio in GIS/web.
Visualizzazione dei risultati di routing
Visualizzare i risultati di pgRouting
aiuta a comprendere e presentare efficacemente le analisi. Puoi scegliere tra strumenti GIS desktop o librerie cartografiche per il web.
Con strumenti GIS desktop (es. QGIS)
QGIS è una soluzione open-source potente e gratuita che si connette direttamente a database PostgreSQL/PostGIS.
- Avvia QGIS.
- Vai su Layer > Data Source Manager.
- Seleziona PostGIS nella barra laterale.
- Clicca su Nuovo (New) per creare una nuova connessione.
- Inserisci le informazioni di ServBay PostgreSQL (ad esempio: Host:
localhost
, Porta:5432
, Database:servbay_geo_db
, Utente:servbay
, Password: quella del tuo database). Puoi premere “Test Connect” per verificare la connessione. - Se la connessione è attiva, espandi il database e seleziona una delle tabelle, ad esempio
ways
oways_vertices_pgr
. - Seleziona la tabella/vista desiderata (ad es. una vista query di risultanze di percorso più breve) e clicca su Aggiungi (Add) per visualizzarla su QGIS.
Visualizzazione in web app (Leaflet o OpenLayers)
Nei progetti web, un backend (PHP, Node.js, Python in esecuzione su ServBay) esegue le query di pgRouting
e restituisce i risultati in formato (di solito) GeoJSON. Il frontend, tramite librerie Javascript come Leaflet o OpenLayers, mostra i dati sulla mappa.
Ecco una struttura HTML esemplificativa che mostra una polilinea statica in Leaflet. Per risultati dinamici occorrerà:
- Eseguire la query
pgRouting
dal backend. - Convertire la geometria risultante in GeoJSON o formato supportato dalla libreria.
- Offrire il GeoJSON tramite API verso il frontend.
- Caricare e mostrare il GeoJSON in JavaScript con Leaflet.
<!DOCTYPE html>
<html>
<head>
<title>Esempio di visualizzazione Web di pgRouting su ServBay</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<style>
#map { height: 600px; width: 100%; } /* Dimensioni del contenitore mappa */
</style>
</head>
<body>
<h1>Visualizzazione dei risultati pgRouting su ServBay</h1>
<div id="map"></div>
<script>
// Inizializza la mappa al centro dell'area di esempio
var map = L.map('map').setView([39.906, 116.409], 14); // Coordinate d'esempio
// Aggiungi la base OpenStreetMap
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// Esempio: aggiungi dati GeoJSON statici derivati da pgRouting (in un'app reale, via AJAX)
var geojsonData = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"id": 1,
"cost": 1.0
},
"geometry": {
"type": "LineString",
"coordinates": [
[116.4074, 39.9042],
[116.4084, 39.9052]
]
}
},
{
"type": "Feature",
"properties": {
"id": 2,
"cost": 1.0
},
"geometry": {
"type": "LineString",
"coordinates": [
[116.4084, 39.9052],
[116.4094, 39.9062]
]
}
},
{
"type": "Feature",
"properties": {
"id": 3,
"cost": 1.0
},
"geometry": {
"type": "LineString",
"coordinates": [
[116.4094, 39.9062],
[116.4104, 39.9072]
]
}
}
]
};
// Usa L.geoJSON per aggiungere i risultati sulla mappa
L.geoJSON(geojsonData, {
style: function (feature) {
return {color: "#ff0000", weight: 4}; // Rosso e spesso
}
}).addTo(map);
// Zoom automatico per includere tutte le features
if (L.geoJSON(geojsonData).getBounds().isValid()) {
map.fitBounds(L.geoJSON(geojsonData).getBounds());
}
</script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
Salva questo file HTML nella root del sito su ServBay (ad es. /Applications/ServBay/www/pgrouting-demo/index.html
) e aprilo tramite ServBay (ad es. http://pgrouting-demo.servbay.demo
) per vedere la mappa con la rotta di esempio. Ricorda che questo è solo un esempio statico dimostrativo; per risultati live occorre integrare i dati in arrivo dal backend.
Avvertenze
- Qualità dei dati: I risultati di
pgRouting
sono strettamente legati alla qualità della rete stradale in input. Assicurati che i dati siano accurati, completi e topologicamente corretti. - Prestazioni: Su reti di grandi dimensioni le analisi possono essere lente. Usa indici, semplifica la rete o valuta algoritmi più efficienti in base al caso d’uso.
- Risorse di memoria: Strutture topologiche grandi possono richiedere molta RAM; verifica che il server database abbia risorse adeguate.
FAQ - Domande frequenti
D: Ottengo un errore “estensione non esistente” con CREATE EXTENSION pgrouting;
. Che fare? R: Verifica che il pacchetto PostgreSQL di ServBay sia installato e attivo, che la versione del database supporti pgRouting
e che ServBay includa davvero l'estensione (di solito, sì). Se il problema persiste, consulta i log di ServBay o PostgreSQL per dettagli. Usa un utente con permessi adeguati (es. l’utente servbay
).
D: Come scelgo il valore giusto di tolleranza per pgr_createTopology
? R: Dipende dalla precisione dei dati geospaziali. La tolleranza definisce la distanza sotto la quale due vertici sono considerati lo stesso nodo. Con coordinate GPS molto precise, puoi usare valori piccoli (es. 0.000001). Con dati eterogenei o meno precisi, aumenta la tolleranza. Se troppo alta, puoi collegare in modo errato segmenti che non dovrebbero esserlo.
D: Come gestisco sensi unici o divieti di inversione di marcia? R: La logica è nei campi cost
e reverse_cost
della tabella ways: per un senso unico imposta reverse_cost
a NULL
o a un valore altissimo. Per divieti di inversione o regole più complesse, serve un modello di rete più raffinato o post-elaborare i risultati di routing; pgRouting offre funzioni avanzate per gestire regole speciali.
Conclusioni
ServBay rende estremamente semplice configurare in locale un database PostgreSQL con supporto a pgRouting
. Bastano pochi comandi SQL per abilitare l'estensione e caricare la rete, e sei già pronto per sfruttare tutta la potenza degli algoritmi di routing geospaziale. Se abbini strumenti GIS desktop o librerie di mappatura web, puoi visualizzare facilmente i risultati e rafforzare le tue applicazioni con dati geospaziali avanzati. ServBay elimina la complessità della configurazione tecnica, permettendo agli sviluppatori di concentrarsi sulla logica e sulle funzionalità della propria applicazione.