これをMySQLに実装したとき(基本的に地球とは何か(地球について話していると思います!)である扁球に場所を格納するため)、データベースにできるだけ多くの事前計算された情報を格納しました。したがって、latitude
を格納する行の場合 およびlongitude
、挿入時に次のフィールドも計算します:
-
radiansLongitude
(Math.toRadians(longitude)
) -
sinRadiansLatitude
(Math.sin(Math.toRadians(latitude)
) -
cosRadiansLatitude
(Math.cos(Math.toRadians(latitude)
)
次に、latitude
のX単位内にある場所を検索すると /longitude
問題の、私の準備されたステートメントは次のとおりです:
from Location l where
acos(
sin(:latitude) * sinRadiansLatitude +
cos(:latitude) * cosRadiansLatitude *
cos(radiansLongitude - :longitude)
) * YYYY < :distance
and l.latitude>:minimumSearchLatitude
and l.latitude<:maximumSearchLatitude
and l.longitude>:minimumSearchLongitude
and l.longitude<:maximumSearchLongitude
order by acos(
sin(:latitude) * sinRadiansLatitude +
cos(:latitude) * cosRadiansLatitude *
cos(radiansLongitude - :longitude)
) * YYYY asc
YYYY
=3965は、マイルまたはYYYY
で距離を示します =6367は、km単位の距離に使用できます。
最後に、maximumSearchLatitude
を使用しました / maximumSearchLongitude
/ minimumSearchLongitude
/ maximumSearchLongitude
データベースが計算を実行する前に、結果セットからポイントの大部分を除外するためのパラメーター。これが必要な場合と不要な場合があります。これを使用する場合は、検索対象によって異なるため、これらのパラメーターにどの値を選択するかはあなた次第です。
明らかに、データベース内のインデックスの賢明な適用が必要になります。
このアプローチを使用する利点は、変更されることはないが毎回必要となる情報が1回だけ計算されるのに対し、radiansLongitude
の値を計算することです。 、sinRadiansLatitude
、cosRadiansLatitude
検索を実行するたびにすべての行が非常に高速になります。
もう1つのオプションは、地理空間インデックス を使用することです。 、これは、これらすべてがデータベースによって処理されることを意味します。ただし、Hibernateがそれとどれほどうまく統合されているかはわかりません。
免責事項:これを見てから長い時間が経ち、私はGISの専門家ではありません!