Toen ik dit heb geïmplementeerd in MySQL (voor het opslaan van plaatsen op een afgeplatte bol, wat in feite is wat aarde is (ik neem aan dat je het over aarde hebt!)), heb ik zoveel mogelijk vooraf berekende informatie opgeslagen in de database. Dus voor een rij die latitude
. opslaat en longitude
, bereken ik op het moment van invoegen ook de volgende velden:
radiansLongitude
(Math.toRadians(longitude)
)sinRadiansLatitude
(Math.sin(Math.toRadians(latitude)
)cosRadiansLatitude
(Math.cos(Math.toRadians(latitude)
)
Als ik vervolgens zoek naar de plaatsen die binnen X-eenheden van de latitude
liggen, /longitude
in kwestie is mijn voorbereide verklaring als volgt:
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
Waar YYYY
=3965 geeft u afstanden in mijlen of YYYY
=6367 kan worden gebruikt voor afstanden in km.
Ten slotte heb ik de maximumSearchLatitude
. gebruikt / maximumSearchLongitude
/ minimumSearchLongitude
/ maximumSearchLongitude
parameters om de meeste punten uit de resultatenset uit te sluiten voordat de database berekeningen moet uitvoeren. Misschien heb je dit wel of niet nodig. Als u dit wel gebruikt, is het aan u welke waarden u kiest voor deze parameters, aangezien dit afhankelijk is van wat u zoekt.
Uiteraard zullen oordeelkundige toepassingen van indexen in de database noodzakelijk zijn.
Het voordeel van deze benadering is dat de informatie die nooit verandert maar elke keer nodig is, slechts één keer wordt berekend, terwijl de waarden van radiansLongitude
worden berekend. , sinRadiansLatitude
, cosRadiansLatitude
voor elke rij elke keer dat u een zoekopdracht uitvoert, wordt het erg snel erg duur.
De andere optie is om een geospatiale index te gebruiken , wat betekent dat dit allemaal voor u wordt afgehandeld door de database. Ik weet echter niet hoe goed Hibernate daarmee integreert.
Disclaimer:het is lang geleden dat ik hier naar heb gekeken, en ik ben geen GIS-expert!