Pergunta

Alguém sabe de uma maneira de buscar todos os polígonos em um dB MySQL a uma determinada distância de um ponto? A distância real não é tão importante, pois é calculada para cada polígono encontrado posteriormente, mas seria uma enorme otimização apenas fazer esse cálculo para os polígonos que estão "próximos".

Eu olhei para o MBR e contém funções, mas o problema é que alguns dos polígonos não estão contidos em uma caixa delimitadora desenhada ao redor do ponto, pois são muito grandes, mas alguns de seus vértices ainda estão próximos.

Alguma sugestão?

Foi útil?

Solução

Uma versão lenta (sem índices espaciais):

SELECT  *
FROM    mytable
WHERE   MBRIntersects(mypolygon, LineString(Point(@X - @distance, @Y - @distance), Point(@X + @distance, @Y + @distance))

Para usar os índices espaciais, você precisa desnormalizar sua tabela para que cada vértice do polígono seja armazenado em seu próprio registro.

Em seguida, crie o SPATIAL INDEX No campo, que contém as coordenadas dos vértices e apenas emitir esta consulta:

SELECT  DISTINCT polygon_id
FROM    vertices
WHERE   MBRContains(vertex, LineString(Point(@X - @distance, @Y - @distance), Point(@X + @distance, @Y + @distance))

As coisas serão muito mais fáceis se você armazenar UTM Coordena em seu banco de dados em vez de latitude e longitude.

Outras dicas

Eu não acho que haja uma única resposta para isso. Geralmente, é uma questão de como organizar seus dados para que eles utilizem a localidade espacial inerente ao seu problema.

A primeira idéia que aparece na minha cabeça seria usar uma grade, atribuir cada ponto a um quadrado e verifique se a seleção do quadrado que o ponto está dentro e as pessoas ao seu redor. Se estamos falando de grades infinitas, use um valor de hash do quadrado, isso daria mais pontos do que o necessário (onde você tem colisões), mas ainda reduzirá o valor. É claro que isso não é imediatamente aplicável aos polígonos, é apenas um brainstorm. Uma abordagem possível que possa produzir muitas colisões seria para ou todos os valores de hash juntos e selecionar todas as entradas em que os hashes e com esse valor são diferentes de zero (não tenho certeza se isso é possível no MySQL), você pode querer usar uma grande quantidade de bits embora.

O problema com essa abordagem é assumir que estamos falando de coordenadas esféricas (Lat, por muito tempo) são as singularidades, à medida que os 'quadrados' da grade crescem mais estreitos à medida que você se aproxima dos pólos. A abordagem fácil para isso é ... não coloque nenhum ponto próximo aos postes ... :)

Crie uma caixa delimitadora para todos os polígonos e (opcionalmente, armazenar esses resultados no banco de dados tornará isso muito mais rápido para polígonos complexos). Você pode comparar a caixa delimitadora de cada polígono com o que volta ao ponto no tamanho desejado. Selecione todos os polígonos que possuem caixas delimitadoras que se cruzam.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top