はい、より良い方法があります。空間インデックスを使用する必要があります。これらのインデックスは、ジオメトリに関するメタデータを整理して、遠くのジオメトリを非常に迅速に除外し、記述した計算を回避することで多くのCPUサイクルを節約します。すべての主要なリレーショナルデータベースは、それらに対応する空間ジオメトリタイプとインデックスを提供するため、自分で実装する必要はありません。
調べたいのは「距離内」クエリ(他のジオメトリから一定の距離内にあるジオメトリのクエリ)です。これらは非常に標準的で非常に解決された問題であり、上記のすべてのデータベースで可能です(そしていくつかに組み込まれています):
- PostGIS:
ST_DWithin
- SQLサーバー:
STDistance
この関数の3Dジオグラフィバージョンでのインデックスの使用がサポートされていることは明らかではありません)
- Oracle:(
SDO_WITHIN_DISTANCE
これは、インデックスの使用をトリガーすることを明示的に言っていません。クエリプランを再確認します。インデックスを使用するためにを適用する必要があるかもしれませんSDO_FILTER
。)
- MySQL:まだこれを理解しています。
インデックスの使用をトリガーするための回避策
システムがこれらのクエリで空間インデックスを使用するのに問題がある最悪の場合、追加のフィルタを追加できます。あなたの探索点を中心とテーブルジオメトリがに対してバウンディングボックスを比較する(距離を検索)長さ2 *の側面と正方形のバウンディングボックスを作成したいという実際の距離をチェックする前に。ST_DWithin
とにかく、上記のPostGIS が内部的に行うことです。
GISの距離
空間インデックスは素晴らしいものであり、問題に対する絶対的な正しい解決策ですが、距離の計算は論理的に複雑になる可能性があります。特に、データがどの投影(基本的には座標系のすべてのパラメーター)に保存されているかを考慮する必要があります。ほとんどの2D投影(さまざまな緯度/経度投影などの角度座標系以外のもの)は長さを大きく歪めます。たとえば、Webメルカトル図法(Google、Bing、および他のすべての主要なベースマッププロバイダーで使用されているもの)は、位置が赤道から遠くなるにつれて面積と距離を拡大します。私はGISで正式に教育を受けていないので間違っているかもしれませんが、2D投影で見た中で最も良いのは、全世界の単一の、一定のポイント。(いいえ、クエリごとに異なるプロジェクションを使用するのは実用的ではありません。インデックスを使用できなくなります。)
一番下の行は、あなたの数学が正確であることを確認する必要があるということです。開発の観点から最も簡単な方法は、回転投影(これらは「地理」と呼ばれることが多い)と回転楕円体モデルを使用した数学の実行をサポートする関数を使用することですが、これらの計算は2Dの計算よりも少し高価ですまた、一部のDBはインデックス作成をサポートしていない場合があります。ただし、それらを使用して許容可能なパフォーマンスを得ることができる場合は、おそらくそれが道です。もう1つの一般的なオプションは、データが世界の特定の部分に限定されている場合に距離と面積の両方をかなり正確に近づける地域投影(UTMゾーンなど)です。アプリに最適なものは、特定の要件によって異なりますが、
これは、組み込みの空間インデックスを使用しない場合でも適用されます。現在使用している、または将来使用するテクノロジーやテクニックに関係なく、データには何らかの予測があり、現在、実行中のクエリや計算にすでに影響を及ぼしています。