如何计算GeoDjango中两点之间的3D距离(包括高度)

时间:2017-08-10 16:03:54

标签: python django gis postgis geodjango

序言

这是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距离?

3 个答案:

答案 0 :(得分:4)

GeoDjango Distance计算两点之间的2D距离,并没有考虑高度差。
为了进行3D计算,我们需要创建一个距离函数,该函数将考虑计算中的高度差:

<强>理论值:

latitudelongitudealtitudePolar 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