Algoritmo per compensare una latitudine / longitudine di una certa quantità di metri


108

Sto cercando un algoritmo che quando mi viene data una coppia di latitudine e longitudine e una traduzione vettoriale in metri in coordinate cartesiane (x, y) mi darebbe una nuova coordinata. Una specie di Haversine al contrario. Potrei anche lavorare con una distanza e una trasformazione di rotta, ma questo probabilmente sarebbe più lento e non altrettanto accurato. Idealmente, l'algoritmo dovrebbe essere veloce mentre sto lavorando su un sistema incorporato. La precisione non è critica, entro 10 metri sarebbe buona.


Quindi staresti bene modellando la terra come una sfera?
underdark

1
Sì, andrebbe bene dato che mi aspetto offset <1km.
Thomas O,

Risposte:


107

Se i tuoi spostamenti non sono troppo grandi (meno di qualche chilometro) e non sei proprio ai poli, usa la stima rapida e sporca che 111.111 metri (111.111 km) nella direzione y è 1 grado (di latitudine) e 111.111 * cos (latitudine) metri nella direzione x è 1 grado (di longitudine).


3
@Thomas: In realtà, puoi essere molto vicino ai poli. Ho verificato un calcolo UTM usando gli spostamenti x e y uguali di 1400 m (quindi lo spostamento totale è di 2 km). I risultati sono buoni a 8,6 metri o meglio. La latitudine peggiore (per questa direzione e quantità di spostamento) è di 81 gradi: l'approssimazione in realtà diventa più accurata man mano che ci si sposta verso nord e il suo errore rimane al di sotto di 10 metri fino a quando non si superano gli 89,6 gradi!
whuber

60
Per inciso, questi numeri magici di 111.111 sono facili da ricordare conoscendo un po 'di storia: i francesi originariamente definivano il metro in modo che 10 ^ 7 metri fosse la distanza lungo il meridiano di Parigi dall'equatore al polo nord. Pertanto, 10 ^ 7/90 = 111.111,1 metri equivalgono a un grado di latitudine rispetto alle capacità dei geometri francesi due secoli fa.
whuber

3
Quindi, con la formula se volessi spostare + 100m nella direzione y da dire 10.0 N, 10.0 E, aggiungerei solo 100/111111? Se si sposta nella direzione x + 100m, sarebbe 100 ÷ (111.111 × (cos 10))? Mi sto solo assicurando di aver capito bene.
Thomas O

5
@Thomas Sì, esatto. Nota come la seconda formula espande lo spostamento x apparente (in virtù della divisione per un numero inferiore a 1) come dovrebbe, perché un grado di longitudine si riduce man mano che ti sposti verso i poli dall'equatore. L'unico potenziale problema è assicurarsi che tu e la tua piattaforma software siate d'accordo su cosa significhi "cos": dovrebbe interpretare meglio cos (10) come il coseno di 10 gradi , non di 10 radianti! (In caso contrario, 10 gradi = 10 * pi / 180 radianti illustra la semplice conversione.) A questo punto, il codice offerto da @haakon_d dovrebbe avere perfettamente senso per te.
whuber

7
Qualcuno ha tentato di modificare questa risposta per sostituire "metri" con "km". Probabilmente stavano leggendo la virgola "," nel senso europeo di un punto decimale. Seguo la convenzione americana (che ritengo sia anche la convenzione delle pubblicazioni internazionali) di usare una virgola per separare le stringhe di cifre lunghe in gruppi di tre e un punto decimale "." invece della virgola. (Questo uso è chiaramente mostrato nei commenti precedenti.) Per evitare qualsiasi ambiguità ho modificato la risposta per mostrare chiaramente cosa significano la virgola e il punto.
whuber

56

Come dice Liedman nella sua risposta, le formule di aviazione di Williams sono una fonte inestimabile e per mantenere la precisione entro 10 metri per spostamenti fino a 1 km, probabilmente dovrai usare il più complesso di questi.

Ma se sei disposto ad accettare errori superiori a 10 m per punti con offset superiore a circa 200 m, puoi utilizzare un calcolo semplificato della terra piatta. Penso che gli errori saranno ancora inferiori a 50 m per offset fino a 1 km.

 //Position, decimal degrees
 lat = 51.0
 lon = 0.0

 //Earth’s radius, sphere
 R=6378137

 //offsets in meters
 dn = 100
 de = 100

 //Coordinate offsets in radians
 dLat = dn/R
 dLon = de/(R*Cos(Pi*lat/180))

 //OffsetPosition, decimal degrees
 latO = lat + dLat * 180/Pi
 lonO = lon + dLon * 180/Pi 

Questo dovrebbe restituire:

 latO = 51,00089832
 lonO = 0,001427437

7
Voglio solo sottolineare che questo è identico alla risposta che ho fornito, tranne per il fatto che tu abbia sostituito il mio valore di 111.111 metri per grado con 111.319,5. Il tuo valore è leggermente migliore alle alte latitudini ma leggermente peggiore alle latitudini più basse (da 0 a circa 40 gradi). Entrambi i valori soddisfano i requisiti di precisione dichiarati.
whuber

1
+1 per fornire il codice. Si noti che è più preciso di quanto si sospetti (l'errore è in genere inferiore a 5 m su 2000 m).
whuber

1
Mi chiedevo se avrei dovuto aggiungere un'osservazione nella mia risposta che questa è una soluzione identica alla tua tranne per il valore di R, ma l'ho lasciata fuori per brevità. Quando si tratta di precisione, hai ragione se non aggiungi errori di rotazione al sistema. Usando gli offset misurati in un sistema di coordinate proiettato locale, gli errori di rotazione possono aumentare abbastanza.
haakon_d,

1
Questo è un punto eccellente: abbiamo implicitamente supposto che lo spostamento x sia almeno vicino al vero est-ovest e lo spostamento y sia vicino a nord-sud. In caso contrario, devono essere convertiti in equivalenti spostamenti EW e NS (non solo "est" e "nord") prima di calcolare i loro equivalenti lat-lon.
whuber

Il parametro d distance delle equazioni del Formulario aeronautico è in radianti, ad es. (Distanza / raggio di terra).
user1089933

23

Trovo che Aviation Formulary, qui è ottimo per questi tipi di formule e algoritmi. Per il tuo problema, controlla "lat / long data radial and distance": qui

Si noti che questo algoritmo potrebbe essere un po 'troppo complesso per l'uso, se si desidera mantenere basse le funzioni di trigonometria, ecc.


Grazie per questo - sembra l'ideale. Anche se non riesco a capire se la distanza è in metri o qualche altra misura.
Thomas O

2

Potrebbe avere senso proiettare prima il punto. Potresti creare qualcosa di simile a questo pseudo-codice:

falt_coordinate = latlon_to_utm(original_koordinate)
new_flat_coordinate = flat_coordinate + (x,y)
result_coordinate = utm_to_latlon(new_flat_coordinate)

dove (x, y) è l'offset desiderato.

Non hai bisogno di usare utm, qualsiasi sistema di coordinate piatto, che abbia senso nella tua area, lo farà.

Con quale software stai lavorando?


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.