【问题标题】:Python distance in miles to euclidean distance between two gps coordinates以英里为单位的 Python 距离到两个 gps 坐标之间的欧几里得距离
【发布时间】:2020-10-29 03:31:36
【问题描述】:

我正在尝试提出一个功能...
输入:以英里或公里为单位的测地距离
输出:任意两个gps点之间的欧式距离,即输入距离

我觉得我有一些组件

import numpy as np
from numpy import linalg as LA
from geopy.distance import geodesic

loc1 = np.array([40.099993, -83.166000])
loc2 = np.array([40.148652, -82.903962])

这是这两点之间的欧几里得距离

LA.norm(loc1-loc2)
#0.2665175636332336

这是这两点之间的测地线距离

geodesic(loc1,loc2).miles
#14.27909749425243

我的大脑现在的汁液不足,任何人都对我如何制作如下函数有任何想法:

geodesic_to_euclidean(14.27909749425243)
#0.2665175636332336

【问题讨论】:

  • 假设地球表面是一个球体,你想要连接两个地理位置的弧的距离吗?
  • 我只查看 50 英里以内的范围,所以我认为假设平坦的表面是公平的?
  • LA.norm 无论如何都不会给你正确的值,因为你没有使用笛卡尔坐标。您需要计算两个位置相对于地球中心的角度(以弧度为单位),然后乘以地球的半径。
  • 好吧,所以我在聚类算法 DBSCAN 中使用欧几里德距离作为参数。输入到算法中的唯一维度是纬度和经度。所以我不需要欧几里得距离来表示任何真实的东西,只需要任何两个向量之间的 2-Norm 距离。这有问题吗?...我对 GIS 的东西超级陌生...
  • @Jamalan 越靠近两极,准确性就会下降。这也是墨卡托地图投影将南极洲炸得比实际大得多的原因。

标签: python gis


【解决方案1】:

如果您对大圆距离没问题(如 cmets 中所述),那么这应该可行。这是harsine距离:

def haversine(origin, destination, units='mi'):
    # Radian deltas
    origin_lat = radians(float(origin[0]))
    origin_lon = radians(float(origin[1]))
    destination_lat = radians(float(destination[0]))
    destination_lon = radians(float(destination[1]))
    lat_delta = destination_lat - origin_lat
    lon_delta = destination_lon - origin_lon

    # Radius of earth in meters
    r = 6378127

    # Haversine formula
    a = sin(lat_delta / 2) ** 2 + cos(origin_lat) * \
        cos(destination_lat) * sin(lon_delta / 2) ** 2
    c = 2 * asin(sqrt(a))
    meters_traveled = c * r

    scaling_factors = {
        "m:": 1,
        "km": 1 / 1000,
        "ft": 3.2808,  # meters to feet
        "mi:": 0.000621371  # meters to miles
    }

    return meters_traveled * scaling_factors[units]

如果您已经有了以米为单位的测地线(大圆)距离并且想要弦长,那么您可以执行以下操作

def chord(geodesic_distance):
    """
    Chord length
    C = 2 * r * sin(theta/2)

    Arc length; which is geodesic distance in this case
    AL = R * theta

    therefore
    C = 2 * R * sin(AL/(2*R))
    """
    r = 6378127  # Radius of earth in meters

    return 2 * r * sin(geodesic_distance / (2 * r))

【讨论】:

  • @Jamalan 绝对不是均匀分布的网格。我知道这可能看起来不像你在想的那样,但你所说的是要求弦和相同角度的弧之间的长度差异。对于小角度(相对于地球半径的小距离),这种差异将是最小的。
  • @Jamalan c 已经是弧度的角度了。只需乘以 180/pi
  • @Jamalan 请参阅上面的和弦长度编辑。不过 Aaron 是对的 - 对于地球表面附近的距离,这将略有不同
  • 你们太棒了。这是堆栈溢出的好处。非愤世嫉俗,只是乐于助人的人。非常感谢你们。我会将您的智慧和代码转化为时尚的辅助函数。
猜你喜欢
  • 1970-01-01
  • 2019-06-19
  • 1970-01-01
  • 2011-01-29
  • 2013-03-02
  • 1970-01-01
  • 2021-12-21
相关资源
最近更新 更多