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

时间:2016-08-29 17:28:44

标签: python django gis 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?

4 个答案:

答案 0 :(得分:5)

通常,所有空间计算都会在给定输入的同一坐标系中产生结果。在你的情况下,你应该使用 SRID 4326 进行计算,它是来自本初子午线和赤道的经度/纬度极数。

因此,GeoDjango的距离计算 - 如果我得到正确的话 - 是两对坐标之间的欧几里德距离。您正在搜索大圆距离(其中111的除法只是一个粗略的近似值,仅接近某些纬度范围内的实际大圆距离)。

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

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

答:自己实施大圈

谷歌的haversine公式,你可以打两对纬度/经度坐标,你应该得到一个很好的近似实际的大圆距离。然而,这取决于使用的墨卡托近似值 - 记住地球不是球体。你可能会遇到两极附近的问题。

B:转换为公制(本地)坐标系

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

仅当您希望计算距离的所有点都在同一地理区域时,此选项才适用。

C:使用库

使用geopyshapely或任何其他合格的库,可根据 SRID 计算实际大圆距离。请记住,所有坐标均为由于地球的不规则性而导致的近似值。

答案 1 :(得分:2)

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

from geopy.distance import vincenty

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

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

有关详细信息,请查看geopy文档。

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

答案 2 :(得分:1)

这里有一个解决方案,它解释了GeoDjango最初做的事情(一个不使用任何标准单位的距离计算,基本上),还有,如何将它变成一个返回距离更多的表格有用的单位 - 代码与你正在做的非常相似,只是它在检索距离之前在每个点上使用变换。链接如下,希望它对您有用:

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

答案 3 :(得分:-2)

GeoDjango将点之间的笛卡尔距离作为以度为单位的浮点值返回。要获得以km或英里为单位的距离值,您可以执行以下操作:



    dist = p1.distance(p2)
    dist.km # or dist.mi for miles

来源:https://docs.djangoproject.com/en/1.10/ref/contrib/gis/functions/#distance