Pregunta

En PHP, tengo el siguiente código para calcular la distancia entre dos ubicaciones:

<?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
?>

Pero ahora quiero seleccionar ubicaciones cercanas a una ubicación determinada a través de PHP desde mi base de datos MySQL:

  • El usuario ingresa a su ciudad natal.
  • Mi secuencia de comandos obtiene los valores de latitud/longitud a través de la API de Google
  • En mi base de datos, tengo alrededor de 200 ubicaciones con un campo para el valor de latitud y un campo para el valor de longitud.
  • Necesito un código para PHP y MySQL para seleccionar las 10 ubicaciones más cercanas a la ciudad natal del usuario.

Espero que puedas ayudarme.¡Gracias de antemano!

¿Fue útil?

Solución

MySQL distancia ortodrómica (fórmula Haversine) hace exactamente lo que necesita .

Con sólo 200 registros sin embargo es posible que también acaba de cargar a todos ellos y comprobar con el código. El conjunto de datos es realmente demasiado pequeño para ser preocuparse demasiado acerca de la base de datos vs código o cualquier otro tipo de optimizaciones.

Cálculo de distancia entre los códigos postales en PHP tiene un par de PHP implementaciones de este algoritmo.

Geo proximidad Buscar es más o menos el mismo problema que tiene.

Otros consejos

Tal vez algo así 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;

o

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 traducido del código PHP)

:1 y :2 es $lat2/180*pi() y $long2/180*pi() respectivamente.

Esa es la fórmula de Haversine.Puede traducir PHP directamente a SQL para poder consultar la base de datos espacialmente (la alternativa es extraer todos los registros de la base de datos y ejecutar los datos a través de PHP).MySQL proporciona todas las funciones matemáticas que necesita.

Hice esto para un sitio web comercial que proporcionaba búsquedas de distancia basadas en códigos postales y postales, por lo que ciertamente es posible sin funciones SIG específicas.

Hay funciones de MySQL disponible para hacer exactamente esto.

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

MySQL tiene la capacidad de filas de índice geoespacialmente. Es posible que no tenga que hacer esto por sí mismo matemáticas (que sólo puede pedir a MySQL para calcular la distancia entre dos objetos geográficos y ordenar por eso ..).

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

Sólo vino una cruz este tema. Tal vez alguien va a estar interesado en esta función, probado en 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;

Calling:

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

¿Por qué no utilizar las funciones geoespaciales de MySQL ...? No, es broma.

Si los 200 registros son lugares reales, como ciudades, etc entonces como una alternativa podría utilizar la API GeoNames'?

La siguiente servicio web proporcionará a los 10 lugares más cercanos al lng lat y siempre que:

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

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

Toda la lista: http://www.geonames.org/export/ws- overview.html

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top