Pergunta

No PHP, eu tenho o seguinte código para calcular a distância entre dois locais:

<?php
function distance($lat1, $long1, $lat2, $long2) {
    // DEGREE TO RADIAN
    $latitude1 = $lat1/180*pi();
    $longitude1 = $long1/180*pi();
    $latitude2 = $lat2/180*pi();
    $longitude2 = $long2/180*pi();
    // FORMULA: e = ARCCOS ( SIN(Latitude1) * SIN(Latitude2) + COS(Latitude1) * COS(Latitude2) * COS(Longitude2-Longitude1) ) * EARTH_RADIUS
    $distance = acos(sin($latitude1)*sin($latitude2)+cos($latitude1)*cos($latitude2)*cos($longitude2-$longitude1))*6371;
    return $distance;
}
echo distance(9.9921962, 53.5534074, 9.1807688, 48.7771056); // Hamburg, DE - Stuttgart, DE
?>

Mas agora, quero selecionar os locais perto de um determinado local via PHP do meu banco de dados MySQL:

  • O usuário digita sua cidade natal
  • Meu script recebe os valores de latitude / longitude através do Google API
  • No meu banco de dados, tenho cerca de 200 locais com um campo para o valor de latitude e um campo para o valor de longitude
  • Eu preciso de um código para PHP e MySQL para selecionar os 10 locais que estão mais próximos à cidade natal do usuário

Eu espero que você possa me ajudar. Agradecemos antecipadamente!

Foi útil?

Solução

MySQL Grande Distância círculo (fórmula Haversine) faz exatamente o que você precisa .

Com apenas 200 registros, contudo, você pode também apenas carregá-los todos e verificá-los com o código. O conjunto de dados é realmente muito pequeno para ser preocupar muito com banco de dados vs código ou quaisquer outras otimizações.

distância entre zip códigos em PHP tem um par de Cálculo implementações de PHP deste algoritmo.

Geo Proximidade Pesquisa é praticamente o mesmo problema que você tem.

Outras dicas

Talvez algo como

SELECT field1, field2, ...,
    ACOS(SIN(latitude / 180 * PI()) * SIN(:1) + COS(latitude / 180 * PI()) * COS(:2) * COS(:2 - longtidude)) * 6371 AS distance
    ORDER BY distance ASC;

ou

SELECT field1, field2, ...,
    ACOS(SIN(RADIANS(latitude)) * SIN(:1) + COS(RADIANS(latitude)) * COS(:2) * COS(:2 - longtidude)) * 6371 AS distance
    ORDER BY distance ASC;

(directamente traduzidos a partir do código PHP)

:1 e :2 é $lat2/180*pi() e $long2/180*pi() respectivamente.

Essa é a fórmula Haversine. Você pode traduzir o PHP diretamente em SQL para que possa consultar o banco de dados espacialmente (o ser alternativa para puxar todos os registros fora do DB e executar os dados através do PHP). MySQL fornece todas as funções de matemática que você precisa.

Eu fiz isso para um site comercial que forneceu pesquisas de distância baseados post / CEP, pelo que a sua certamente possível sem funções GIS específicas.

Existem funções MySQL disponíveis para fazer exatamente isso.

http://dev.mysql.com/doc /refman/5.0/en/gis-introduction.html

MySQL tem a capacidade de linhas do índice geoespacialmente. Você pode não precisar fazer isso de matemática por si mesmo (você pode simplesmente pedir MySQL para calcular a distância entre dois objetos geográficos e classificar por que ..).

Veja: http://forums.mysql.com/read.php ? 23,159205,159205

Apenas veio a atravessar este tema. Talvez alguém estará interessado nesta função, testado em MySql 5.7:

    create function GetDistance(lat1 real, lng1 real, lat2 real, lng2 real) returns real no sql
    return ATAN2(SQRT(POW(COS(RADIANS(lat2)) * SIN(RADIANS(lng1 - lng2)), 2) + 
                POW(COS(RADIANS(lat1)) * SIN(RADIANS(lat2)) - SIN(RADIANS(lat1)) *
                COS(RADIANS(lat2)) *  COS(RADIANS(lng1 - lng2)), 2)), 
                (SIN(RADIANS(lat1)) * SIN(RADIANS(lat2)) + COS(RADIANS(lat1)) *
                COS(RADIANS(lat2)) * COS(RADIANS(lng1 - lng2)))) * 6372.795;

Chamar:

select GetDistance(your_latitude, your_longitude, table_field_lat,
                   table_field_lng) as dist from [your_table] limit 5;

Por que você não usar os recursos geoespaciais do MySQL ...? Não, estou brincando.

Se os 200 registros são lugares reais, como cidades, etc, em seguida, como uma alternativa você pode usar API GeoNames?

A seguir webservice irá fornecer os 10 locais mais próximos da lat e lng desde que:

http://ws.geonames.org/findNearby?lat=47.3&lng = 9

Fonte: http://www.geonames.org/export/web -services.html # findNearbyPlaceName

Lista completa: http://www.geonames.org/export/ws- overview.html

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