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?
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)
andpolar_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)
andp_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)
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