将纬度,经度转换为距离赤道的公里数,并将其转换为最接近的公里数

时间:2017-03-08 13:46:33

标签: python google-maps coordinates latitude-longitude pyproj

对于我所拥有的每个坐标,我发现距赤道的距离以千米为单位给出了两个距离:

from pyproj import Geod
wgs84_geod = Geod(ellps='WGS84')    
_,_, lon_dist = wgs84_geod.inv(0, 0,lon, 0)
_,_, lat_dist = wgs84_geod.inv(0, 0,0, lat)

作为一个完整性检查,我可以从这些值重新计算原始坐标,如下所示(假设赤道坐标(0,0)的方向是北和西:

_, new_lat, _ = wgs84_geod.fwd(0,0, 0, lat_dist)
new_lon, _, _ = wgs84_geod.fwd(0, 0, 90, lon_dist)

这让我回到了我开始时的相同坐标。

现在我想找到离坐标最近的公里点。我将lon_dist和lat_dist从赤道值转到几公里。

lat_km_dist = round(lat_dist/1000)*1000 #to nearest km and back to meters
lon_km_dist = round(lon_dist/1000)*1000 

我以与之前相同的方式使用这些距离获得坐标

_, km_lat, _ = wgs84_geod.fwd(0,0, 0, lat_km_dist)
km_lon, _, _ = wgs84_geod.fwd(0, 0, 90, lon_km_dist)

逻辑应该是对于同一区域内的多个坐标,任何km_lat,km_lon对之间的最近距离应为1km。 这在北/南轴上是正确的,但对于经度,距离根据我在哪个纬度而变化。 我附上了两个屏幕截图来显示问题,其中km_lat,km_lon坐标由多边形中心的黑色圆圈表示,面积为1km。

我该如何纠正?

Copenhagen

San Francisco

1 个答案:

答案 0 :(得分:1)

这个算法基本上做的是它在赤道(lat = 0)和主子午线(lon = 0)上构造一个等距网格(相距1km的点)。然后它有效地构造椭球上的网格作为这些点的笛卡尔积。

然而,纬度/经度坐标不形成笛卡尔坐标系,由这些网格点生成的平行/经线定义“正方形”,其大小不仅取决于特定的经度,还取决于纬度。在一个完美的球体上,这将在南北方向上起作用,因为在纬度上,等于(在大圆距离方面)lon = 0的网格也是等距的(纬度差异等于距离的差异)球体的半径)。

换句话说,如果您修复两个纬度lat1lat2并且特定经度lon(lat1, lon)移动,(lat2, lon)移动1公里,比如说,向西方向,然后这些新获得的点将不会有相同的经度......

我不完全确定你想要达到的目标,但如果目标是获得一些彼此不太接近的代表点,那么就大圆距离来说,hierarchical clustering可能会提供合理的结果...

编辑:

作为一种近似的解决方法,您最有可能选择另一个参考点而不是(0, 0) - 新的参考点不应该离您想要描述的区域太远(类似于感兴趣区域的“左下角”)。如果整个感兴趣的区域不覆盖全球的大部分区域(大跨度纬度),那么差异将非常小,因此它们可能在GoogleMaps可视化中几乎不可见......

因此,如果您对丹麦感兴趣(通过屏幕截图判断),那么以下内容可能会有效:

lat_ref, lon_ref = 53.637976, 6.694138

_,_, lon_dist = wgs84_geod.inv(lon_ref,lat_ref, lon, 0)
_,_, lat_dist = wgs84_geod.inv(lon_ref,lat_ref, 0, lat)

lat_km_dist = round(lat_dist/1000)*1000 #to nearest km and back to meters
lon_km_dist = round(lon_dist/1000)*1000


_, km_lat, _ = wgs84_geod.fwd(lon_ref,lat_ref,  0, lat_km_dist)
km_lon, _, _ = wgs84_geod.fwd(lon_ref,lat_ref, 90, lon_km_dist)