如何用 GeoDjango 计算两点之间的实际距离?

How can calculate the real distance between two points with GeoDjango?

from django.contrib.gis.geos import Point

p1 = Point(36.74851779201058, -6.429006806692149, srid=4326)
p2 = Point(37.03254161520977, -8.98366068931684, srid=4326)
p1.distance(p2)
Out: 2.5703941316759376

但是这个浮点数的单位是什么?

如果计算这个距离,就是229.88 Km。您也可以使用 geopy 获取它:

from geopy.distance import distance
distance(p1, p2)
Out: Distance(229.883275249)
distance(p1, p2).km
Out: 229.88327524944066

我读到过,如果将前面的数字除以 111,就可以得到(一般):

(2.5703941316759376 / 111) * 10000
Out: 231.5670388897241  # kilometers

有什么方法可以只使用 GeoDjango 来获取真实距离吗?还是应该使用 geopy?

在线有一个解决方案,它解释了 GeoDjango 最初在做什么(本质上不使用任何标准单位的距离计算),以及如何将其变成 returns 以更有用的单位表示的距离——代码与您已经在做的非常相似,除了它在检索距离之前在每个点上使用变换。 link如下,希望对你有用:

https://coderwall.com/p/k1gg1a/distance-calculation-in-geodjango

据我所知,GeoDjango 不支持计算实际距离。它只是在几何上计算距离。因此,我认为你应该像我在我的项目中那样使用geopy..

from geopy.distance import vincenty

distance = vincenty((lat1, lon1), (lat2, lon2)).kilometers

这将给出以公里为单位的正确距离。

有关更多信息,请查看 geopy 文档。

http://geopy.readthedocs.io/en/latest/

通常,所有空间计算都会在与给定输入相同的坐标系中产生结果。在你的情况下,你应该使用 SRID 4326 进行计算,它是 longitude/latitude 极地,以本初子午线和赤道的度数为单位。

因此,GeoDjango 的距离计算——如果我没记错的话——是两对坐标之间的欧氏距离。您正在搜索 大圆距离 (您除以 111 只是一个粗略的近似值,仅接近某些纬度范围内的实际大圆距离)。

geopy 应该隐含地使用 SRID 4326 的大圆距离,从而产生正确的结果。

您现在有几个不同的选择:

答:自己实现大圈

Google对于haversine公式,可以打入两对lat/lon坐标,应该可以很好地近似实际的大圆距离。然而,这取决于所使用的墨卡托近似——记住地球不是球体。您可能会 运行 遇到两极附近的问题。

B:转换为公制(局部)坐标系

如果将两个位置转换到另一个以米为单位的坐标系,计算欧几里德距离将产生正确的结果。但是,这样的坐标系(称它们为 平面系统 )对于地球上的不同区域是不同的。不同国家有不同的投影,因为将地球不规则曲面近似为平面是错误的——尤其是对于其表面上的任何位置都不是唯一错误。

这仅适用于您要计算距离的所有点都在同一地理区域中的情况。

C:为此使用库

使用 geopyshapely 或任何其他合格的库,可以根据您给出的点数 SRID 计算实际大圆距离。请记住,由于地球的不规则性,所有坐标都只是近似值。