緯度と経度の平均座標の計算


19

複数の緯度と経度のスポット間の平均を計算するにはどうすればよいですか?

latとlngの両方の算術平均を計算するだけですか?


3
平均化の適切性は、ユースケースに依存すると思います。Webマップ用に都市のレストランの場所をクラスタリングしている場合、ほとんどの場合、平均化が機能することを確認してください。ただし、いくつかの場所でバグが発生します。プロトタイプまたは低予算のアプリの場合は、おそらく大丈夫です。ただし、もっと深刻なことをしている場合や広範囲をカバーしている場合は、投影のニュアンスを考慮する必要があります。
グレン

1
これらのポイントはどのように収集されましたか?座標を平均化する方法を尋ねる代わりに、平均化が測定誤差を補正する適切な方法であるかどうかを尋ねるかもしれません。この電子ブック には多くのエラー定義があります。
カーククイケンドール

「平均点」が明確に定義されていないエッジケースがいくつかあることに注意してください。例えば、赤道に沿ったどこかがN極とS極の「平均」になる可能性があります。
ダンS.

回答:


15

簡単な意味では、経度と緯度の座標を平均したくありません。これは低緯度ではかなりうまくいくかもしれませんが、高緯度では結果が悪くなり、極付近で完全に壊れ始めます。

このタイプのことで使用した方法は、経度/緯度座標を3Dデカルト座標(x、y、z)に変換することです。これらを平均して(デカルトベクトルを得るため)、再度変換します。ベクトルを正規化する必要はないため、実際の平均プロセスは単純な合計になる可能性があることに注意してください。


編集、ここに私のコードがあります:

以下は、デカルト座標を緯度/経度(度)に変換します:RAD2DEGラジアンの定数を削除します。

Latitude = MPUtility.RAD2DEG * Math.Atan2(z, Math.Sqrt(x * x + y * y));
Longitude = MPUtility.RAD2DEG * Math.Atan2(-y, x);

そして、ここでは緯度/経度(ラジアンで指定)からデカルト座標を計算します。

private void CalcCartesianCoord()
{
    _x = Math.Sin(LatitudeRadians) * Math.Cos(LongitudeRadians);
    _y = Math.Sin(LatitudeRadians) * Math.Sin(LongitudeRadians);
    _z = Math.Cos(LatitudeRadians); 
}

両方とも実際のコードから切り取って貼り付けられているため、度とラジアンが混在しています。ここには、いくつかの変換を行うプロパティがあります(たとえばLatitudeRadians、ラジアン値を返すプロパティです)。

最適化が可能であることに注意してください。たとえば、正弦計算を複製します。また、トリガーの計算を頻繁に呼び出すと、キャッシュ可能な場合があります。


1
素晴らしい点。私がそれを言及するのを忘れたとは信じられません。
グレン

3
(+1)問題は極と+ -180度子午線に限定されません:平均化するポイントの緯度が大幅に異なる場合、緯度/経度座標の直線平均は、プレートキャリー投影の使用と同等です。緯度とともに増加する可変メトリック歪みを導入します。数値的な問題はありませんが、平均は単に間違った場所にあります。このため、@ Glennの回答で提案されている緯度/経度の計算は、比較的小さな非極性領域を除いてほとんど受け入れられません。
whuber

@winwaedありがとう、これを行うためのいくつかの(Java)コードスニペットまたは良いチュートリアルを提案できますか?
動脈瘤

1
数学は「デカルト座標」の下のen.wikipedia.org/wiki/Spherical_coordinatesにあります。(私の実装はC#で、部分的に最適化されています-加えて、歯科医でこれを入力しています!!)
winwaed

1
エンジニアリングの正確な使用例については非常に正しいと思います。ただし、極端な精度が必要な場合を除き、都市および地域のWGS84緯度、経度座標の平均化はかなりうまく機能し、平均化を使用するほとんどの用途で許容できる精度の結果が得られます。
グレン

3

クラスタリングオプション:この種の操作をカバーする概念的なバズワードは、「クラスタリング」です。平均化は、実装が最も簡単で、ほとんどの目的に適しています。私が何か他のものを使用するのは、外れ値[編集]->極または国際日付変更線が心配な場合だけです。[編集]->また、平均化すると、クラスターの中心に近いものが得られますが、緯度経度が常に同じ距離ではないという事実に起因する投影の不正確さのため、少しずれますkm /マイル単位で離れています。平均化する面積が大きいほど、歪みが大きくなります。

以下は、いくつかのクラスタリングオプションの比較です。

平均(簡単、最速、不正確): lat値を合計してカウントで除算し、lng値についても同じことを行います。Int32を使用している場合、一部のシステム(特にc#)が静かにオーバーフローして低い数値に戻る場合、オーバーフローに注意してください。加算アキュムレータに浮動小数点の精度を使用すると、これらのエラーを回避できます。この方法の問題の1つは、外れ値によって位置が歪む可能性があることです。[編集]->もう1つは、極と国際日付変更線の近くでの数学がうまく平均化されず、場所をひどくゆがめることです。

最近傍(少し難しく、遅く、外れ値の偏りがない) 平均化するのではなく、実際の緯度経度の位置で、すべての隣接点までの平均距離が最小になるようにすることができます。これは、「中央値」を取るようなものです。欠点は、すべてのポイントを他のすべてのポイントと比較し、それらの間の距離を計算するため、これは計算コストが高いことです。たとえば、10,000ポイントをクラスター化するには、1億の距離計算が必要になります。それほど遅くはありませんが、確実にうまくスケーリングできません。

グリッドセル(少し余分な設定が必要で、はるかに高速で、外れ値の偏りはありません)これは最近傍に似ていますが、はるかに高速です。任意のレベルの精度、たとえば.01 deg lat lng(人口緯度でおよそ1 km程度)を選択し、ポイントを.01 x .01度のバケットにグループ化できます。次に、最も多くのポイントを持つバケットを選択し、それらのポイントの平均を取るか、それらのポイントのみで最近傍分析を実行します。私はこの方法を非常に大きなデータセット(数千億件のレコード)で頻繁に使用し、精度と速度のバランスが取れていることを発見しました。

Convex Hull Centroid(ハード、スロー、きちんとした結果): ポイントの周りにバンドを描画して、それらすべてをカバーする形状を定義し(ウィキペディアを参照)、この形状の中心点を計算することもできます。典型的な重心関数は中心に重み付けされていないため、エッジから最も遠いものが見つかるまで、形状内のサンプルポイントを使用して、ある種の逆最近傍分析を行う必要があります。この方法は、高速でも特に正確でもない実際の中心検出アルゴリズムではなく、凸包自体のために非常に興味深いものです。


@winwaedは、極付近の座標の平均化について素晴らしい点を示しており、国際日付変更線も追加します。たとえば、片側に1つのポイントがあり、もう一方に1つのポイントがある場合、いくつかの悪い平均(および境界ボックス)が得られます。これはめったに発生しませんが、それを実行すると、デバッグするのが非常に苦痛になります
グレン

@whuberは、平均化したときに中心のドリフトについて良い点を示します。平均化するとクラスターの中心に近いものが得られますが、緯度と経度は必ずしもkm / milesで同じ距離にあるわけではないという事実に起因する投影の不正確さのため、少しずれます。平均化する面積が大きいほど、歪みが大きくなります。
グレン

0

何を達成しようとしているのかわかりませんが、緯度が元のポイントセットの緯度の平均であり、経度が元のポイントセットの経度の平均であるポイントが、元のポイントセットの平均ポイントになります。[更新]:上記のavgは算術平均です。


あなたの答えでは、avg = Arithmetic mean?
動脈瘤

1
はい正解。それは私が明快さの欠如のために残念に思ったことです。答えを更新しました。しかし、私は確かに、私は...ここにテーブルにひどく有益な何かを持っていないんだけど
GuillaumeC
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.