与在线工具和 Google 地图相比,为什么我的 Python 半正弦距离计算是错误的?
Why is my Python haversine distance calculation wrong compared to online tools and Google Maps?
我正在 Python 中编写一个 haversine 距离和角度计算器,作为小型自主 RC 汽车项目的一部分。我的两个测试位置是 38.63594444444444,-90.2315
和 38.63594444444444,-90.23211111111111
.
大多数在线计算器(以及我自己的个人 TI-89)得到的距离大约为 0.05308 公里。但是,我的 Python 函数的距离为 0.06795 公里。那是大约 15 米的距离,对于一辆小型遥控车来说,这是巨大的。
我的轴承计算函数 points2angle
一直失败,直到我在我的 toDegrees
函数中进行了一些浮动转换。整数除法把我搞砸了。
请注意,我的 points2angle
和 points2distance
函数需要一个元组(度、分、秒)。两个测试位置是 (38, 38, 9.4), (-90, 13, 53.4)
和 (38, 38, 9.4), (-90, 13, 55.6)
格式。
编辑: 感谢 MSeifert。我只是把我的纬度和经度搞混了。我在下面修复了我的 points2angle
代码,但在我的 points2distance
代码中留下了错误,所以我的错误代码和答案之间的区别仍然很清楚。
我的距离计算(返回错误的距离):
def points2distance(start, end):
start_long = math.radians(toDegrees(start[0]))
start_latt = math.radians(toDegrees(start[1]))
end_long = math.radians(toDegrees(end[0]))
end_latt = math.radians(toDegrees(end[1]))
d_latt = float(end_latt - start_latt)
d_long = float(end_long - start_long)
a = (math.sin(d_latt/2)**2) + math.cos(start_latt) * math.cos(end_latt)* (math.sin(d_long/2)**2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
return 6371 * c
我的十进制度数转换函数(有效):
def toDegrees(coord):
degrees = float(math.fabs(coord[0])) + float(coord[1]/60) + float(coord[2]/3600)
if coord[0] < 0:
degrees = degrees*-1
return degrees
我的方位角计算(工作):
def points2angle(start, end):
start_long = math.radians(toDegrees(start[1]))
start_latt = math.radians(toDegrees(start[0]))
end_long = math.radians(toDegrees(end[1]))
end_latt = math.radians(toDegrees(end[0]))
d_latt = end_latt - start_latt
d_long = end_long - start_long
y = math.sin(d_long)*math.sin(end_latt)
x = (math.cos(start_latt)*math.sin(end_latt)) - (math.sin(start_latt)*math.cos(end_latt)*math.cos(d_long))
brng = math.degrees(math.atan2(y,x))
compBear = (brng+360) % 360;
return compBear
你的经度和纬度混淆了,只需交换它们(或者如果它们在参数中被交换然后在那里交换它们)并且它有效:
def points2distance(start, end):
start_long = math.radians(toDegrees(start[1]))
start_latt = math.radians(toDegrees(start[0]))
end_long = math.radians(toDegrees(end[1]))
end_latt = math.radians(toDegrees(end[0]))
d_latt = float(end_latt - start_latt)
d_long = float(end_long - start_long)
a = (math.sin(d_latt/2)**2) + math.cos(start_latt) * math.cos(end_latt)* (math.sin(d_long/2)**2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
return 6371 * c
points2distance([(38, 38, 9.4), (-90, 13, 53.4)], [(38, 38, 9.4), (-90, 13, 55.6)])
# returns: 0.053079628495340196
我正在 Python 中编写一个 haversine 距离和角度计算器,作为小型自主 RC 汽车项目的一部分。我的两个测试位置是 38.63594444444444,-90.2315
和 38.63594444444444,-90.23211111111111
.
大多数在线计算器(以及我自己的个人 TI-89)得到的距离大约为 0.05308 公里。但是,我的 Python 函数的距离为 0.06795 公里。那是大约 15 米的距离,对于一辆小型遥控车来说,这是巨大的。
我的轴承计算函数 points2angle
一直失败,直到我在我的 toDegrees
函数中进行了一些浮动转换。整数除法把我搞砸了。
请注意,我的 points2angle
和 points2distance
函数需要一个元组(度、分、秒)。两个测试位置是 (38, 38, 9.4), (-90, 13, 53.4)
和 (38, 38, 9.4), (-90, 13, 55.6)
格式。
编辑: 感谢 MSeifert。我只是把我的纬度和经度搞混了。我在下面修复了我的 points2angle
代码,但在我的 points2distance
代码中留下了错误,所以我的错误代码和答案之间的区别仍然很清楚。
我的距离计算(返回错误的距离):
def points2distance(start, end):
start_long = math.radians(toDegrees(start[0]))
start_latt = math.radians(toDegrees(start[1]))
end_long = math.radians(toDegrees(end[0]))
end_latt = math.radians(toDegrees(end[1]))
d_latt = float(end_latt - start_latt)
d_long = float(end_long - start_long)
a = (math.sin(d_latt/2)**2) + math.cos(start_latt) * math.cos(end_latt)* (math.sin(d_long/2)**2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
return 6371 * c
我的十进制度数转换函数(有效):
def toDegrees(coord):
degrees = float(math.fabs(coord[0])) + float(coord[1]/60) + float(coord[2]/3600)
if coord[0] < 0:
degrees = degrees*-1
return degrees
我的方位角计算(工作):
def points2angle(start, end):
start_long = math.radians(toDegrees(start[1]))
start_latt = math.radians(toDegrees(start[0]))
end_long = math.radians(toDegrees(end[1]))
end_latt = math.radians(toDegrees(end[0]))
d_latt = end_latt - start_latt
d_long = end_long - start_long
y = math.sin(d_long)*math.sin(end_latt)
x = (math.cos(start_latt)*math.sin(end_latt)) - (math.sin(start_latt)*math.cos(end_latt)*math.cos(d_long))
brng = math.degrees(math.atan2(y,x))
compBear = (brng+360) % 360;
return compBear
你的经度和纬度混淆了,只需交换它们(或者如果它们在参数中被交换然后在那里交换它们)并且它有效:
def points2distance(start, end):
start_long = math.radians(toDegrees(start[1]))
start_latt = math.radians(toDegrees(start[0]))
end_long = math.radians(toDegrees(end[1]))
end_latt = math.radians(toDegrees(end[0]))
d_latt = float(end_latt - start_latt)
d_long = float(end_long - start_long)
a = (math.sin(d_latt/2)**2) + math.cos(start_latt) * math.cos(end_latt)* (math.sin(d_long/2)**2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
return 6371 * c
points2distance([(38, 38, 9.4), (-90, 13, 53.4)], [(38, 38, 9.4), (-90, 13, 55.6)])
# returns: 0.053079628495340196