Calcolo dinamico della distanza tra due punti geografici in SQL Server con Stored Procedure
Introduzione
Nel mondo moderno, le applicazioni che utilizzano dati geografici sono sempre più comuni: servizi di food delivery, app di navigazione, logistica, e-commerce con selezione dei punti di ritiro, e molte altre. Un elemento fondamentale è il calcolo preciso della distanza tra due punti sulla superficie terrestre. SQL Server fornisce strumenti nativi per gestire dati geospaziali tramite i tipi di dato GEOGRAPHY
e GEOMETRY
, rendendo possibile eseguire operazioni complesse direttamente nel database.
In questo articolo approfondiremo il calcolo della distanza tra due coordinate geografiche usando il tipo GEOGRAPHY
e la funzione STDistance()
, implementando una stored procedure dinamica e spiegando ogni passaggio nel dettaglio. Inoltre, vedremo come integrare queste soluzioni in contesti reali, come ottimizzarle per prestazioni elevate e cosa tenere in considerazione quando si lavora con dati geospaziali.
Tipi di dati spaziali in SQL Server
SQL Server offre due tipi principali per rappresentare dati spaziali:
GEOGRAPHY: Modella la superficie terrestre come una sfera, tenendo conto della curvatura terrestre. È perfetto per coordinate GPS (latitudine e longitudine).
GEOMETRY: Usa un sistema cartesiano plano, adatto a mappe tecniche, disegni architettonici, e scenari locali dove la curvatura terrestre è trascurabile.
Nel nostro scenario, dove trattiamo distanze geografiche reali tra punti su scala cittadina, regionale o nazionale, è obbligatorio usare GEOGRAPHY
per ottenere risultati corretti.
SRID e coordinate geografiche
L'SRID (Spatial Reference Identifier) più comunemente utilizzato è il 4326, che fa riferimento al sistema di coordinate WGS 84 (utilizzato dai GPS di tutto il mondo). Ogni punto GEOGRAPHY
in SQL Server deve specificare l'SRID corretto per assicurare accuratezza nei calcoli.
Rappresentare un punto geografico
Per creare un punto geografico in SQL Server, si usa la funzione:
GEOGRAPHY::Point(latitudine, longitudine, SRID)
Esempio:
DECLARE @p GEOGRAPHY = GEOGRAPHY::Point(38.1157, 13.3615, 4326); -- Palermo
Questo crea un punto geospaziale nel formato corretto. Si noti che la latitudine viene indicata per prima, seguita dalla longitudine. L'inversione di questi parametri è un errore comune che può portare a risultati errati.
Calcolare la distanza tra due punti
Una volta creati due oggetti GEOGRAPHY
, è possibile calcolare la distanza con il metodo STDistance
, che restituisce il risultato in metri.
DECLARE @p1 GEOGRAPHY = GEOGRAPHY::Point(38.1157, 13.3615, 4326);
DECLARE @p2 GEOGRAPHY = GEOGRAPHY::Point(37.5079, 15.0830, 4326);
SELECT @p1.STDistance(@p2) AS DistanzaInMetri;
Il metodo STDistance
utilizza algoritmi interni per calcolare la distanza sulla superficie di un ellissoide terrestre. Il risultato è molto più accurato rispetto alle formule trigonometriche classiche.
Questa query restituirà circa 166000 metri (ovvero 166 km), che rappresenta la distanza tra Palermo e Catania.
Creazione di una stored procedure
Per riutilizzare il calcolo all'interno di applicazioni o query automatizzate, possiamo creare una stored procedure parametrica.
Codice completo
CREATE PROCEDURE CalcolaDistanzaTraDuePunti
@Lat1 FLOAT,
@Lon1 FLOAT,
@Lat2 FLOAT,
@Lon2 FLOAT
AS
BEGIN
DECLARE @Punto1 GEOGRAPHY = GEOGRAPHY::Point(@Lat1, @Lon1, 4326);
DECLARE @Punto2 GEOGRAPHY = GEOGRAPHY::Point(@Lat2, @Lon2, 4326);
SELECT
@Punto1.STDistance(@Punto2) AS DistanzaInMetri,
ROUND(@Punto1.STDistance(@Punto2) / 1000.0, 2) AS DistanzaInKm;
END;
Esecuzione
EXEC CalcolaDistanzaTraDuePunti
@Lat1 = 38.1157, @Lon1 = 13.3615,
@Lat2 = 37.5079, @Lon2 = 15.0830;
Espansione della procedura
La procedura può essere estesa per includere anche:
Nome dei punti come parametri
Salvataggio in una tabella di log
Calcolo di tempo di percorrenza stimato (con velocità media)
Uso pratico con una tabella
Supponiamo di avere una tabella con le posizioni dei negozi.
CREATE TABLE Negozi (
Id INT PRIMARY KEY,
Nome NVARCHAR(100),
Posizione GEOGRAPHY
);
INSERT INTO Negozi (Id, Nome, Posizione)
VALUES (1, 'Negozio A', GEOGRAPHY::Point(38.12, 13.36, 4326));
Per trovare i negozi entro 10 km da una posizione:
DECLARE @PosUtente GEOGRAPHY = GEOGRAPHY::Point(38.1157, 13.3615, 4326);
SELECT Nome,
Posizione.STDistance(@PosUtente) AS DistanzaMetri
FROM Negozi
WHERE Posizione.STDistance(@PosUtente) < 10000
ORDER BY DistanzaMetri;
Ottimizzazione con Spatial Index
Le query spaziali possono diventare lente su grandi volumi di dati. Per questo, è buona pratica creare un indice spaziale:
CREATE SPATIAL INDEX IX_Negozi_Posizione
ON Negozi(Posizione)
USING GEOGRAPHY_AUTO_GRID;
Con questo indice, SQL Server utilizza strutture ottimizzate per velocizzare i confronti geospaziali.
Integrazione con applicazioni moderne
I risultati delle query geografiche possono essere esportati in formato GeoJSON, integrati in API REST o visualizzati in mappe interattive tramite Leaflet, Mapbox o Google Maps. Questo consente di costruire interfacce utente moderne che rispondono dinamicamente alla posizione dell'utente.
Esempio di serializzazione in GeoJSON:
SELECT 'Feature' AS type,
JSON_QUERY(
CONCAT(
'{"type":"Point","coordinates":[',
CAST(Posizione.Long AS VARCHAR), ',',
CAST(Posizione.Lat AS VARCHAR),
']}'
)
) AS geometry
FROM Negozi
Ulteriori considerazioni
Precisione: Il tipo
GEOGRAPHY
considera la curvatura terrestre, offrendo maggiore precisione rispetto a soluzioni "manuali" basate su formule come Haversine.Compatibilità: Puoi integrare questa logica in API RESTful o frontend, ad esempio mostrando i risultati su una mappa interattiva (Leaflet, Mapbox, Google Maps).
Estensioni: Puoi estendere la stored procedure per accettare più punti, usare
TVP
(Table-Valued Parameters) per batch di calcoli, o aggiungere logica per calcolare anche il tempo stimato in base alla distanza.
Esempi di casi d'uso reali
L'utilizzo delle funzionalità geospaziali in SQL Server trova applicazione in molti scenari reali. Di seguito alcuni esempi concreti:
1. Logistica e trasporti
Aziende di logistica possono calcolare le distanze tra magazzini, centri di distribuzione e destinazioni finali per ottimizzare le rotte di consegna. Le stored procedure geografiche possono essere utilizzate per pianificare percorsi efficienti, calcolare costi stimati e ridurre i tempi di viaggio.
2. Servizi di emergenza
Centrali operative di pronto intervento (ambulanza, vigili del fuoco, polizia) possono localizzare in tempo reale il punto di emergenza e trovare la stazione di partenza più vicina. Un sistema con stored procedure geospaziali può restituire rapidamente i tre punti di soccorso più vicini con stima delle distanze e dei tempi di arrivo.
3. Applicazioni mobili e geolocalizzazione
App come Uber, Deliveroo o Google Maps si basano su distanze dinamiche calcolate in tempo reale tra utenti, veicoli e punti di interesse. SQL Server con GEOGRAPHY
può essere il backend di un sistema che mostra solo gli esercizi commerciali o i driver a meno di X km dall’utente.
4. Retail e marketing geolocalizzato
I grandi brand possono sfruttare le distanze geografiche per inviare promozioni mirate agli utenti che si trovano vicino ai punti vendita. Le query spaziali possono essere integrate con CRM e piattaforme di marketing automation per campagne personalizzate.
5. Analisi ambientale e pianificazione urbana
Organizzazioni pubbliche possono valutare l’impatto di nuove infrastrutture calcolando la distanza da aree protette, corsi d’acqua o zone residenziali. La pianificazione urbana può essere supportata da query spaziali per identificare aree raggiungibili entro una certa distanza da servizi essenziali (ospedali, scuole, ecc.).
Conclusione
Il calcolo della distanza tra punti geografici è una funzionalità fondamentale per molte applicazioni moderne. SQL Server, grazie al supporto nativo per il tipo GEOGRAPHY
, permette di implementarla in modo semplice, preciso e performante. Creare una stored procedure dedicata consente di riutilizzare questa logica in diversi contesti e semplificare l'integrazione con altri sistemi.
Integrare queste soluzioni nel tuo database può migliorare notevolmente l'efficienza delle analisi geospaziali e fornire funzionalità avanzate agli utenti finali.