给定点、方位和距离计算GPS坐标

5 投票
3 回答
14575 浏览
提问于 2025-04-16 09:02

我在某个项目中遇到了一个问题,已经困扰我一段时间了。

我基本上想要用我写的脚本生成的一些点(x, y坐标)来圈住一个多边形。这里的lat和lon是多边形中心的GPS坐标,我想找出它周围的多边形。

这是我在Python中的一部分代码:

def getcords(lat, lon, dr, bearing):
    lat2=asin(sin(lat)*cos(dr)+cos(lat)*sin(dr)*cos(bearing))
    lon2=lon+atan2(sin(bearing)*sin(dr)*cos(lat),cos(dr)-sin(lat)*sin(lat2))
    return [lat2,lon2]

我的输入是这样的:

  • lat和lon - 是以小数度表示的。
  • dr - 是通过将距离(以英里为单位)除以地球半径(=3958.82)计算出来的角度。
  • bearing - 角度范围在0到360度之间。

但是对于输入:

getcorsds1(42.189275, -76.85823, 0.5/3958.82, 30)

我得到的输出是: [-1.3485899508698462, -76.8576637627568],而正确的答案是 [42.2516666666667, -76.8097222222222]

至于角度距离,我是通过将距离(以英里为单位)除以地球半径(=3958.82)来简单计算的。

有人能帮忙吗?

3 个回答

3

sin和cos函数需要的参数是弧度,而不是角度。asin和atan2函数的结果也是弧度,而不是角度。一般来说,你需要把输入的角度(lat1、lon1和bearing)从角度转换成弧度,可以用math.radians()这个函数;而输出的角度(lat2和lon2)则需要从弧度转换成角度,可以用math.degrees()这个函数。

另外,你的代码还有两个其他问题:

(1) 它没有考虑到跨越180度经线的情况;你需要限制你的答案,使得 -180 <= longitude_degrees <= +180。

(2) 如果你打算频繁使用这个函数,可能需要去掉一些多余的计算:sin(lat1)、cos(dr)、cos(lat1)和sin(dr)这些值每个都计算了两次。

5

使用 geopy v2.0.0(单位是公里而不是英里)

from geopy import Point                                                                                                                                                                       
from geopy.distance import geodesic                                                                                                                                                           
                                                                                                                                                                                              
distKm = 1                                                                                                                                                                                    
lat1 = 35.68096477080332                                                                                                                                                                      
lon1 = 139.76720809936523                                                                                                                                                                     
                                                                                                                                                                                              
print('center', lat1, lon1)                                                                                                                                                                   
print('north', geodesic(kilometers=distKm).destination(Point(lat1, lon1), 0).format_decimal())                                                                                                
print('east', geodesic(kilometers=distKm).destination(Point(lat1, lon1), 90).format_decimal())                                                                                                
print('south', geodesic(kilometers=distKm).destination(Point(lat1, lon1), 180).format_decimal())                                                                                              
print('west', geodesic(kilometers=distKm).destination(Point(lat1, lon1), 270).format_decimal()) 

结果是

center 35.6809647708 139.767208099
north 35.6899775841, 139.767208099
east 35.680964264, 139.778254714
south 35.6719519439, 139.767208099
west 35.680964264, 139.756161485
4

你为什么不使用一些很不错的库呢?

from geopy import Point
from geopy.distance import distance, VincentyDistance

# given: lat1, lon1, bearing, distMiles
lat2, lon2 = VincentyDistance(miles=distMiles).destination(Point(lat1, lon1), bearing)

比如说,给定的参数是纬度42.189275、经度-76.85823、距离0.5英里和方向30度,它会返回新的纬度42.1955489和经度-76.853359。

撰写回答