Når jeg har implementeret dette i MySQL (til lagring af steder på en oblate kugle, som i bund og grund er, hvad jorden er (jeg går ud fra, du taler om jorden!)), har jeg gemt så meget forudberegnet information som muligt i databasen. Altså for en række, der gemmer latitude
og longitude
, jeg beregner også ved indsættelsestidspunktet følgende felter:
radiansLongitude
(Math.toRadians(longitude)
)sinRadiansLatitude
(Math.sin(Math.toRadians(latitude)
)cosRadiansLatitude
(Math.cos(Math.toRadians(latitude)
)
Så når jeg søger efter de steder, der er inden for X enheder af latitude
/longitude
i spørgsmålet, er min udarbejdede erklæring som følger:
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
Hvor YYYY
=3965 giver dig afstande i miles eller YYYY
=6367 kan bruges til afstande i km.
Endelig har jeg brugt maximumSearchLatitude
/ maximumSearchLongitude
/ minimumSearchLongitude
/ maximumSearchLongitude
parametre for at udelukke størstedelen af punkter fra resultatsættet, før databasen skal udføre nogen beregninger. Du har muligvis brug for dette. Hvis du bruger dette, er det op til dig, hvilke værdier du vælger for disse parametre, da det vil afhænge af, hvad du søger.
Naturligvis vil velovervejede anvendelser af indekser i databasen være nødvendige.
Fordelen ved at bruge denne tilgang er, at den information, der aldrig ændrer sig, men som er nødvendig hver gang, kun beregnes én gang, mens beregning af værdierne af radiansLongitude
, sinRadiansLatitude
, cosRadiansLatitude
for hver række, hver gang du udfører en søgning vil blive meget dyrt meget hurtigt.
Den anden mulighed er at bruge et geospatialt indeks , hvilket betyder, at alt dette håndteres for dig af databasen. Jeg ved dog ikke, hvor godt Hibernate integrerer med det.
Ansvarsfraskrivelse:det er længe siden, jeg har set på dette, og jeg er ikke en GIS-ekspert!