How to calculate 3D distance (including altitude) between two points in GeoDjango

倖福魔咒の 提交于 2019-12-18 17:00:07

问题


Prologue:

This is a question arising often in SO:

  • 3d distance calculations with GeoDjango
  • Calculating distance between two points using latitude longitude and altitude (elevation)
  • Distance between two 3D point in geodjango (postgis)

I wanted to compose an example on SO Documentation but the geodjango chapter never took off and since the Documentation got shut down on August 8, 2017, I will follow the suggestion of this widely upvoted and discussed meta answer and write my example as a self-answered post.

Of course, I would be more than happy to see any different approach as well!!


Question:

Assume the model:

class MyModel(models.Model):
    name = models.CharField()
    coordinates = models.PointField()

Where I store the point in the coordinate variable as a lan, lng, alt point:

MyModel.objects.create(
    name='point_name', 
    coordinates='SRID=3857;POINT Z (100.00 10.00 150)')

I am trying to calculate the 3D distance between two such points:

p1 = MyModel.objects.get(name='point_1').coordinates
p2 = MyModel.objects.get(name='point_2').coordinates

d = Distance(m=p1.distance(p2))

Now d=X in meters.

If I change only the altitude of one of the points in question:

For example:

p1.coordinates = 'SRID=3857;POINT Z (100.00 10.00 200)'

from 150 previously, the calculation:

d = Distance(m=p1.distance(p2))

returns d=X again, like the elevation is ignored.
How can I calculate the 3D distance between my points?


回答1:


GeoDjango Distance calculates the 2D distance between two points and doesn't take into consideration the altitude differences.
In order to get the 3D calculation, we need to create a distance function that will consider altitude differences in the calculation:

Theory:

The latitude, longitude and altitude are Polar coordinates and we need to translate them to Cartesian coordinates (x, y, z) in order to apply the Euclidean Formula on them and calculate their 3D distance.

  • Assume:
    polar_point_1 = (long_1, lat_1, alt_1)
    and
    polar_point_2 = (long_2, lat_2, alt_2)

  • Translate each point to it's Cartesian equivalent by utilizing this formula:

    x = alt * cos(lat) * sin(long)
    y = alt * sin(lat)
    z = alt * cos(lat) * cos(long)
    

    and you will have p_1 = (x_1, y_1, z_1) and p_2 = (x_2, y_2, z_2) points respectively.

  • Finally use the Euclidean formula:

    dist = sqrt((x_2-x_1)**2 + (y_2-y_1)**2 + (z_2-z_1)**2)
    



回答2:


Once converted into Cartesian coordinates, you can compute the norm with numpy:

np.linalg.norm(point_1 - point_2)


来源:https://stackoverflow.com/questions/45618544/how-to-calculate-3d-distance-including-altitude-between-two-points-in-geodjang

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!