简体   繁体   English

如何一次计算沿路径(纬度/经度点)的测地距离?

[英]How to calculate geodesic distance along a path (lat/lon points) at once?

Using Python 3.7 with Jupyter Notebook on a Win10 x64.在 Win10 x64 上使用 Python 3.7 和 Jupyter Notebook。

I have a list of lat-long tuples representing a path and I want to calculate the total length along that path in meters.我有一个表示路径的经纬度元组列表,我想计算沿该路径的总长度(以米为单位)。 I would like to avoid calculating each segment distance and then adding them all together as I have to do this for 7 million paths.我想避免计算每个段距离,然后将它们全部加在一起,因为我必须对 700 万条路径执行此操作。 So time efficiency is key.所以时间效率是关键。 Adding all segments after computing individual distances takes 7ms per path.在计算单个距离后添加所有段每条路径需要 7 毫秒。 I want to make it at least 1ms fast.我想让它至少快 1ms。

Edit: I need to calculate distances using the WGS84 ellipsoid, so spherical (Haversine) is not sufficient.编辑:我需要使用 WGS84 椭球计算距离,所以球面(Haversine)是不够的。 I think I could work with 1m accurracy.我想我可以以 1m 的精度工作。 Points are distributed randomly along paths.点沿路径随机分布。 Some can have 20 kilometers between them, and some have below 1 km.有些之间的距离可以达到 20 公里,有些则不到 1 公里。

Here is the path with points (decimal lat/lon):这是带点的路径(十进制纬度/经度):

[(49.009722, 2.547778), (49.015556, 2.573611), (49.021389, 2.599167), (49.039167, 2.676389), (49.048056, 2.715), (49.044444, 2.835), (49.041667, 2.928333), (49.042778, 2.942222), (49.051667, 3.066667), (49.061389, 3.205), (49.072222, 3.357222), (49.085, 3.536944), (49.086111, 3.550833), (49.097778, 3.729444), (49.113056, 3.963056), (49.130833, 4.238056), (49.138889, 4.361667), (49.1925, 4.564444), (49.306667, 4.995556), (49.333611, 5.096944), (49.395, 5.329167), (49.490556, 5.690833), (49.514444, 5.781111), (49.53, 5.845833), (49.599444, 6.127778), (49.637222, 6.281667), (49.673333, 6.440278), (50.0475, 8.078333), (50.053611, 8.637222), (50.056667, 8.800278), (50.063056, 9.19), (50.066944, 9.486389), (50.07, 9.783056), (50.072778, 10.098611), (50.073333, 10.242778), (50.075278, 10.728889), (50.046667, 10.863333), (50.0325, 10.930278), (49.981111, 11.172222), (49.969722, 11.225833), (49.961111, 11.491389), (49.959444, 11.547222), (49.957222, 11.617222), (49.946111, 11.9325), (49.937222, 12.343889), (49.933333, 12.47), (49.9325, 12.498056), (49.928611, 12.624167), (49.924167, 12.764444), (49.919444, 12.918611), (49.910833, 13.199167), (49.909444, 13.241111), (49.907778, 13.283611), (49.900556, 13.481944), (50.077222, 13.840278), (50.124167, 13.995556), (50.182778, 14.189722), (50.220278, 14.315), (50.268889, 14.478056), (50.211389, 14.403611), (50.166389, 14.345), (50.133611, 14.3025), (50.100833, 14.26)]

I have discovered cartopy - a package providing geodesic calculations that uses shapely and proj .我发现cartopy -包提供短程的计算方法,用途匀称凸出 However the docs on cartpopy do not give a relevent example and I am stuck at this point.然而,关于 cartpopy 的文档没有给出一个相关的例子,我在这一点上被卡住了。 Basically the geometry_length gives the length of a shapely object in one go, so I am doing it in the following way:基本上, geometry_length一次性给出了匀称对象的长度,因此我按以下方式进行操作:

#defining the geoid on which to make calculations
myGeod = geodesic.Geodesic(6378137.0,1 / 298.257223563)

#making my list of latlon (in decimal degrees) into a shapely 
shapelyObject = LineString(list(latlon_dd))

#applying the method on the shapelyObject given the defined ellipsoid
myGeod.geometry_length(shapelyObject)

I want to compute the length in meters, which should be around 917,315.3 meters.我想计算以米为单位的长度,应该是大约 917,315.3 米。 Instead, I get this ValueError:相反,我得到了这个 ValueError:

ValueError                                Traceback (most recent call last)
<ipython-input-243-7c75042775e3> in <module>
      6 
      7 #applying the method on the shapelyObject given the defined ellipsoid
----> 8 myGeod.geometry_length(shapelyObject)

lib\cartopy\geodesic\_geodesic.pyx in cartopy.geodesic._geodesic.Geodesic.geometry_length()

lib\cartopy\geodesic\_geodesic.pyx in cartopy.geodesic._geodesic.Geodesic.geometry_length()

lib\cartopy\geodesic\_geodesic.pyx in cartopy.geodesic._geodesic.Geodesic.inverse()

ValueError: Expecting input points to be (N, 2), got (1, 63)

Thanks in advance!提前致谢!

Going to answer my question based on the reply found here .将根据此处找到的答复回答我的问题。 Apparently it is a bug, and the current workaround is to use:显然这是一个错误,当前的解决方法是使用:

myGeod.geometry_length(np.array(shapelyObject.coords))

instead of代替

myGeod.geometry_length(shapelyObject)

Will update when a final solution is available.将在最终解决方案可用时更新。

You might not want to include another library, but LatLon has a built-in method for calculating WGS84 distance in km between two lat/lon points.您可能不想包含另一个库,但LatLon有一个内置方法来计算两个纬度/经度点之间的 WGS84 距离(以公里为单位)。

Example taken from the linked page:来自链接页面的示例:

>> palmyra = LatLon(Latitude(5.8833), Longitude(-162.0833)) # Location of Palmyra Atoll
>> honolulu = LatLon(Latitude(21.3), Longitude(-157.8167)) # Location of Honolulu, HI
>> distance = palmyra.distance(honolulu) # WGS84 distance in km
>> print distance
1766.69130376
>> print palmyra.distance(honolulu, ellipse = 'sphere') # FAI distance in km
1774.77188181

Edit: just noticed after posting that you wanted to calculate the distance of a path with many points not between two (at a time), sorry...编辑:在发布后才注意到您想计算一条路径的距离,其中许多点不在两个(一次)之间,对不起...

You can still use pyproj and solve the whole list at once您仍然可以使用 pyproj 并立即解决整个列表

geod = pyproj.Geod(ellps='WGS84')
_, _, distances_in_meters = geod.inv(
         lons1_float_or_list_or_numpy_array,
         lats1_float_or_list_or_numpy_array,
         lons2_float_or_list_or_numpy_array,
         lats2_float_or_list_or_numpy_array)

To get this format from what you gave, we can use 4 comprehensions and ittertools.combinations.为了从您提供的内容中获得这种格式,我们可以使用 4 个理解和 ittertools.combinations。

your_list = [(49.009722, 2.547778), (49.015556, 2.573611), ...]

edges = ittertools.combinations(your_list, 2)

lons1 = [edge[0][1], for edge in edges]
lats1 = [edge[0][0], for edge in edges]
lons2 = [edge[1][1], for edge in edges]
lats2 = [edge[1][0], for edge in edges]

如何在坐标(纬度,经度)中计算截然相反的坐标,其中-90 <lat<90 and -180<lon<180< div><div id="text_translate"><p> 给定坐标点 X=(lat, lon) 和圆心 C=(lat_center, lon_center) 我想计算点 X 截然相反的坐标(假设 X 在圆心为 C 的圆内) .</p><p> 例如,如果 C=(45.9, 180),则与 X=(45.9, -179) 截然相反的值应该是 (45.9, 179)。</p><p> 以下 function 是一个近似值,但不能解决纬度在 (-90, 90) 和经度 (-180, 180) 之间的问题。</p><pre> def f(lat, lon, center): lat_center = center[0] lon_center = center[1] dist_lon = np.abs(lon - lon_center) if np.abs(lon - lon_center)&lt;180 else 360 - np.abs(lon - lon_center) dist_lat = np.abs(lat - lat_center) if np.abs(lat - lat_center)&lt;180 else 360 - np.abs(lat - lat_center) lon_op = lon_center + dist_lon if lon_center + dist_lon.= lon else lon_center - dist_lon lat_op = lat_center + dist_lat if lat_center + dist_lat,= lat else lat_center - dist_lat return np,round(lat_op. 2), np.round(lon_op, 2)</pre> </div></lat<90> - How to calculate diametrically opposite in coordinates(lat, lon) where -90<lat<90 and -180<lon<180

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在python中使用经纬度数据计算最小距离 - How to calculate minimum distance using lat-lon data in python 如何找到经/纬/高点之间的3d距离? - How can I find 3d distance between lat/lon/alt points? 如何使用Python NLTK计算WordNet中两个形容词之间的最短路径(测地距离)? - How do I calculate the shortest path (geodesic) distance between two adjectives in WordNet using Python NLTK? 如何执行经纬度数据点的聚类 - How to perform clustering of lat/lon data points 减少拉特隆点 - reduce lat lon points 使用最大/最小纬度和经度以及网格点数,如何获得经纬度网格? - With max/min lat and lon and number of grid points, how to get lat/lon grid? 如何在坐标(纬度,经度)中计算截然相反的坐标,其中-90 <lat<90 and -180<lon<180< div><div id="text_translate"><p> 给定坐标点 X=(lat, lon) 和圆心 C=(lat_center, lon_center) 我想计算点 X 截然相反的坐标(假设 X 在圆心为 C 的圆内) .</p><p> 例如,如果 C=(45.9, 180),则与 X=(45.9, -179) 截然相反的值应该是 (45.9, 179)。</p><p> 以下 function 是一个近似值,但不能解决纬度在 (-90, 90) 和经度 (-180, 180) 之间的问题。</p><pre> def f(lat, lon, center): lat_center = center[0] lon_center = center[1] dist_lon = np.abs(lon - lon_center) if np.abs(lon - lon_center)&lt;180 else 360 - np.abs(lon - lon_center) dist_lat = np.abs(lat - lat_center) if np.abs(lat - lat_center)&lt;180 else 360 - np.abs(lat - lat_center) lon_op = lon_center + dist_lon if lon_center + dist_lon.= lon else lon_center - dist_lon lat_op = lat_center + dist_lat if lat_center + dist_lat,= lat else lat_center - dist_lat return np,round(lat_op. 2), np.round(lon_op, 2)</pre> </div></lat<90> - How to calculate diametrically opposite in coordinates(lat, lon) where -90<lat<90 and -180<lon<180 如何计算沿插值路径的均匀距离(Python2.7)? - How to calculate even distance along an interpolated path (Python2.7)? 根据纬度/经度计算密度 - Calculate Density based on Lat/Lon 如何使用 GeoPandas 将点的 GeoSeries 转换为元组(经纬度)列表 - How to convert a GeoSeries of points to a list of tuples (lat, lon) using GeoPandas
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM