序言
这是SO中经常出现的问题:
我想在SO文档上撰写一个示例,但geodjango
章从未起飞,自2017年8月8日文档关闭以来,我将按照this widely upvoted and discussed meta answer的建议编写我的文章例如,作为一个自我回答的帖子。
当然,我也很高兴看到任何不同的方法!!
问题:
假设模型:
class MyModel(models.Model):
name = models.CharField()
coordinates = models.PointField()
我将coordinate
变量中的点存储为lan, lng, alt
点:
MyModel.objects.create(
name='point_name',
coordinates='SRID=3857;POINT Z (100.00 10.00 150)')
我正在尝试计算两个这样的点之间的3D距离:
p1 = MyModel.objects.get(name='point_1').coordinates
p2 = MyModel.objects.get(name='point_2').coordinates
d = Distance(m=p1.distance(p2))
现在d=X
以米为单位。
如果我只改变其中一个点的高度:
例如:
p1.coordinates = 'SRID=3857;POINT Z (100.00 10.00 200)'
从之前的150,计算:
d = Distance(m=p1.distance(p2))
再次返回d=X
,就像忽略高程一样
如何计算我的点之间的3D距离?
答案 0 :(得分:4)
GeoDjango Distance
计算两点之间的2D距离,并没有考虑高度差。
为了进行3D计算,我们需要创建一个距离函数,该函数将考虑计算中的高度差:
<强>理论值:强>
latitude
,longitude
和altitude
为Polar coordinates,我们需要将其翻译为Cartesian coordinates (x
, y
, z
)才能应用Euclidean Formula他们并计算他们的3D距离。
假设:
polar_point_1 = (long_1, lat_1, alt_1)
和
polar_point_2 = (long_2, lat_2, alt_2)
利用以下公式将每个点翻译成笛卡尔等效词:
x = alt * cos(lat) * sin(long)
y = alt * sin(lat)
z = alt * cos(lat) * cos(long)
您将分别获得p_1 = (x_1, y_1, z_1)
和p_2 = (x_2, y_2, z_2)
点。
最后使用欧几里德公式:
dist = sqrt((x_2-x_1)**2 + (y_2-y_1)**2 + (z_2-z_1)**2)
答案 1 :(得分:1)
转换为笛卡尔坐标后,您可以使用numpy计算范数:
np.linalg.norm(point_1 - point_2)
答案 2 :(得分:1)
使用geopy
,这是最简单和完美的解决方案。
https://geopy.readthedocs.io/en/stable/#geopy.distance.lonlat
>>> from geopy.distance import distance
>>> from geopy.point import Point
>>> a = Point(-71.312796, 41.49008, 0)
>>> b = Point(-81.695391, 41.499498, 0)
>>> print(distance(a, b).miles)
538.3904453677203