Calcular la distancia entre puntos de geolocalizaciones múltiples

3 minutos de lectura

Mi aplicación recopila puntos de geolocalización del usuario cada cierta cantidad de tiempo, estoy tratando de usar estos puntos para calcular la distancia desde el primer punto a través de todos los puntos.

tenga en cuenta que cuando el usuario se mueve en línea recta, los puntos de geolocalización no forman una línea recta, porque los puntos que recopilo tienen un margen de error debido a la imprecisión, por lo que no puedo usar algo como Fórmula Haversine porque dará un valor incorrecto (distancia más larga que la distancia real)

y no puedo usar API de distancia de Google Maps porque calcula la distancia entre 2 puntos solamente, y será muy costoso llamarlo 200 veces para calcular la distancia a través de todos los puntos.

y quiero calcular este valor en el lado del servidor debido a algunas reglas de seguridad que tengo. por lo tanto, usar el SDK de Google Maps en la interfaz para calcularlo tampoco es una opción.

Alguna idea …

  • Una opción sería simplificar la línea, luego ejecutar los datos a través de la API de Google Roads (suponiendo que el viaje sea por carreteras) y luego medir la longitud de la línea resultante (siguiendo las carreteras).

    – geocodezip

    28 de septiembre de 2019 a las 14:49

  • Gracias por tu solución, ¡funcionó! Convertí mis puntos de geolocalización sin procesar en puntos en la carretera real y luego usé un método fuera de línea para calcular la distancia usando los puntos ajustados

    – Hamzeh Hirzallah

    29 de septiembre de 2019 a las 7:25

  • ¿Puede proporcionar algún ejemplo de código con el que haya tenido problemas y publicar una solución para que su pregunta pueda ser de ayuda en el futuro? Por el momento, no está completamente claro qué hizo para alcanzar y resolver el problema. Gracias

    – Pedro Rodríguez

    29 de septiembre de 2019 a las 14:18

Una opción sería simplificar la línea y luego ejecutar los datos a través del API de carreteras de Google (asumiendo que el viaje es por caminos), luego mida la longitud de la línea resultante (siguiendo los caminos).

para cualquiera que tenga el mismo problema, he seguido este enlace
https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/roads/snap

aquí está mi código en PHP

// snap the collected points from user to the nearest road using google API
$fields = array(
    'path' => '60.170880,24.942795|60.170879,24.942796|60.170877,24.942796|60.170902,24.942654',
    'key' =>  '<YOUR_KEY_HERE>'
);
$url = "https://roads.googleapis.com/v1/snapToRoads?" . http_build_query($fields, '', '&');

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response  = curl_exec($ch);
$response = json_decode($response);

$totalDistance = 0;
$previousPoint = null;
foreach ($response->snappedPoints as $pointOnRoad) {
    if(!$previousPoint){
        $previousPoint = $pointOnRoad;
        continue;
    }

    $totalDistance += getDistance($pointOnRoad->location->latitude, $pointOnRoad->location->longitude,
                                  $previousPoint->location->latitude, $previousPoint->location->longitude);
}

echo $totalDistance;


// calculate distance between 2 geo points
function getDistance($latitude1, $longitude1, $latitude2, $longitude2) {

    $earth_radius = 6371;

    $dLat = deg2rad($latitude2 - $latitude1);
    $dLon = deg2rad($longitude2 - $longitude1);

    $a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * sin($dLon/2) * sin($dLon/2);
    $c = 2 * asin(sqrt($a));
    $d = $earth_radius * $c;

    return $d;
}   

Estamos teniendo un tipo similar de requisito. Hay 2 rutas y debemos asegurarnos de que cada nodo en la primera ruta (excepto el inicio y el final) esté al menos a 100 KM de distancia entre sí de la segunda ruta.

¿Puede compartir un fragmento de código o la lógica detrás de esto?

Planteamiento del problema

El uso de la fórmula de Haversine en bucle afectará el rendimiento. Por lo tanto, sugiera alguna solución mejor.

¿Ha sido útil esta solución?