【问题标题】:How to calculate distance from a GPX file?如何计算与 GPX 文件的距离?
【发布时间】:2009-02-20 15:28:47
【问题描述】:

我有一个带有 GPS 轨迹的GPX file。现在我想计算我用这条赛道走过的距离。

最好的计算方法是什么?

【问题讨论】:

    标签: xml algorithm gps gpx


    【解决方案1】:

    计算两点(GPX 文件中的每一对航路点)之间距离的传统方法是使用 Haversine 公式。

    我有一个实现该算法的 SQL Server 函数。这应该很容易翻译成其他语言:

    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
    

    这将返回以英里为单位的距离。对于千米,将地球半径替换为等效千米。

    Here是更深入的解释。

    编辑:此功能足够快且足够准确,可以使用邮政编码数据库进行半径搜索。多年来,它在this site 上一直表现出色(但现在不再如此,因为链接现在已断开)。

    【讨论】:

    • 非常感谢。我将它移植到java并在这里发布。 @DtoR 是什么意思?到半径的距离?
    • 这是将度数转换为弧度的系数,pi/180。
    • 感谢您的链接。我很快就会发布我的 Java 版本
    • 该方法非常适合简单计算,但它假设地球是球形的。更准确的计算应使用 WGS 84 椭球标准或类似标准。
    【解决方案2】:

    Mike Gavaghan has an algorithm 在他的网站上进行距离计算。有 C# 和 JAVA 版本的代码。

    【讨论】:

      【解决方案3】:

      Vincenty formulae 的 Delphi 实现可以在 here 找到。

      【讨论】:

      • @Adam Carter:我检查了网址,还是没问题。
      【解决方案4】:

      这是一个 Scala 实现。

      3958.761 是以英里为单位的mean radius of the Earth。要获得以公里(或其他单位)为单位的结果,只需更改此数字即可。

      // 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
        }
      }
      

      【讨论】:

        【解决方案5】:

        这个问题比较老了,但为了完整起见,我想添加一个 python 选项。 GeoPy 同时拥有great-circle distanceVincenty distance

        【讨论】:

          猜你喜欢
          • 2014-07-03
          • 2020-09-01
          • 2015-03-23
          • 1970-01-01
          • 2022-06-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多