为什么我的代码计算的变换坐标之间的距离不正确?

时间:2019-06-19 04:30:48

标签: python python-3.x distance geopandas pyproj

我有一个很大的点文件,我试图找到这些点与另一组点之间的距离。最初,我使用geopandas的to_crs函数来转换crs,以便在执行df.distance(point)时可以获得以米为单位的精确距离度量。但是,由于文件很大,因此转换文件的crs花费的时间太长。该代码运行了2个小时,但仍未完成转换。因此,我改用了这段代码。

inProj = Proj(init='epsg:4326')
outProj = Proj(init='epsg:4808')

for index, row in demand_indo_gdf.iterrows():
    o = Point(row['origin_longitude'], row['origin_latitude'])
    o_proj = Point(transform(inProj, outProj, o.x, o.y))

    for i, r in bus_indo_gdf.iterrows():
        stop = r['geometry']
        stop_proj = Point(transform(inProj, outProj, stop.x, stop.y))
        print ('distance:', o_proj.distance(stop_proj), '\n\n')

我认为单独转换crs并进行分析可能会更快。对于这组要点:

o = (106.901024 -6.229162)
stop = (106.804 -6.21861)

我将这个EPSG 4326坐标转换为本地投影EPSG 4808,并得到了:

o_proj = (0.09183386384156803 -6.229330112968891)
stop_proj = (-0.005201753272169649 -6.218776788266844)

得出的距离量度为0.09760780527657992。谷歌地图为我提供了一个距离测量,坐标为ostop,为10.79公里。看来我的代码的距离度量给出的答案比实际距离小10 ^ -3倍。为什么呢?我的代码正确吗?

1 个答案:

答案 0 :(得分:1)

您使用的坐标单位是度,而不是米。

您正在使用的Points类可能对此并不在意,并计算了它们之间的笛卡尔距离。

请使用Haversine等式,例如来自here的那个:

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)) 
    r = 6371 # Radius of earth in kilometers. Use 3956 for miles
    return c * r

然后您的代码返回正确的结果:

from pyproj import Proj, transform

inProj = Proj(init='epsg:4326')
outProj = Proj(init='epsg:4808')

o = (106.901024, -6.229162)
stop = (106.804, -6.21861)

o_proj = transform(inProj, outProj, o[0], o[1])
stop_proj = transform(inProj, outProj, stop[0], stop[1])

print(haversine(o_proj[0], o_proj[1], stop_proj[0], stop_proj[1]))