Distance between two 3D point in geodjango (postgis)

北战南征 提交于 2020-02-25 07:25:07

问题


I have the following problem:
I created two points, for example:

SRID=3857;POINT Z (62780.8532226825 5415035.177460473 100)
SRID=3857;POINT Z (62785.8532226825 5415035.177460473 70)

As you can see, there is 5m difference in X coordinates, and 30m in Z coordinates. When I run a.distance(b) in django shell, it returns 5, which is wrong.

However, whenIi run in a psql shell:

SELECT ST_3DDistance(a.coordinates, b.coordinates)
FROM restapi_entityxyz a, restapi_entityxyz b
WHERE a.external_id='6841zef1561' AND b.external_id='1G23Fzd';

It returns:

st_3ddistance
------------------
 30.4138126514911

Which is the correct answer.

Is it a lack of functionality in geodjango or a bug?
Should I use a custom library to perform such a calculation?

My environment is the following:

  • Python 3.5,
  • Django,
  • postgresql 9.4 + postgis
  • gdal and a lot of python libraries.

回答1:


The django distance method is not for calculating the distance of 3D points (with elevation) but of 2D.

We can work around that by creating a custom 3d distance calculation method, like the one described here: Calculating distance between two points using latitude longitude and altitude (elevation)

  • Let:
    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)
    


Confirmed solution of a similar issue from the second part of my answer here: 3d distance calculations with GeoDjango

来源:https://stackoverflow.com/questions/40024322/distance-between-two-3d-point-in-geodjango-postgis

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