如何用 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 文档。
通常,所有空间计算都会在与给定输入相同的坐标系中产生结果。在你的情况下,你应该使用 SRID 4326 进行计算,它是 longitude/latitude 极地,以本初子午线和赤道的度数为单位。
因此,GeoDjango 的距离计算——如果我没记错的话——是两对坐标之间的欧氏距离。您正在搜索 大圆距离 (您除以 111
只是一个粗略的近似值,仅接近某些纬度范围内的实际大圆距离)。
geopy
应该隐含地使用 SRID 4326 的大圆距离,从而产生正确的结果。
您现在有几个不同的选择:
答:自己实现大圈
Google对于haversine
公式,可以打入两对lat/lon坐标,应该可以很好地近似实际的大圆距离。然而,这取决于所使用的墨卡托近似——记住地球不是球体。您可能会 运行 遇到两极附近的问题。
B:转换为公制(局部)坐标系
如果将两个位置转换到另一个以米为单位的坐标系,计算欧几里德距离将产生正确的结果。但是,这样的坐标系(称它们为 平面系统 )对于地球上的不同区域是不同的。不同国家有不同的投影,因为将地球不规则曲面近似为平面是错误的——尤其是对于其表面上的任何位置都不是唯一错误。
这仅适用于您要计算距离的所有点都在同一地理区域中的情况。
C:为此使用库
使用 geopy
或 shapely
或任何其他合格的库,可以根据您给出的点数 SRID 计算实际大圆距离。请记住,由于地球的不规则性,所有坐标都只是近似值。
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 文档。
通常,所有空间计算都会在与给定输入相同的坐标系中产生结果。在你的情况下,你应该使用 SRID 4326 进行计算,它是 longitude/latitude 极地,以本初子午线和赤道的度数为单位。
因此,GeoDjango 的距离计算——如果我没记错的话——是两对坐标之间的欧氏距离。您正在搜索 大圆距离 (您除以 111
只是一个粗略的近似值,仅接近某些纬度范围内的实际大圆距离)。
geopy
应该隐含地使用 SRID 4326 的大圆距离,从而产生正确的结果。
您现在有几个不同的选择:
答:自己实现大圈
Google对于haversine
公式,可以打入两对lat/lon坐标,应该可以很好地近似实际的大圆距离。然而,这取决于所使用的墨卡托近似——记住地球不是球体。您可能会 运行 遇到两极附近的问题。
B:转换为公制(局部)坐标系
如果将两个位置转换到另一个以米为单位的坐标系,计算欧几里德距离将产生正确的结果。但是,这样的坐标系(称它们为 平面系统 )对于地球上的不同区域是不同的。不同国家有不同的投影,因为将地球不规则曲面近似为平面是错误的——尤其是对于其表面上的任何位置都不是唯一错误。
这仅适用于您要计算距离的所有点都在同一地理区域中的情况。
C:为此使用库
使用 geopy
或 shapely
或任何其他合格的库,可以根据您给出的点数 SRID 计算实际大圆距离。请记住,由于地球的不规则性,所有坐标都只是近似值。