Algoritma untuk mengimbangi garis lintang / bujur beberapa meter

108

Saya mencari algoritma yang ketika diberi pasangan garis lintang dan bujur dan terjemahan vektor dalam meter dalam koordinat Cartesian (x, y) akan memberi saya koordinat baru. Semacam seperti Haversine terbalik. Saya juga bisa bekerja dengan jarak dan transformasi heading, tetapi ini mungkin akan lebih lambat dan tidak seakurat. Idealnya, algoritme harus cepat karena saya sedang mengerjakan sistem tertanam. Akurasi tidak kritis, dalam jarak 10 meter akan bagus.

Thomas O
sumber
Jadi, Anda akan menjadi model bumi baik-baik saja sebagai bola?
underdark
1
Ya, itu akan baik-baik saja karena saya mengharapkan offset <1 km.
Thomas O

Jawaban:

107

Jika perpindahan Anda tidak terlalu besar (kurang dari beberapa kilometer) dan Anda tidak benar di kutub, gunakan perkiraan cepat dan kotor bahwa 111,111 meter (111,111 km) di arah y adalah 1 derajat (garis lintang) dan 111.111 * cos (garis lintang) meter di arah x adalah 1 derajat (garis bujur).

whuber
sumber
3
@ Thomas: Sebenarnya, Anda bisa sangat dekat dengan kutub. Saya memeriksa perhitungan UTM menggunakan perpindahan x dan y sama dengan 1400 m (sehingga total perpindahan adalah 2 km). Hasilnya bagus hingga 8,6 meter atau lebih baik. Lintang terburuk (untuk arah dan jumlah perpindahan ini) adalah 81 derajat: perkiraannya menjadi lebih akurat saat Anda bergerak ke utara dan kesalahannya tetap di bawah 10 meter sampai Anda melampaui 89,6 derajat!
whuber
60
Secara kebetulan, angka ajaib 111.111 ini mudah diingat dengan mengetahui beberapa sejarah: orang Prancis pada awalnya menentukan meter sehingga 10 ^ 7 meter akan menjadi jarak sepanjang meridian Paris dari khatulistiwa ke kutub utara. Dengan demikian, 10 ^ 7/90 = 111.111,1 meter sama dengan satu derajat garis lintang ke dalam kemampuan surveyor Prancis dua abad yang lalu.
whuber
3
Jadi dengan rumus jika saya ingin memindahkan + 100m ke arah y dari katakanlah 10.0 N, 10.0 E, apakah saya hanya akan menambahkan 100/111111? Jika bergerak ke arah x + 100m, apakah itu 100 ÷ (111,111 × (cos 10))? Hanya memastikan saya sudah benar ini.
Thomas O
5
@ Thomas Ya, benar. Perhatikan bagaimana rumus kedua memperluas perpindahan-x yang nyata (berdasarkan pembagian dengan angka kurang dari 1) sebagaimana mestinya, karena derajat bujur semakin kecil saat Anda bergerak ke arah kutub dari khatulistiwa. Satu-satunya halangan potensial adalah untuk memastikan Anda dan platform perangkat lunak Anda menyetujui apa arti "cos": lebih baik menafsirkan cos (10) sebagai cosinus 10 derajat , bukan 10 radian! (Jika tidak, 10 derajat = 10 * pi / 180 radian menggambarkan konversi sederhana.) Pada titik ini, kode yang ditawarkan oleh @haakon_d akan masuk akal bagi Anda.
whuber
7
Seseorang berusaha mengedit jawaban ini untuk mengganti "meter" dengan "km." Mereka mungkin sedang membaca koma "," dalam arti Eropa titik desimal. Saya mengikuti konvensi Amerika (yang saya percaya adalah konvensi publikasi internasional juga) menggunakan koma untuk memisahkan string digit panjang menjadi kelompok tiga dan titik desimal "." bukannya koma. (Penggunaan ini jelas ditunjukkan dalam komentar sebelumnya.) Untuk menghindari ambiguitas, saya telah mengedit jawaban untuk menunjukkan dengan jelas apa arti koma dan poin.
whuber
56

Seperti yang dikatakan Liedman dalam jawabannya, formula penerbangan Williams adalah sumber yang tak ternilai, dan untuk menjaga akurasi dalam jarak 10 meter untuk perpindahan hingga 1 km Anda mungkin perlu menggunakan yang lebih kompleks dari ini.

Tetapi jika Anda bersedia menerima kesalahan di atas 10m untuk poin mengimbangi lebih dari sekitar 200m Anda dapat menggunakan perhitungan bumi datar disederhanakan. Saya pikir kesalahan masih akan kurang dari 50m untuk offset hingga 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 

Ini akan kembali:

 latO = 51,00089832
 lonO = 0,001427437
haakon_d
sumber
7
Saya hanya ingin menunjukkan bahwa ini identik dengan jawaban yang saya berikan kecuali Anda telah mengganti nilai saya 111.111 meter per derajat dengan 111.319,5. Nilai Anda sedikit lebih baik di lintang tinggi tetapi sedikit lebih buruk di lintang rendah (dari 0 hingga sekitar 40 derajat). Nilai mana pun memenuhi persyaratan akurasi yang dinyatakan.
whuber
1
+1 untuk memberikan kode. Perhatikan bahwa ini lebih akurat daripada yang Anda duga (kesalahan biasanya kurang dari 5 m lebih dari 2000 m).
whuber
1
Saya bertanya-tanya apakah saya harus menambahkan komentar dalam jawaban saya bahwa ini adalah solusi yang identik untuk Anda kecuali untuk nilai R, tetapi meninggalkannya karena singkatnya. Ketika datang ke presisi Anda benar selama Anda tidak menambahkan kesalahan rotasi ke sistem. Menggunakan offset yang diukur dalam sistem koordinat lokal yang diproyeksikan, kesalahan rotasi mungkin tumbuh cukup besar.
haakon_d
1
Itu titik yang sangat baik: kami telah secara implisit mengasumsikan x-perpindahan setidaknya dekat dengan benar timur-barat dan y-perpindahan dekat utara-selatan. Jika tidak, mereka harus dikonversi menjadi perpindahan EW dan NS yang setara (tidak hanya "arah timur" dan "arah utara") sebelum menghitung ekivalen lat-lon mereka.
whuber
Parameter jarak d dari persamaan Formasi Penerbangan adalah dalam radian, misalnya (jarak / jari-bumi).
user1089933
23

Saya menemukan bahwa Aviation formularium, di sini sangat bagus untuk jenis rumus dan algoritma. Untuk masalah Anda, lihat "lat / panjang yang diberikan radial dan jarak": di sini

Perhatikan bahwa algoritma ini mungkin agak terlalu rumit untuk Anda gunakan, jika Anda ingin tetap menggunakan fungsi trigonometri rendah, dll.

Liedman
sumber
Terima kasih untuk ini - terlihat ideal. Meskipun saya tidak tahu apakah jaraknya dalam meter atau pengukuran lain.
Thomas O
2

Mungkin masuk akal untuk memproyeksikan poinnya terlebih dahulu. Anda dapat membuat sesuatu seperti pseudo-code ini:

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

di mana (x, y) adalah offset yang diinginkan.

Anda tidak perlu menggunakan utm, sistem koordinat datar apa pun, yang masuk akal di wilayah Anda akan berhasil.

Perangkat lunak apa yang Anda gunakan?

MartinHvidberg
sumber