vincenty、haversine、またはcosinesの球面法則を使用するかどうかにかかわらず、使用する予定のコードの潜在的な問題、注意して緩和すること、vincenty vs haversine vs slocの問題に対処する方法に気づくのは賢明ですよく知られているかもしれないし、知られていないかもしれない、それぞれの潜んでいる問題/エッジケースに気付くと、異なるでしょう。熟練したプログラマーはこれを知っています。初心者はできません。フォーラムからのスニペットが特定の場合に予期しない何かをするとき、私はそれらのフラストレーションのいくつかを免れたいと思っています。これらのいずれかのバージョンを真剣に使用する場合、vincenty、haversine、sloc、SE、SO、Reddit、Quoraなどは、ソリューションの初期コーディングで限定的なヘルプを提供した可能性がありますが、それは意味しません彼らの解決策または受け入れられた「答え」には問題はありません。プロジェクトが十分に重要である場合、適切な妥当な量の研究に値します。マニュアルを読み、ドキュメントを読んで、そのコードのコードレビューが存在する場合はそれを読んでください。100回以上支持されたスニペットまたは要点をコピーして貼り付けても、その安全性が包括的で保証されているという意味ではありません。
cffkが投稿した興味深い答えは、例外やその他の問題を引き起こす可能性のある、パッケージ化されたソリューションに潜むエッジケースに気付くポイントを上げます。その投稿で行われた具体的な主張は、現在追求する私の時間予算を超えていますが、少なくとも1人のビンセンティの実装を含む特定のパッケージに潜んでいる問題があり、少なくとも1人が改善することを提案していますこれらの困難に遭遇するリスクを最小化または排除するために、何らかの方法で。私はvincentyに関するトピックにこれ以上追加しません(それについてはあまりにも無知すぎる)が、代わりにhaversineになります。少なくとも一部はOPに関するトピックです。
一般的に公開されているHaversine式は、Pythonでも他の言語でも、今日のほとんどすべてのIntelおよびIntelのようなシステム、およびARMプロセッサ、powerPCなどでIEEE 754浮動小数点仕様を使用する可能性が最も高いためです。また、浮動小数点近似と丸めのために、180度のアーク距離に近い、または180度のアーク距離で、まれではあるが実際の反復可能な例外エラーの影響を受けやすくなります。一部の初心者は、この状況にまだ噛まれていないかもしれません。このfp仕様は概算と丸めを行うため、fp64を呼び出すコードが例外エラーを引き起こす可能性があるという意味ではありません。しかし、いくつかのコード、IEEE 754 fp64の近似と丸めにより、そのような値を完全に評価すると予想される数学メソッドの領域から値がわずかに外れることがある、いくつかの式はそれほど明白なエッジケースを持たない場合があります。例... sqrt()。負の値がsqrt(-0.00000000000000000122739)などのsqrt()に到達すると、例外エラーが発生します。解決策に向かって進む方法であるHaversine式には、atan2()に2つのsqrt()メソッドがあります。のAを計算し、次いで、SQRTに使用される()、地球上の正反対の点で、わずかに非常にわずかに、0.0より下または1.0より上ためのfp64近似を逸脱することができ、丸め、まれに、しかし反復。このコンテキストでは、一貫性のある信頼性の高い再現性により、これは例外リスクであり、孤立したランダムなフリュークではなく、保護するためのエッジケースであり、軽減します。必要な保護なしのhaversineの短いpython3スニペットの例を次に示します。
import math as m
a = m.sin(dlat / 2)**2 + m.cos(lat1) * m.cos(lat2) * m.sin(dlon / 2)**2
c = 2 * m.atan2(m.sqrt(a), m.sqrt(1 - a))
distance = Radius * c
非常に近くまたは対pod点で、式の最初の行で計算された値は、負の値を逸脱する場合がありますが、めったにありませんが、同じ緯度座標で繰り返します。これらのまれな発生を保護/修正するには、以下に示すように、計算後に単純に追加できます。
import math as m
note = ''
a = m.sin(dlat / 2)**2 + m.cos(lat1) * m.cos(lat2) * m.sin(dlon / 2)**2
if a < 0.0: a = 0.0 ; note = '*'
if a > 1.0: a = 1.0 ; note = '**'
c = 2 * m.atan2(m.sqrt(a), m.sqrt(1 - a))
distance = Radius * c
# note = '*' # a went below 0.0 and was normalized back to 0.0
# note = '**' # a went above 1.0 and was normalized back to max of 1.0
もちろん、ここでは関数全体を示していませんが、頻繁に投稿される短いスニペットです。ただし、これは、aをテストし、必要に応じて正規化することで、sqrt()の保護を示します。note = '' up topは、関数の結果と共に返される場合、値が割り当てられる前にノートが使用されていることをバイトコードステージが抗議しないようにするためのものです。
この2つのaテストを追加するだけの簡単な変更により、sqrt()関数は満足になり、コードには呼び出しコードに返される追加のメモがあり、結果がわずかに正規化されたこととその理由を警告します。気にかける人もいれば、気にしない人もいますが、例外エラーを防ぐために、そうでなければ「発生する」ことがあります。try exceptブロックは例外をキャッチするかもしれませんが、そうするように明示的に書かれていない限り修正しません。それは直後に補正ライン(複数可)のコードに簡単に思える計算行。徹底的にスクラブされた入力は、ここでブロック以外のtryを必要としません。
要約、haversineを使用し、パッケージまたはライブラリを使用するのではなく明示的にコーディングする場合、選択する言語に関係なく、テストして、0.0 <= a <= 1.0の必要な範囲に戻るように正規化することをお勧めしますc計算で次の行を保護します。しかし、haversineコードスニペットの大部分はそれを示しておらず、リスクについては言及していません。
経験:世界中で徹底的なテスト中に、0.001度刻みで、CPU冷却の信頼性を付随的にテストする1か月の間に、例外、信頼性の高い一貫した反復可能な例外を引き起こした緯度経度の組み合わせでハードドライブをいっぱいにしましたファン、そして私の忍耐。はい、それらのログの目的は主にポイントを証明することだったので、私はそれ以来それらのログのほとんどを削除しました(しゃれが許可されている場合)。しかし、テスト用に保存された「問題の緯度経度値」の短いログがいくつかあります。
精度:ドメインとその小さなビットを正規化することで、aとHaversineの結果全体の精度がいくらか失われますか?大したことではないかもしれませんが、おそらくfp64の近似値と端数処理が既に導入されていたため、ドメインからのわずかなドリフトが発生していました。Haversineがvincentyを超えて受け入れられることがすでにわかっている場合、よりシンプルで、高速で、カスタマイズ、トラブルシューティング、および保守が容易な場合、haversineはプロジェクトに適したソリューションです。
私は地球上の位置から見た空のオブジェクト間の角距離を測定するために頭上に投影された天球でヘイバーシンを使用しました。投影された理論上のスカイスフィアは、地球の表面上の位置から2つのオブジェクト間の角度距離と視角を測定する場合、完全な球体です。それは私のニーズに完全に合っています。ですから、特定のアプリケーションでは(十分に私の目的の範囲内で)Haversineは非常に有用で非常に正確です...しかし、GISまたはナビゲーションのために地球上で、または天体の観測および測定でそれを使用する場合、対pod点または対anti点に非常に近い場合、テストにより必要に応じて、必要なドメインに戻します。
保護されていないHaversineはインターネット中にあり、JPLの誰かからのように、1985年以前、IEEE 754以前の浮動小数点仕様であったと思われる、いくつかの保護を示す古いusenetの投稿を見たことがあります。他の2つのページでは、対pod点の近くで起こりうる問題について言及しましたが、それらの問題、またはそれらを軽減する方法については説明しませんでした。したがって、信頼できるプロジェクトにコピーして貼り付けたコードをさらに調査し、エッジケースをテストするのに十分なプラクティスを常に理解していない初心者(私のような)に懸念があります。cffkの興味をそそる投稿は、これらのタイプの問題で公開されており、頻繁に言及されておらず、スニペットで保護するために公開されていることはめったになく、投稿された保護されていない議論されていないバージョンの量と比較して、この方法で議論されることはめったになかったという点で更新されました。
20190923の時点で、haversineフォーミュラのWikiページには、コンピューティングデバイスの浮動小数点の問題により、対pod点で起こりうる問題が実際に言及されています...
https://en.wikipedia.org/wiki/Haversine_formula
(現時点では、wikiページには直接リンクするセクションのhtmlアンカーがないため、ページが読み込まれた後、そのブラウザーページで「これらの数式を使用するとき」を検索すると、言及された対with点に関するヘイバーシンの問題を、より公式に参照してください。)
そして、この他のサイトにも非常に短い言及があります:
https://www.movable-type.co.uk/scripts/latlong.html
「丸めエラーに対する保護を含む」ためにそのページで検索を行うと、これがあります...
atan2が利用できない場合、cは2⋅asin(min(1、√a))から計算できます(丸め誤差に対する保護を含む)。
まれに、丸めエラーが記載されているケースがあり、asin()バージョンでは保護が表示されますが、atan2()バージョンでは表示または表示されません。ただし、少なくとも丸め誤差のリスクについては言及されています。
Haversineを使用する24/7/365アプリケーションであるimhoは、重要かつシンプルなディテールとして、対anti点付近のこの保護を必要とします。
どのHaversineパッケージがこの保護を行うか含まないかはわかりませんが、これにまったく慣れておらず、よく公開されている「スニペット」バージョンを使用する場合は、保護が必要であることがわかります。その保護は実装が非常に簡単です。つまり、vincentyを使用しておらず、パッケージのコードを変更するための簡単なアクセスなしにパッケージ化されたHaversineを使用していない場合です。
IOWは、vincenty、haversine、slocのいずれを使用する場合でも、コードの問題、注意し、緩和すること、およびvincenty vs haversine vs slocの問題に対処する方法が、それぞれの問題に気付くにつれて異なることを認識する必要があります一般的に知られているかもしれないし、知られていないかもしれない問題/エッジケースを潜んでいます。