Als ich dies in MySQL implementiert habe (zum Speichern von Orten auf einer abgeflachten Sphäre, was im Grunde das ist, was die Erde ist (ich nehme an, Sie sprechen von der Erde!)), habe ich so viele vorberechnete Informationen wie möglich in der Datenbank gespeichert. Also für eine Zeile, die latitude
speichert und longitude
, berechne ich auch zum Zeitpunkt des Einfügens die folgenden Felder:
radiansLongitude
(Math.toRadians(longitude)
)sinRadiansLatitude
(Math.sin(Math.toRadians(latitude)
)cosRadiansLatitude
(Math.cos(Math.toRadians(latitude)
)
Wenn ich dann nach den Orten suche, die innerhalb von X Einheiten des latitude
liegen /longitude
In Frage, meine vorbereitete Aussage ist wie folgt:
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
Wobei YYYY
=3965 gibt Ihnen Entfernungen in Meilen oder YYYY
=6367 kann für Entfernungen in km verwendet werden.
Schließlich habe ich die maximumSearchLatitude
verwendet / maximumSearchLongitude
/ minimumSearchLongitude
/ maximumSearchLongitude
Parameter, um die Mehrheit der Punkte aus der Ergebnismenge auszuschließen, bevor die Datenbank irgendwelche Berechnungen durchführen muss. Sie können dies benötigen oder auch nicht. Wenn Sie dies verwenden, liegt es an Ihnen, welche Werte Sie für diese Parameter auswählen, da dies davon abhängt, wonach Sie suchen.
Offensichtlich sind vernünftige Anwendungen von Indizes in der Datenbank erforderlich.
Der Vorteil dieses Ansatzes besteht darin, dass die Informationen, die sich nie ändern, aber jedes Mal benötigt werden, nur einmal berechnet werden, während die Werte von radiansLongitude
berechnet werden , sinRadiansLatitude
, cosRadiansLatitude
denn jede Zeile wird jedes Mal, wenn Sie eine Suche durchführen, sehr schnell sehr teuer.
Die andere Option ist die Verwendung eines Geodatenindex , was bedeutet, dass all dies von der Datenbank für Sie erledigt wird. Ich weiß allerdings nicht, wie gut sich Hibernate damit integrieren lässt.
Haftungsausschluss:Es ist lange her, dass ich mir das angesehen habe, und ich bin kein GIS-Experte!