2

我想通过使用库中的Geod类来计算两个 lon / lat 点之间的距离pyproj

from pyproj import Geod

g = Geod(ellps='WGS84')
lonlat1 = 10.65583081724002, -7.313341167341917
lonlat2 = 10.655830383300781, -7.313340663909912

_, _, dist = g.inv(lonlat1[0], lonlat1[1], lonlat2[0], lonlat2[1])

我收到以下错误:

ValueError                                Traceback (most recent call last)
<ipython-input-5-8ba490aa5fcc> in <module>()
----> 1 _, _, dist = g.inv(lonlat1[0], lonlat1[1], lonlat2[0], lonlat2[1])

/usr/lib/python2.7/dist-packages/pyproj/__init__.pyc in inv(self, lons1, lats1, lons2, lats2, radians)
    558         ind, disfloat, dislist, distuple = _copytobuffer(lats2)
    559         # call geod_inv function. inputs modified in place.
--> 560         _Geod._inv(self, inx, iny, inz, ind, radians=radians)
    561         # if inputs were lists, tuples or floats, convert back.
    562         outx = _convertback(xisfloat,xislist,xistuple,inx)

_geod.pyx in _geod.Geod._inv (_geod.c:1883)()

ValueError: undefined inverse geodesic (may be an antipodal point)

此错误消息来自哪里?

4

1 回答 1

6

这两点仅相距几厘米。看起来pyproj/Geod不能很好地处理靠得很近的点。这有点奇怪,因为在这样的距离下,简单的平面几何已经绰绰有余了。此外,该错误消息有点可疑,因为它表明这两个点是对映的,即完全相反,显然不是这样!OTOH,也许它提到的对映点是在计算中以某种方式出现的一些中间点......不过,我在使用这样的库时会犹豫不决。

鉴于这个缺陷,我怀疑它pyproj还有其他缺陷。特别是,它可能使用旧的文森蒂公式进行椭球测地线计算,已知该公式在处理近对映点时不稳定,并且在远距离上不是特别准确。我推荐使用 CFF Karney 的现代算法。

Karney 博士是 Wikipedia 关于测地线文章的主要贡献者,特别是椭圆体上的测地线,他的 geodesics 在PyPi上可用,因此您可以使用pip. 有关更多信息,请参阅他的SourceForge 站点以及其他语言的 geolib 绑定​​。

FWIW,这是一个简短的演示,使用 geolib 来计算您问题中的距离。

from geographiclib.geodesic import Geodesic

Geo = Geodesic.WGS84

lat1, lon1 = -7.313341167341917, 10.65583081724002
lat2, lon2 = -7.313340663909912, 10.655830383300781

d = Geo.Inverse(lat1, lon1,  lat2, lon2)
print(d['s12'])

输出

0.07345528623159624

该数字以米为单位,因此这两点相距 73 毫米多一点。


如果您希望看到 geolib 用于解决复杂的测地线问题,请参阅我去年写的这个math.stackexchange 答案,其中包含 Python 2 / 3 源代码在gist上。


希望这不再是问题,因为pyproj 现在使用 geolib 中的代码

于 2016-11-25T11:04:35.767 回答