Jawaban ini dibagi menjadi beberapa bagian:
Analisis dan Pengurangan Masalah , menunjukkan cara menemukan titik yang diinginkan dengan rutinitas "kalengan".
Ilustrasi: Prototipe Bekerja , memberikan kode kerja.
Contoh , menunjukkan contoh solusi.
Perangkap , membahas potensi masalah dan cara mengatasinya.
Implementasi ArcGIS , komentar tentang membuat alat ArcGIS khusus dan tempat untuk mendapatkan rutinitas yang diperlukan.
Analisis dan Pengurangan Masalah
Mari kita mulai dengan mengamati bahwa dalam model bola (bulat sempurna) akan selalu ada solusi - pada kenyataannya, tepat dua solusi. Diberikan titik dasar A, B, dan C, masing-masing pasangan menentukan "garis-beratnya tegak lurus," yang merupakan himpunan titik-titik yang berjarak sama dari dua titik yang diberikan. Garis bagi ini adalah geodesik (lingkaran besar). Geometri bola berbentuk bulat panjang : setiap dua geodesik berpotongan (dalam dua titik unik). Dengan demikian, titik-titik persimpangan garis-bagi AB dan garis-garis BC adalah - menurut definisi - berjarak sama dari A, B, dan C, dengan demikian menyelesaikan masalah. (Lihat gambar pertama di bawah ini.)
Hal-hal terlihat lebih rumit pada ellipsoid, tetapi karena itu adalah gangguan kecil dari bola, kita dapat mengharapkan perilaku yang sama. (Analisis ini akan membawa kita terlalu jauh.) Rumus rumit yang digunakan (secara internal dalam GIS) untuk menghitung jarak akurat pada ellipsoid bukanlah komplikasi konseptual, meskipun: masalahnya pada dasarnya sama. Untuk melihat betapa sederhananya masalahnya, mari kita nyatakan dengan agak abstrak. Dalam pernyataan ini, "d (U, V)" mengacu pada jarak benar dan akurat antara titik U dan V.
Diberikan tiga titik A, B, C (sebagai pasangan lat-lon) pada ellipsoid, cari titik X yang (1) d (X, A) = d (X, B) = d (X, C) dan ( 2) jarak bersama ini sekecil mungkin.
Ketiga jarak ini semua bergantung pada X yang tidak diketahui . Jadi perbedaan jarak u (X) = d (X, A) - d (X, B) dan v (X) = d (X, B) - d (X, C) adalah fungsi X yang bernilai riil. Sekali lagi, agak abstrak, kita dapat menggabungkan perbedaan-perbedaan ini menjadi pasangan yang teratur. Kami juga akan menggunakan (lat, lon) sebagai koordinat untuk X, memungkinkan kami untuk mempertimbangkannya sebagai pasangan yang dipesan, juga, katakanlah X = (phi, lambda). Dalam pengaturan ini, fungsinya
F (phi, lambda) = (u (X), v (X))
adalah fungsi dari bagian dari ruang dua dimensi yang mengambil nilai dalam ruang dua dimensi dan masalah kita berkurang menjadi
Temukan semua yang mungkin (phi, lambda) untuk yang F (phi, lambda) = (0,0).
Di sinilah abstraksi terbayar: ada banyak perangkat lunak yang hebat untuk memecahkan masalah ini (pencarian akar multidimensi numerik murni). Cara kerjanya adalah bahwa Anda menulis rutin untuk menghitung F , kemudian Anda meneruskannya ke perangkat lunak bersama dengan informasi tentang pembatasan inputnya ( phi harus berada di antara -90 dan 90 derajat dan lambda harus berada di antara -180 dan 180 derajat). Itu engkol pergi untuk sepersekian detik dan mengembalikan (biasanya) hanya satu nilai ( phi , lambda ), jika dapat menemukan satu.
Ada detail untuk ditangani, karena ada seni untuk ini: ada berbagai metode solusi untuk dipilih, tergantung pada bagaimana F "berperilaku"; ini membantu untuk "mengarahkan" perangkat lunak dengan memberikannya titik awal yang masuk akal untuk pencariannya (ini adalah salah satu cara kita bisa mendapatkan solusi terdekat , daripada yang lain); dan Anda biasanya perlu menentukan seberapa akurat solusi yang Anda inginkan (sehingga ia tahu kapan harus menghentikan pencarian). (Untuk informasi lebih lanjut tentang apa yang perlu diketahui analis GIS tentang perincian seperti itu, yang banyak muncul dalam masalah GIS, silakan kunjungi Topik yang disarankan untuk dimasukkan dalam kursus Ilmu Komputer untuk Teknologi Geospasial dan lihat di bagian "Lain-lain" di bagian akhir. )
Ilustrasi: Prototipe yang Berfungsi
Analisis menunjukkan kita perlu memprogram dua hal: perkiraan awal kasar solusi dan perhitungan F itu sendiri.
Perkiraan awal dapat dibuat dengan "rata-rata bulat" dari tiga titik dasar. Ini diperoleh dengan mewakili mereka dalam koordinat geosentris Cartesian (x, y, z), rata-rata koordinat tersebut, dan memproyeksikan rata-rata itu kembali ke bola dan mengekspresikannya kembali dalam lintang dan bujur. Ukuran bola tidak material dan perhitungannya dibuat langsung: karena ini hanyalah titik awal, kita tidak perlu perhitungan ellipsoidal.
Untuk prototipe yang berfungsi ini saya menggunakan Mathematica 8.
sphericalMean[points_] := Module[{sToC, cToS, cMean},
sToC[{f_, l_}] := {Cos[f] Cos[l], Cos[f] Sin[l], Sin[f]};
cToS[{x_, y_, z_}] := {ArcTan[x, y], ArcTan[Norm[{x, y}], z]};
cMean = Mean[sToC /@ (points Degree)];
If[Norm[Most@cMean] < 10^(-8), Mean[points], cToS[cMean]] / Degree
]
(Kondisi terakhir If
menguji apakah rata-rata mungkin gagal untuk menunjukkan dengan jelas garis bujur; jika demikian, ia jatuh kembali ke rata-rata aritmatika lurus dari lintang dan bujur inputnya - mungkin bukan pilihan yang bagus, tetapi setidaknya yang valid. Bagi mereka yang menggunakan kode ini untuk panduan implementasi, perhatikan bahwa argumen Mathematica ArcTan
dibalik dibandingkan dengan kebanyakan implementasi lainnya: argumen pertama adalah koordinat x, yang kedua adalah koordinat y, dan mengembalikan sudut yang dibuat oleh vektor ( x, y).)
Sejauh bagian kedua, karena Mathematica - seperti ArcGIS dan hampir semua GIS lainnya - berisi kode untuk menghitung jarak akurat pada ellipsoid, hampir tidak ada yang bisa ditulis. Kami hanya memanggil rutinitas pencarian root:
tri[a_, b_, c_] := Block[{d = sphericalMean[{a, b, c}], sol, f, q},
sol = FindRoot[{GeoDistance[{Mod[f, 180, -90], Mod[q, 360, -180]}, a] ==
GeoDistance[{Mod[f, 180, -90], Mod[q, 360, -180]}, b] ==
GeoDistance[{Mod[f, 180, -90], Mod[q, 360, -180]}, c]},
{{f, d[[1]]}, {q, d[[2]]}},
MaxIterations -> 1000, AccuracyGoal -> Infinity, PrecisionGoal -> 8];
{Mod[f, 180, -90], Mod[q, 360, -180]} /. sol
];
Aspek yang paling penting dari implementasi ini adalah bagaimana ia menghindari kebutuhan untuk membatasi lintang ( f
) dan bujur ( q
) dengan selalu menghitungnya masing-masing modulo 180 dan 360 derajat. Ini menghindari keharusan membatasi masalah (yang sering menimbulkan komplikasi). Parameter kontrol MaxIterations
dll. Di-tweak untuk membuat kode ini memberikan akurasi setinggi mungkin.
Untuk melihatnya dalam tindakan, mari kita terapkan pada tiga poin dasar yang diberikan dalam pertanyaan terkait :
sol = tri @@ (bases = {{-6.28530175, 106.9004975375}, {-6.28955287, 106.89573839}, {-6.28388865789474, 106.908087643421}})
{-6.29692, 106.907}
Jarak yang dihitung antara solusi ini dan tiga titik adalah
{1450.23206979, 1450.23206979, 1450.23206978}
(Ini adalah meter). Mereka setuju melalui angka signifikan kesebelas (yang sebenarnya terlalu tepat, karena jarak jarang akurat hingga lebih baik dari satu milimeter atau lebih). Berikut adalah gambar dari tiga poin ini (hitam), tiga garis timbal balik mereka, dan solusinya (merah):
Contoh
Untuk menguji implementasi ini dan mendapatkan pemahaman yang lebih baik tentang bagaimana masalah itu terjadi, berikut adalah plot kontur dari perbedaan rata-rata kuadrat akar dalam jarak untuk tiga titik dasar yang tersebar luas. (Perbedaan RMS diperoleh dengan menghitung ketiga perbedaan d (X, A) -d (X, B), d (X, B) -d (X, C), dan d (X, C) -d (X , A), rata-rata kuadrat mereka, dan mengambil akar kuadrat.Ini sama dengan nol ketika X memecahkan masalah dan sebaliknya meningkat ketika X menjauh dari solusi, dan dengan demikian mengukur seberapa "dekat" kita untuk menjadi solusi di lokasi mana pun. )
Titik dasar (60, -120), (10, -40), dan (45,10) ditunjukkan dengan warna merah dalam proyeksi Plate Carree ini; solusinya (49.2644488, -49.9052992) - yang membutuhkan 0,03 detik untuk menghitung - berwarna kuning. Perbedaan RMS-nya kurang dari tiga nanometer , meskipun semua jarak yang relevan adalah ribuan kilometer. Area gelap menunjukkan nilai kecil RMS dan area terang menunjukkan nilai tinggi.
Peta ini jelas menunjukkan solusi lain yang terletak dekat (-49.2018206, 130.0297177) (dihitung dengan RMS dua nanometer dengan menetapkan nilai pencarian awal secara diametris berlawanan dengan solusi pertama.)
Perangkap
Ketidakstabilan angka
Ketika poin dasar hampir collinear dan berdekatan, semua solusi akan hampir setengah dunia dan sangat sulit untuk dijabarkan secara akurat. Alasannya adalah bahwa perubahan kecil di lokasi di seluruh dunia - bergerak menuju atau menjauh dari titik dasar - hanya akan menyebabkan perubahan kecil dalam perbedaan jarak. Hanya saja tidak ada cukup akurasi dan presisi yang dibangun dalam perhitungan jarak geodetik yang biasa untuk memberikan hasil.
Misalnya, dimulai dengan titik dasar di (45.001, 0), (45, 0), dan (44.999.0), yang dipisahkan sepanjang Prime Meridian dengan hanya 111 meter antara masing-masing pasangan, tri
mendapatkan solusi (11.8213, 77.745) ). Jarak dari itu ke titik dasar adalah 8.127.964.998 77; 8.127.964.998 41; dan 8.127.964.998 masing-masing 65 meter. Mereka setuju dengan milimeter terdekat! Saya tidak yakin seberapa akurat hasil ini, tetapi tidak akan sedikit terkejut jika implementasi lain mengembalikan lokasi yang jauh dari yang ini, menunjukkan kesetaraan hampir sama baiknya dari ketiga jarak.
Waktu perhitungan
Perhitungan ini, karena melibatkan pencarian yang cukup dengan menggunakan perhitungan jarak yang rumit, tidak cepat, biasanya membutuhkan sepersekian detik. Aplikasi waktu nyata perlu mengetahui hal ini.
Implementasi ArcGIS
Python adalah lingkungan skrip yang disukai untuk ArcGIS (dimulai dengan versi 9). The paket scipy.optimize memiliki rootfinder multivariat root
yang harus melakukan apa yang FindRoot
dilakukannya dalam Mathematica kode. Tentu saja ArcGIS sendiri menawarkan perhitungan jarak ellipsoidal yang akurat. Selebihnya, adalah semua detail implementasi: tentukan bagaimana koordinat titik dasar akan diperoleh (dari lapisan? Diketik oleh pengguna? Dari file teks? Dari mouse?) Dan bagaimana output akan disajikan (sebagai koordinat ditampilkan di layar "sebagai titik grafik" sebagai objek titik baru dalam sebuah lapisan?), tulis antarmuka itu, port kode Mathematica yang ditunjukkan di sini (langsung), dan Anda akan siap.