在给定起始坐标、方位和距离的情况下查找目的地坐标
Find destination coordinates given starting coordinates, bearing, and distance
I'm looking at the formula listed here: http://www.movable-type.co.uk/scripts/latlong.html
我似乎遇到了麻烦,因为生成的坐标不是我期望的那样。
鉴于以下信息:
起始纬度:28.455556
开始经度:-80.527778
方位:317.662819(度)
距离:130.224835(海里)
def getEndpoint(lat1,lon1,bearing,d):
R = 6378.1 #Radius of the Earth
brng = math.radians(bearing) #convert degrees to radians
d = d*1.852 #convert nautical miles to km
lat2 = math.asin( math.sin(lat1)*math.cos(d/R) + math.cos(lat1)*math.sin(d/R)*math.cos(brng))
lon2 = lon1 + math.atan2(math.sin(brng)*math.sin(d/R)*math.cos(lat1),math.cos(d/R)-math.sin(lat1)*math.sin(lat2))
return lat2,lon2
函数returns:
结束纬度:-0.209110644042
结束经度:-80.5017472335
但这是我起始位置以东的坐标,没有任何意义,因为 317 方位角指向我起始位置的西北。
上图是最终结束坐标在左上角的样子
哪里出错了?
另请注意,您的纬度正好在赤道南。我怀疑您的问题是坐标系:三角函数通常在笛卡尔坐标系中工作:参考角(方位角 0)是 +x 轴,也称为 "due east",并向 +y(逆时针方向)前进。罗盘航向从北开始,顺时针方向。
替换 1:
brng = math.radians(90-bearing) #convert degrees to radians
您还没有使用您的起始纬度。尝试:
lat2 = lat1 + math.asin(...
这给了我们
的最终位置
(28.246445355975514, -80.50284677329569)
math.sin(x)
... Return x 弧度的正弦。
因此,您需要先将 lat1 和 lon1 转换为弧度,然后再将 lat2 和 lon2 转换回度数。
我忘了先转换为弧度,然后在计算完成后再转换回度数。这是最终代码:
def getEndpoint(lat1,lon1,bearing,d):
R = 6371 #Radius of the Earth
brng = math.radians(bearing) #convert degrees to radians
d = d*1.852 #convert nautical miles to km
lat1 = math.radians(lat1) #Current lat point converted to radians
lon1 = math.radians(lon1) #Current long point converted to radians
lat2 = math.asin( math.sin(lat1)*math.cos(d/R) + math.cos(lat1)*math.sin(d/R)*math.cos(brng))
lon2 = lon1 + math.atan2(math.sin(brng)*math.sin(d/R)*math.cos(lat1),math.cos(d/R)-math.sin(lat1)*math.sin(lat2))
lat2 = math.degrees(lat2)
lon2 = math.degrees(lon2)
return lat2,lon2
如果您想要高精度结果,请考虑使用 geodesics。这是 GeographicLib 的示例,它使用 angular 度数单位和米数距离单位。
from geographiclib.constants import Constants
from geographiclib.geodesic import Geodesic
def getEndpoint(lat1, lon1, bearing, d):
geod = Geodesic(Constants.WGS84_a, Constants.WGS84_f)
d = geod.Direct(lat1, lon1, bearing, d * 1852.0)
return d['lat2'], d['lon2']
print(getEndpoint(28.455556, -80.527778, 317.662819, 130.224835))
# (30.05352669918092, -82.21197985232848)
这应该与确切位置相差不超过几纳米。
我似乎遇到了麻烦,因为生成的坐标不是我期望的那样。
鉴于以下信息:
起始纬度:28.455556
开始经度:-80.527778
方位:317.662819(度)
距离:130.224835(海里)
def getEndpoint(lat1,lon1,bearing,d):
R = 6378.1 #Radius of the Earth
brng = math.radians(bearing) #convert degrees to radians
d = d*1.852 #convert nautical miles to km
lat2 = math.asin( math.sin(lat1)*math.cos(d/R) + math.cos(lat1)*math.sin(d/R)*math.cos(brng))
lon2 = lon1 + math.atan2(math.sin(brng)*math.sin(d/R)*math.cos(lat1),math.cos(d/R)-math.sin(lat1)*math.sin(lat2))
return lat2,lon2
函数returns:
结束纬度:-0.209110644042
结束经度:-80.5017472335
但这是我起始位置以东的坐标,没有任何意义,因为 317 方位角指向我起始位置的西北。
上图是最终结束坐标在左上角的样子
哪里出错了?
另请注意,您的纬度正好在赤道南。我怀疑您的问题是坐标系:三角函数通常在笛卡尔坐标系中工作:参考角(方位角 0)是 +x 轴,也称为 "due east",并向 +y(逆时针方向)前进。罗盘航向从北开始,顺时针方向。
替换 1:
brng = math.radians(90-bearing) #convert degrees to radians
您还没有使用您的起始纬度。尝试:
lat2 = lat1 + math.asin(...
这给了我们
的最终位置(28.246445355975514, -80.50284677329569)
math.sin(x)
... Return x 弧度的正弦。
因此,您需要先将 lat1 和 lon1 转换为弧度,然后再将 lat2 和 lon2 转换回度数。
我忘了先转换为弧度,然后在计算完成后再转换回度数。这是最终代码:
def getEndpoint(lat1,lon1,bearing,d):
R = 6371 #Radius of the Earth
brng = math.radians(bearing) #convert degrees to radians
d = d*1.852 #convert nautical miles to km
lat1 = math.radians(lat1) #Current lat point converted to radians
lon1 = math.radians(lon1) #Current long point converted to radians
lat2 = math.asin( math.sin(lat1)*math.cos(d/R) + math.cos(lat1)*math.sin(d/R)*math.cos(brng))
lon2 = lon1 + math.atan2(math.sin(brng)*math.sin(d/R)*math.cos(lat1),math.cos(d/R)-math.sin(lat1)*math.sin(lat2))
lat2 = math.degrees(lat2)
lon2 = math.degrees(lon2)
return lat2,lon2
如果您想要高精度结果,请考虑使用 geodesics。这是 GeographicLib 的示例,它使用 angular 度数单位和米数距离单位。
from geographiclib.constants import Constants
from geographiclib.geodesic import Geodesic
def getEndpoint(lat1, lon1, bearing, d):
geod = Geodesic(Constants.WGS84_a, Constants.WGS84_f)
d = geod.Direct(lat1, lon1, bearing, d * 1852.0)
return d['lat2'], d['lon2']
print(getEndpoint(28.455556, -80.527778, 317.662819, 130.224835))
# (30.05352669918092, -82.21197985232848)
这应该与确切位置相差不超过几纳米。