【问题标题】:How can calculate the real distance between two points with GeoDjango?如何使用 GeoDjango 计算两点之间的实际距离?
【发布时间】:2016-08-29 17:28:44
【问题描述】:
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?

【问题讨论】:

  • 根据here 的讨论,您应该首先使用球形墨卡托转换您的点(他们正在使用 geodjango)。抱歉,我帮不上忙,我对地理位置不太感兴趣
  • [复制/粘贴我的其他评论] 谢谢!如果我转换点的结果是:288735.5781466976 (288.73 Km) 误差为 20%。这太多了。

标签: python django gis geodjango


【解决方案1】:

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

因此,GeoDjango 的距离计算——如果我理解正确的话——是两对坐标之间的欧几里得距离。您正在搜索大圆距离(您除以111 只是一个粗略的近似值,仅接近特定纬度范围内的实际大圆距离)。

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

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

A:自己实现大圈

Google for haversine 公式,您可以输入两对纬度/经度坐标,您应该可以很好地近似实际大圆距离。然而,这取决于所使用的墨卡托近似——请记住,地球不是一个球体。你可能会在两极附近遇到问题。

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

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

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

C:为此使用库

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

【讨论】:

  • 谢谢!您认为最好的解决方案是什么?对我来说,如果这个解决方案有一点错误,我会是 B,我知道我总是会得到一个错误。但是如果我应用 B 解决方案(转换为公制(本地)坐标系),我会得到 20% 的错误(请参阅我的其他评论:“如果我转换点的结果是:288735.5781466976 (288.73 Km) 错误为 20 %。 这太多了。”)。所以我认为最好的解决方案是 C。请告诉我你的意见。
  • 球形墨卡托 (SRID 900913) 越接近两极就越错误。只需在谷歌地图上查看南极洲或格陵兰岛的大小。另外,您可能需要参考:gis.stackexchange.com/questions/31681/… -- 总而言之,您绝对应该选择 选项 C
【解决方案2】:

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

from geopy.distance import vincenty

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

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

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

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

【讨论】:

  • 谢谢!但我更喜欢它: from geopy.distance 导入距离;距离(p1,p2)比你的解决方案
【解决方案3】:

网上有一个解决方案,它既解释了 GeoDjango 最初在做什么(本质上不使用任何标准单位的距离计算),也解释了如何将其转换为以更多形式返回距离的形式有用的单位——该代码与您已经在做的非常相似,只是它在检索距离之前对每个点使用了变换。链接如下,希望对你有用:

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

【讨论】:

  • 谢谢!如果我转换点的结果是:288735.5781466976 (288.73 Km) 误差为 20%。这太多了。
  • 是的,我想你可能会被它困住——从今天阅读更多内容来看,人们似乎恢复使用 geopy 或 postgis 作为解决方案,而不是仅仅使用 GeoDjango。当然,如果你不想使用其中任何一个,你可以只计算它。
猜你喜欢
  • 2018-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-30
  • 1970-01-01
  • 2020-09-25
相关资源
最近更新 更多