Calcolo della distanza tra due punti geografici

Tutti i sistemi GPS sono in grado di calcolare la distanza che intendiamo percorrere. Lo stesso Google Earth fa lo stesso, una volta indicati i due punti sulla superficie del globo.

Ma non è che a furia di avere la pappa già pronta, finiamo per dipendere troppo dagli altri?

Questa domanda mi sono posto qualche giorno fa, quando mi è nata l’esigenza di calcolare la distanza tra due punti geografici, di cui conoscevo le coordinate. All’inizio ho pensato che probabilmente c’era già qualche API da qualche parte che facesse questo tipo di elaborazione; poi mi sono fermato e mi sono detto: perché non me lo realizzo da solo?

A scuola ho studiato Trigonometria sferica, ed avevo letto anche qualcosa sulle geodetiche, che senza entrare troppo nello specifico, altro non sono che la traiettoria più breve fra punti di un particolare spazio. Dopo aver dato una rispolverata alle varie formule matematiche di cui avevo bisogno, ho iniziato la fase di analisi vera e propria; e qui voglio illustrarla, per poi far seguire il codice in PHP.

Ci sono due premesse da fare. La prima è che in realtà la Terra non è sferica (è simile ad uno sferoide oblado) ma per semplicità di calcolo ho assunto che lo fosse, anche perché l’errore generato è molto trascurabile (per i miei utilizzi). La seconda è che il raggio della Terra cambia a seconda da dove viene misurato, per cui per semplicità ho adottato il raggio quadratico medio, che è pari a 6372,795477598 chilometri.

Dopo aver disegnato una sfera e due punti su di essa e tutte le linee ed aver individuato i punti, ho iniziato a buttare giù qualche formula per capire di che dati avevo bisogno ed in che formato.

disgeo

Sicuramente avevo bisogno della latitudine e longitudine sia del punto A che del punto B. Ma in che formato?

I punti io li ho in gradi, mentre la formula li necessita in radianti. La conversione viene fatta moltiplicando la coordinata per π e poi dividendo il risultato per 180.

Da questo punto in poi le coordinate sono sempre utilizzate in radianti.

Inoltre non avevo l’angolo φ. Esso è uguale al valore assoluto della differenza tra la longitudine A e la latitudine B.

Ora manca solo l’angolo P che è uguale all’arcocoseno del prodotto del seno della latitudine A con il seno della latitudine B, più il prodotto del coseno della latitudine A col coseno della latitudine B col coseno di φ.

Una volta fatto questo, per calcolare la distanza mi basta moltiplicare il valore del punto P per il raggio quadratico medio terrestre (ovviamente, se il raggio quadratico medio terrestre è espresso in chilometri, il risultato sarà in chilometri).

Volendo schematizzare il tutto possiamo avere qualcosa del tipo:

R = 6372.795477598
π = 3.1415927

radLatA = π * decLatA / 180
radLonA = π * delLonA / 180
radLatB = π * decLatB / 180
radLonB = π * delLonB / 180

φ = abs(radLonA - radLonB)

P = acos{[sin(radLatA) * sin(radLatB)] + [cos(radLatA) * cos(radLatB) * cos(φ)]}

distanza = P * R

Trasformare tutto in una funzione PHP è molto semplice arrivati a questo punto, anche grazie alla funzioni implementate all’interno del codice stesso; e mi riferisco a quelle matematiche.

Una funzione ipotetica che riceve come parametri le coppie di coordinate latitudine e longitudine (separate da virgola) dei due punti terrestri potrebbe essere la seguente:

A questo punto una semplice richiesta va evocata nel seguente modo:

In questo caso ho provato a calcolare la distanza tra il Colosseo e la Torre Eiffel. Il risultato della funzione, 1.109,74 Km si discosta di soli 0,22 Km rispetto alla distanza calcolata da Google Earth; un valore accettabile considerando le limitazioni elencate all’inizio di questo articolo.

  1. Federico
    1 novembre 2008 alle 23:45

    Molto interessante.
    Ho un problema analogo da risolvere: dati tre punti definiti da Latitudine e Longitudine come fare per verificare se una data posizione risiede dentro il triangolo descritto dai tre punti?

  2. Gianluca Altieri
    19 gennaio 2009 alle 14:27

    Grazie mille è proprio quello che cercavo!

  3. Vittoria
    20 gennaio 2009 alle 14:28

    Ciao !ho letto appena ora il tuo intervento!io domani ho un esame di geografia umana da non frequentante però !vorrei sapere siccome non m sn esercitata molto su qstcalcoli come CALCOLARE LA LATITUDINE di un punto P INTERMEDIO TRA DUE PARALLELI! E CALCOLO DELLA QUOTA DI UN PUNTO P INTERMEDIO TRA DUE ISOIPSE IN UNA CARTA CON EQUIDISTANZA 25 m E SCALA 1:25.000 !!!!
    ho una pauraaaaaaaaaaaaaaaaaaaa! l’altro ho studiato tutto ma nnsn eccellente in qst conti ke immagino chiederà il prof!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    c tengo !
    rispppppppppp prima possibile…!ENTRO OGGII!
    GRAZIEEEEEEEEEEEEEEEEEEEEEE

  4. 20 gennaio 2009 alle 15:11

    @Vittoria
    Mi dispiace, ma ne so meno di te … Non sono un topologo :(

  5. nico
    9 settembre 2009 alle 03:55

    Salve, ho una curiosita’….quant’e’ la distanza tra lecce e kabul…Spero di avere una vostra risposta… grazie

  6. 9 settembre 2009 alle 09:19

    Beh, forse hai sbagliato sito o hai frainteso l’articolo.

    Io qui insegno a calcolare le distanze utilizzando le coordinate geografiche; ma non mi offro come calcolatore di distanze.
    ;)

  7. Andrea
    11 febbraio 2010 alle 14:52

    Ciao, ho letto con attenzione l’articolo, non essendo esperto di matematica è stata una manna dal cielo… però vorrei farti notare che nella spiegazione dici: “Inoltre non avevo l’angolo φ. Esso è uguale al valore assoluto della differenza tra la longitudine A e la latitudine B.” mentre nel codice sottrai le due longitudini.
    Inoltre ho provato questa funzione su una serie di coordinate che ho nel database e mi calcola una distanza di 14,80 (circa) su una distanza reale di 15km circa, mentre mi da una distanza di 16,80 (circa) su una distanza reale di circa 40km… ci lavorerò un po’ su…

  8. Andrea
    11 febbraio 2010 alle 15:45

    @Andrea

    Il problema della distanza l’ho risolto, avevo invertito latitudine e longitudine, rimane comunque la discrepanza tra l’articolo e il codice scritto nel calcolo di phi.

  9. 2 trackbacks