Pergunta

Como é que um aplicativo executa uma pesquisa de proximidade? Por exemplo, um usuário digita um código postal, em seguida, as listas de aplicativos todas as empresas dentro de 20 milhas ordenados por proximidade.

Eu quero construir algo parecido em PHP e MySQL. esta abordagem é a correta?

  1. obter os endereços para locais Estou interessado em e armazenar em meu banco de dados
  2. Geocode todos os endereços com serviço de geocodificação do Google
  3. Crie uma consulta de banco de dados que inclui fórmula Haversine para fazer a pesquisa por proximidade e ordenação

É este o OK? Na etapa 3, eu vou calcular a proximidade para cada consulta. É melhor ter uma tabela de proximidade que relaciona a distância entre cada empresa e um locais de poucos referência?

Foi útil?

Solução

Se houver registros suficientes para velocidade à matéria, aqui está uma forma de posicioná-los antes do tempo.

Defina uma grade de caixas de cerca de 20 milhas em um lado. Armazenar o número bin com o registro de cada loja. No tempo de pesquisa, calcular os números de todos os compartimentos que se cruzam de um raio de 20 milhas a partir do seu ponto de pesquisa. Em seguida, recuperar todas as lojas em qualquer uma dessas caixas, e proceda como antes.

Outras dicas

Nós usamos isso para fazer muitos milhares de pontos. É importante se você estiver executando isso em SQL para ter um índice na coluna de latitude e longitude. Tentamos fazer isso no SQL 2008, com índices espaciais, mas nós realmente não ver o aumento de desempenho que esperávamos. Embora se você quiser calcular a uma certa distância de um ZIP você precisa pensar se você estiver indo para usar o centróide ZIP ou uma representação polígono da CEP.

Haversine forumla é um bom lugar para começar.

Não tivemos problemas de desempenho calcular a distância em tempo real, nós calculá-lo antes do tempo para algumas aplicações onde sabemos que os pontos antes do tempo e não vão ser de milhões de registros.

SELECT
        [DistanceRadius]=
        69.09 *
        DEGREES(
          ACOS(
            SIN( RADIANS(latitude) )*SIN( RADIANS(@ziplat) ) 
           +
            COS( RADIANS(latitude) )*COS( RADIANS(@ziplat) ) 
           *
            COS( RADIANS(longitude - (@ziplon)) )
          )
        )
        ,*
        FROM
            table

    ) sub
WHERE
    sub.DistanceRadius < @radius

Nós fazemos isso por cerca de 1200 locais. Gostaria apenas de usar a fórmula Haversine on the fly embora dependendo de você aplicação, pode ser melhor para armazená-lo em PHP, em vez de SQL. (Nossa implementação está em .net para que sua milhagem pode variar).

Realmente a nossa maior desvantagem com a forma como foi implementado, é que todos os cálculos (até recentemente) teve de ser calculado sobre a camada de dados que foi dolorosamente lento (quando digo lento, eu realmente quero dizer não-instantânea demorou um segundo ou assim), mas que foi devido ao fato de que ele tinha que calcular a distância para todos os 1200 locais com base no CEP fornecido.

Dependendo do caminho que você escolher, existem maneiras de acelerar os cálculos número distância, olhando para a longitude e latitude e removendo os fora de um intervalo pré-definido (por exemplo, se você está olhando para todos os endereços dentro de 20 milhas há uma gama longitude você pode calcular qual todos os endereços que cair em ser 20 milhas de distância.) Isso pode acelerar você consulta, se necessário.

Nós realmente olhou para armazenar todas as combinações possíveis na nossa base de dados. Na realidade, parece que ele poderia ser um grande armazenamento de dados, mas não é realmente no grande âmbito das coisas. Com índices pode ser bastante rápido, e você não precisa se preocupar com algoritmo de otimização etc. Decidimos contra isso, porque nós tivemos a equação em C #, e isso permitiu-nos para armazenar em cache as informações necessárias para fazer todos os cálculos no camada de negócios. Ou vai funcionar muito bem, é apenas uma questão de que sua preferência é.

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