この答えは複数のセクションに分かれています。
問題の分析と削減。「缶詰」ルーチンで目的のポイントを見つける方法を示します。
図:作業用プロトタイプ、作業コードを提供します。
例、ソリューションの例を示します。
潜在的な問題とそれらに対処する方法を議論する落とし穴。
ArcGISの実装、カスタムArcGISツールの作成に関するコメント、および必要なルーチンの入手先。
問題の分析と削減
(完全な円形の)球体モデルには常に解が存在することを確認することから始めましょう。実際には、正確に2つの解があります。基点A、B、およびCが与えられると、各ペアは2つの与えられた点から等距離にある点のセットである「垂直二等分線」を決定します。この二等分線は測地線(大円)です。球体のジオメトリは楕円形です。2つの測地線は(2つの一意のポイントで)交差します。したがって、ABの二等分線とBCの二等分線の交点は、定義上、A、B、およびCから等距離であるため、問題を解決します。(下の最初の図を参照してください。)
楕円体では物事はより複雑に見えますが、球体の小さな摂動であるため、同様の動作が期待できます。(これを分析すると、遠すぎます。)楕円体の正確な距離を計算するために(GISの内部で)使用される複雑な数式は、概念的な複雑さではありませんが、問題は基本的に同じです。 問題が実際にどれほど単純であるかを見るために、多少抽象的に述べましょう。このステートメントの「d(U、V)」は、ポイントUとVの間の完全に正確な距離を指します。
楕円体上の3つの点A、B、C(緯度経度ペアとして)が与えられた場合、(1)d(X、A)= d(X、B)= d(X、C)および( 2)この共通距離は可能な限り小さい。
これら3つの距離はすべて、未知のXに依存します。このような違い距離のU(X)= D(X、A) - D(X、B)とV(X)= D(X、B) - D(X、C)は、Xの実数値関数であります繰り返しますが、やや抽象的には、これらの違いを順序付けられたペアにまとめることができます。また、Xの座標として(lat、lon)を使用します。これにより、X =(phi、lambda)のように、それを順序付きペアと見なすこともできます。この設定では、関数
F(phi、lambda)=(u(X)、v(X))
は、2次元空間の一部からの関数であり、2次元空間の値を取得し、問題は
F(phi、lambda)=(0,0)の可能なすべての(phi、lambda)を見つけます。
ここに抽象化が功を奏します。 この(純粋に数値的な多次元のルート探索)問題を解決するための優れたソフトウェアがたくさんあります。 動作方法は、Fを計算するルーチンを作成し、その入力の制限に関する情報とともにソフトウェアに渡すことです(phiは-90〜90度、lambdaは-180〜180でなければなりません。度)。ほんの数秒でクランクを切り、(通常)1つの値(phi、lambda)を返します(見つかった場合)。
これには技術があるため、処理する詳細があります。Fの「動作」に応じて、さまざまな解決方法を選択できます。検索の合理的な出発点を与えることにより、ソフトウェアを「操縦」するのに役立ちます(これは、他のソリューションではなく、最も近いソリューションを取得できる1つの方法です)。通常、ソリューションの精度を指定する必要があります(そのため、いつ検索を停止するかがわかります)。(GISアナリストがGIS問題でよく出てくるこのような詳細について知っておくべきことの詳細については、地理空間テクノロジーのためのコンピューターサイエンスコースに含まれる推奨トピックをご覧ください。 )
イラスト:実用プロトタイプ
この分析では、解の大まかな初期推定とF自体の計算という2つのことをプログラムする必要があることが示されています。
最初の推定は、3つのベースポイントの「球面平均」によって行うことができます。これは、地心デカルト(x、y、z)座標でそれらを表現し、それらの座標を平均し、その平均を球に投影し、緯度と経度で再表現することにより得られます。球のサイズは重要ではなく、計算は簡単です。これは単なる出発点であるため、楕円計算は必要ありません。
この作業用プロトタイプには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
]
(最終If
条件は、平均が経度を明確に示すことができないかどうかをテストします。そうである場合、入力の緯度と経度の直線的な算術平均にフォールバックします-多分、素晴らしい選択ではありませんが、少なくとも有効なものです。実装ガイダンスにこのコードを使用する場合、Mathematicaの 引数はArcTan
他のほとんどの実装と比較して逆になっていることに注意してください:最初の引数はx座標で、2番目はy座標で、ベクトルによって作られた角度を返します( x、y)。)
2番目の部分に関しては、Mathematica(ArcGISや他のほとんどすべてのGISと同様)には楕円体上の正確な距離を計算するコードが含まれているため、記述することはほとんどありません。ルート検索ルーチンを呼び出すだけです。
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
];
この実装の最も注目すべき点は、常にそれぞれ180度と360度を法として計算することにより、緯度(f
)と経度(q
)を制約する必要性をどのように回避するかです。これにより、問題を制約する必要がなくなります(多くの場合、問題が発生します)。制御パラメーターMaxIterations
などを調整して、このコードが可能な限り最高の精度を提供するようにします。
動作を確認するために、関連する質問で指定された3つのベースポイントに適用してみましょう。
sol = tri @@ (bases = {{-6.28530175, 106.9004975375}, {-6.28955287, 106.89573839}, {-6.28388865789474, 106.908087643421}})
{-6.29692、106.907}
この解と3つの点の間の計算された距離は次のとおりです。
{1450.23206979、1450.23206979、1450.23206978}
(これらはメートルです)。これらは、有効桁数11桁目で一致します(実際には、距離が1ミリ程度を超えるほど正確ではないため、実際には精度が高すぎます)。これらの3つのポイント(黒)、3つの相互二等分線、および解(赤)の写真を次に示します。
例
この実装をテストし、問題の振る舞いをよりよく理解するために、3つの間隔の広いベースポイントの距離の二乗平均平方根の不一致の等高線図を次に示します。(RMSの不一致は、3つの差d(X、A)-d(X、B)、d(X、B)-d(X、C)、およびd(X、C)-d(X 、A)、それらの平方を平均し、平方根を取得します。Xが問題を解くとゼロに等しく、Xが解から離れるにつれて増加し、任意の場所で解にどれだけ「近い」かを測定します。 )
基点(60、-120)、(10、-40)、および(45,10)は、このPlate Carree投影では赤で示されています。ソリューション(49.2644488、-49.9052992)-計算に0.03秒かかりました-は黄色です。関連するすべての距離は数千キロメートルにも関わらず、RMSの不一致は3 ナノメートル未満です。暗い領域はRMSの小さな値を示し、明るい領域は高い値を示します。
このマップは、別のソリューションが(-49.2018206、130.0297177)の近くにあることを明確に示しています(最初のソリューションの正反対に初期検索値を設定することで2ナノメートルのRMSに計算されます)。
落とし穴
数値不安定性
基点がほぼ同一直線上にあり、互いに近接している場合、すべてのソリューションは世界のほぼ半分離れており、正確に特定することは非常に困難です。その理由は、地球上の位置の小さな変化(基点に向かって、または基点から遠ざかる)によって、距離の差に非常に小さな変化しか生じないためです。結果を特定するための測地距離の通常の計算には、十分な精度と精度が組み込まれていません。
たとえば、(45.001、0)、(45、0)、および(44.999,0)の基点から開始し、各ペア間で111メートルだけ主子午線に沿って分離されているためtri
、解(11.8213、77.745)が得られます)。それから基点までの距離は8,127,964.998 77です。8,127,964.998 41; それぞれ8,127,964.998 65メートルです。彼らは最も近いミリメートルに同意します!この結果がどれほど正確であるかはわかりませんが、他の実装がこれから遠く離れた場所を返し、3つの距離のほぼ同等の同等性を示しても、驚くことではありません。
計算時間
これらの計算は、複雑な距離計算を使用したかなりの検索を伴うため、高速ではなく、通常はわずかな秒を必要とします。リアルタイムアプリケーションはこれに注意する必要があります。
ArcGISの実装
Pythonは、ArcGISの推奨スクリプト環境です(バージョン9以降)。scipy.optimizeパッケージは、多変量rootfinder持ってroot
何をすべきFindRoot
ではないMathematicaのコードを。もちろん、ArcGIS自体が正確な楕円距離計算を提供します。残りはすべて実装の詳細です:基点座標の取得方法(ユーザーが入力したレイヤーから、テキストファイルから、マウスから)、出力の表示方法(座標として)を決定します画面に表示されますか?グラフィックポイントとして?レイヤーの新しいポイントオブジェクトとして?)、そのインターフェースを記述し、ここに示されているMathematicaコードを移植します(直接)、あなたはすべて設定されます。