Quando implementei isso no MySQL (para armazenar lugares em uma esfera oblata, que é basicamente o que a terra é (suponho que você esteja falando sobre a terra!)), armazenei o máximo possível de informações pré-calculadas no banco de dados. Portanto, para uma linha que armazena
latitude
e longitude
, também calculo no momento da inserção os seguintes campos:radiansLongitude
(Math.toRadians(longitude)
)sinRadiansLatitude
(Math.sin(Math.toRadians(latitude)
)cosRadiansLatitude
(Math.cos(Math.toRadians(latitude)
)
Então, quando eu pesquiso os lugares que estão dentro de X unidades da
latitude
/longitude
em questão, minha declaração preparada é a seguinte: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
Onde
YYYY
=3965 fornece distâncias em milhas ou YYYY
=6367 pode ser usado para distâncias em km. Por fim, usei o
maximumSearchLatitude
/ maximumSearchLongitude
/ minimumSearchLongitude
/ maximumSearchLongitude
parâmetros para excluir a maioria dos pontos do conjunto de resultados antes que o banco de dados tenha que realizar quaisquer cálculos. Você pode ou não precisar disso. Se você usar isso, caberá a você quais valores escolher para esses parâmetros, pois dependerá do que você está pesquisando. Obviamente, serão necessárias aplicações criteriosas de índices no banco de dados.
A vantagem de usar essa abordagem é que as informações que nunca mudam, mas são necessárias todas as vezes, são calculadas apenas uma vez, enquanto o cálculo dos valores de
radiansLongitude
, sinRadiansLatitude
, cosRadiansLatitude
para cada linha, toda vez que você realizar uma pesquisa, ficará muito caro muito rápido. A outra opção é usar um índice geoespacial , o que significa que tudo isso é tratado para você pelo banco de dados. Eu não sei quão bem o Hibernate se integra com isso.
Isenção de responsabilidade:faz muito tempo desde que olhei para isso e não sou um especialista em GIS!