【发布时间】:2020-07-05 11:39:40
【问题描述】:
我想从中间站计算两个站(前后)之间的距离。每个站都有一个 GPS 位置。例如:
P1 20.2 70
P2 21 70.3
P3 21.5 70.4
P4 22 71
P5 22.75 71.6
P6 23 72
P7 23.2 72.4
P8 24 73.3
P9 24.5 74
P10 25.1 74.3
这里第 1 列中的每个 P 是特定站点的站点名称,并分别在第 2 列和第 3 列中具有纬度和经度位置。
我想计算每个站点与其前面和后面的距离,即
For P2 what is the distance between P1 and P3 in KM?
For P3 What is the distance between P2 and P4 in KM?
For P4 what is the distance between P3 and P5 in KM?
........
........
For P9 what is the distance between P8 and P10 in KM?
所需的输出如下所示:
P2 149.62
P3 134.27
P4 190.60
P5 155.56
P6 100.97
P7 180.41
P8 226.77
P9 163.53
我使用以下公式计算了距离,但我不确定在基于 GPS 的位置中使用它是否正确。
d = sqrt(pow(lat2-lat1, 2) + pow(lon2-lon1, 2))
我正在为上述内容编写awk 代码,但遇到了问题。 Karafa(见答案)根据我的要求帮助编写了awk 脚本。这是
awk ' {k[NR] = $1
a[NR] = $2
b[NR] = $3}
END {for(i=2; i<NR; i++)
print k[i], (sqrt((a[i+1]-a[i-1])^2 + (b[i+1]-b[i-1])^2))*110}' file.txt
它工作得非常好,但是,在得到 Dawg 的评论(见 cmets)后,我意识到 Haversine 公式将是正确的方法,我从这里 https://rosettacode.org/wiki/Haversine_formula#AWK 处理。
# syntax: GAWK -f HAVERSINE_FORMULA.AWK
# converted from Python
BEGIN {
distance(36.12,-86.67,33.94,-118.40) # BNA to LAX
exit(0)
}
function distance(lat1,lon1,lat2,lon2, a,c,dlat,dlon) {
dlat = radians(lat2-lat1)
dlon = radians(lon2-lon1)
lat1 = radians(lat1)
lat2 = radians(lat2)
a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
c = 2 * atan2(sqrt(a),sqrt(1-a))
printf("distance: %.4f km\n",6372.8 * c)
}
function radians(degree) { # degrees to radians
return degree * (3.1415926 / 180.)
}
现在我想用上面的 Haversine 公式更新解决方案。我这样做如下,但遇到很多语法错误:
awk ' {k[NR] = $1
a[NR] = $2
b[NR] = $3}
END {for(i=2; i<NR; i++)
function distance(a[i-1],b[i-1],a[i+1],b[i+1], a,c,dlat,dlon) {
dlat = radians(a[i+1]-a[i-1])
dlon = radians(b[i+1]-b[i-1])
lat1 = radians(a[i-1])
lat2 = radians(a[i+1])
a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
c = 2 * atan2(sqrt(a),sqrt(1-a))
#printf("distance: %.4f km\n",6372.8 * c) #I have disabled it
}
function radians(degree) { # degrees to radians
return degree * (3.1415926 / 180.)
}
print k[i], 6372.8 * c}' file.txt
【问题讨论】:
-
在
END块中,您引用 $1,它是最后一行的第一个字段,因为它是 END 块! -
函数
pow()在awk中不存在。现有功能在此处列出:gnu.org/software/gawk/manual/html_node/Arithmetic-Ops.html -
您可以使用Haversine Formula 计算给定纬度/经度对之间的大圆距离。 HERE 是
awk的实现。 -
@dawg 距离是为 P1-P3 计算的。它匹配 150 公里。