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!