【问题标题】:ST_Distance_Sphere() in Python?Python中的ST_Distance_Sphere()?
【发布时间】:2023-03-23 14:36:01
【问题描述】:

我正在做一个 Python 项目,我有两个纬度/经度对,我想计算它们之间的距离。在其他项目中,我使用 ST_Distance_Sphere(a.loc_point, b.loc_point) 计算了 Postgres 中的距离,但我想避免将所有数据加载到 Postgres 中,以便计算距离差异。我已经搜索过,但找不到我想要的,这是一个纯粹的 Python 实现,所以我不必将我的数据加载到 Postgres 中。

我知道还有其他将地球视为完美球体的距离计算,但由于精度差,这些计算还不够好,这就是我想使用 PostGIS ST_Distance_Sphere() 函数(或等效函数)的原因.

这是我想计算距离的几个示例经度/纬度:

Lat, Long 1: (49.8755, 6.07594)
Lat, Long 2: (49.87257, 6.0784)

我无法想象我是第一个提出这个问题的人,但是有没有人知道在 Python 脚本中使用 ST_Distance_Sphere() 进行纬度/长距离计算的方法?

【问题讨论】:

    标签: python postgresql postgis


    【解决方案1】:

    我会推荐 geopy 包 - 请参阅文档中的 Measuring Distance 部分...

    针对您的特殊情况:

    from geopy.distance import great_circle
    
    p1 = (49.8755, 6.07594)
    p2 = (49.87257, 6.0784)
    
    print(great_circle(p1, p2).kilometers)
    

    【讨论】:

      【解决方案2】:

      这是一个基本函数,用于计算半径 = 地球半径的完美球体上两个坐标之间的距离

      from math import pi , acos , sin , cos
      def calcd(y1,x1, y2,x2):
         #
         y1  = float(y1)
         x1  = float(x1)
         y2  = float(y2)
         x2  = float(x2)
         #
         R   = 3958.76 # miles
         #
         y1 *= pi/180.0
         x1 *= pi/180.0
         y2 *= pi/180.0
         x2 *= pi/180.0
         #
         # approximate great circle distance with law of cosines
         #
         x = sin(y1)*sin(y2) + cos(y1)*cos(y2)*cos(x2-x1)
         if x > 1:
             x = 1
         return acos( x ) * R
      

      希望这会有所帮助!

      【讨论】:

      • 您如何使用此解决方案获得以米为单位的答案?
      • 在 R = 3958.76 # 英里的行中,只需将 R 设置为以米为单位的地球半径(637.1 万米),这应该以米为单位返回答案
      【解决方案3】:

      看到这个How can I quickly estimate the distance between two (latitude, longitude) points?

      from math import radians, cos, sin, asin, sqrt
      def haversine(lon1, lat1, lon2, lat2):
          """
          Calculate the great circle distance between two points 
          on the earth (specified in decimal degrees)
          """
          # convert decimal degrees to radians 
          lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
          # haversine formula 
          dlon = lon2 - lon1 
          dlat = lat2 - lat1 
          a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
          c = 2 * asin(sqrt(a)) 
          km = 6367 * c
          return km
      

      由亚伦 D

      您可以通过添加miles = km * 0.621371修改它以返回里程

      【讨论】:

        【解决方案4】:

        除了此处提供的答案之外,我还找到了另一种方法。使用 python hasrsine 模块。

        from haversine import haversine as h
        
        # Return results in meters (*1000)
        print '{0:30}{1:12}'.format("haversine module:", h(a, b)*1000)
        

        我根据我在 Postgres 中使用 ST_Distance_Sphere(a, b) 得到的结果测试了所有三个答案以及 hasrsine 模块。所有答案都很好(谢谢),但 Sishaar Rao 的所有数学答案(calcd)是最接近的。结果如下:

        # Short Distance Test
        ST_Distance_Sphere(a, b):     370.43790478    
        vincenty:                     370.778186438
        great_circle:                 370.541763803
        calcd:                        370.437386736
        haversine function:           370.20481753
        haversine module:             370.437394767
        
        #Long Distance test:
        ST_Distance_Sphere(a, b):     1011734.50495159
        vincenty:                     1013450.40832
        great_circle:                 1012018.16318
        calcd:                        1011733.11203
        haversine function:           1011097.90053
        haversine module:             1011733.11203
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-09
          • 1970-01-01
          • 2020-07-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-18
          相关资源
          最近更新 更多