xml - online - crear archivo gpx
¿Cómo calcular la distancia desde un archivo GPX? (5)
Mike Gavaghan tiene un algoritmo para cálculos de distancia en su sitio. Hay una C # y también una versión JAVA del código.
Tengo un archivo GPX con una pista de GPS. Ahora quiero calcular la distancia que cubrí con esta pista.
¿Cuál es la mejor manera de calcular esto?
La implementación de Delphi de las fórmulas de Vincenty se puede encontrar aquí .
Aquí hay una implementación de Scala.
3958.761 es el radio medio de la Tierra en millas. Para obtener un resultado en km (o en alguna otra unidad) solo modifique este número.
// The Haversine formula
def haversineDistance(pointA: (Double, Double), pointB: (Double, Double)): Double = {
val deltaLat = math.toRadians(pointB._1 - pointA._1)
val deltaLong = math.toRadians(pointB._2 - pointA._2)
val a = math.pow(math.sin(deltaLat / 2), 2) + math.cos(math.toRadians(pointA._1)) * math.cos(math.toRadians(pointB._1)) * math.pow(math.sin(deltaLong / 2), 2)
val greatCircleDistance = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
3958.761 * greatCircleDistance
}
// A sequence of gpx trackpoint lat,long pairs parsed from the track GPX data
val trkpts: Seq[(Double, Double)] = {
val x = scala.xml.XML.loadString(track)
(x // "trkpt").map(trkpt => ((trkpt / "@lat").text.toDouble, (trkpt / "@lon").text.toDouble))
}
// Distance of track in miles using Haversine formula
val trackDistance: Double = {
trkpts match {
case head :: tail => tail.foldLeft(head, 0.0)((accum, elem) => (elem, accum._2 + haversineDistance(accum._1, elem)))._2
case Nil => 0.0
}
}
La forma tradicional de calcular la distancia entre dos puntos (cada par de puntos de referencia en su archivo GPX) es con la fórmula de Haversine.
Tengo una función de SQL Server que implementa el algoritmo. Esto debería ser fácil de traducir a otros idiomas:
create function dbo.udf_Haversine(@lat1 float, @long1 float,
@lat2 float, @long2 float) returns float begin
declare @dlon float, @dlat float, @rlat1 float,
@rlat2 float, @rlong1 float, @rlong2 float,
@a float, @c float, @R float, @d float, @DtoR float
select @DtoR = 0.017453293
select @R = 3959 -- Earth radius
select
@rlat1 = @lat1 * @DtoR,
@rlong1 = @long1 * @DtoR,
@rlat2 = @lat2 * @DtoR,
@rlong2 = @long2 * @DtoR
select
@dlon = @rlong1 - @rlong2,
@dlat = @rlat1 - @rlat2
select @a = power(sin(@dlat/2), 2) + cos(@rlat1) *
cos(@rlat2) * power(sin(@dlon/2), 2)
select @c = 2 * atn2(sqrt(@a), sqrt(1-@a))
select @d = @R * @c
return @d
end
Esto devuelve la distancia en millas. Para kilómetros, reemplace el radio de tierra con su equivalente de km.
Aquí hay una explicación más profunda.
Editar: Esta función es lo suficientemente rápida y precisa para hacer búsquedas de radio con una base de datos de código postal. Ha estado haciendo un gran trabajo en este sitio durante años (pero ya no funciona, ya que el enlace está roto ahora).
Esta pregunta es bastante antigua, pero me gustaría agregar una opción de pitón para que esté completa. GeoPy tiene great-circle distance
y Vincenty distance
.