r - 计算经纬度坐标与移动动物之间的角度
问题描述
我想弄清楚图表上的绿色和黄色角度是什么。红线是动物 1 的运动,每个编号的点代表它在每个时间点的位置(数据中的 rowid)。A3 表示动物 1 在点 2 时动物 3 的位置。
要计算橙色角度,我想我需要计算出黑色绘制的角度,然后减去黑色角度 180°,但我也不知道如何计算。
我想为数据中的每个时间点解决这个问题,我在下面包含了一个示例。在某些情况下,我没有动物 3 的位置,这很好,角度可以是 NA。我已经包含了 2 个图表来显示可能发生的不同情况。crs = 4326。非常感谢任何帮助!
rowid,id,t_,lon,lat,Animal3.lon,Animal3 .lat
1,Animal 1,01/01/2017 06:19,-9.95545,3.777097,#N/A,#N/A
2,Animal 1,01/01/2017 08:45,-9.93917,3.774998,-9.95192,3.789981
3,Animal 1,01/01/2017 16:34,-9.94561,3.779115,-9.94959,3.783688
4,Animal 1,01/02/2017 08:18,-9.94575,3.784986,-9.94617,3.798219
5,Animal 1,01/02/2017 15:57,-9.94198,3.794307,-9.94861,3.802043
6,Animal 1,01/03/2017 07:24,-9.9353,3.783469,-9.9472,3.795541
7,Animal 1,01/03/2017 17:44,-9.93446,3.775781,-9.93526,3.81313
8,Animal 1,01/03/2017 19:33,-9.94091,3.773766,#N/A,#N/A
9,Animal 1,01/04/2017 06:33,-9.93553,3.775065,-9.93203,3.799718
10,Animal 1,01/04/2017 17:01,-9.93588,3.779135,-9.93348,3.796017
11,Animal 1,01/05/2017 08:43,-9.92929,3.774276,-9.93471,3.794776
12,Animal 1,01/05/2017 16:43,-9.92989,3.778653,-9.93755,3.803964
解决方案
这是我的解决方案,基于您提供的矩阵的简化版本。归功于@mdsummer 的功能——在这里——我只是稍微修改了一下。
library(tidyverse)
library(maptools)
library(sf)
# Function - get angle from set of three points
trackAngle <- function(xy) {
if(any(is.na(xy))){return(NA)}
angles <- abs(c(trackAzimuth(xy), 0) -
c(0, rev(trackAzimuth(xy[nrow(xy):1, ]))))
angles <- ifelse(angles > 180, 360 - angles, angles)
angles[is.na(angles)] <- 180
angles[-c(1, length(angles))]
}
# Original Matrix
animal_mat <- t(matrix(c(-9.95545,3.777097,NA, NA,
-9.93917,3.774998,-9.95192,3.789981,
-9.94561,3.779115,-9.94959,3.783688,
-9.94575,3.784986,-9.94617,3.798219,
-9.94198,3.794307,-9.94861,3.802043,
-9.9353,3.783469,-9.9472,3.795541,
-9.93446,3.775781,-9.93526,3.81313,
-9.94091,3.773766,NA, NA,
-9.93553,3.775065,-9.93203,3.799718,
-9.93588,3.779135,-9.93348,3.796017,
-9.92929,3.774276,-9.93471,3.794776,
-9.92989,3.778653,-9.93755,3.803964), 4, 12))
## Reformat to get lists of points
# Other animal angles
animal_pts1 <- map(2:nrow(animal_mat), function(idx){
animal_pt <- unname(animal_mat[idx,][c(1,2)])
other_pt <- unname(animal_mat[idx,][c(3,4)])
animal_last_pt <- unname(animal_mat[idx-1,][c(1,2)])
animal_pts_mat <- rbind(animal_last_pt, animal_pt, other_pt)
animal_pts_mat
})
# Main animal angles
animal_pts2 <- map(2:(nrow(animal_mat)-1), function(idx){
animal_pt <- unname(animal_mat[idx,][c(1,2)])
animal_last_pt <- unname(animal_mat[idx-1,][c(1,2)])
animal_next_pt <- unname(animal_mat[idx+1,][c(1,2)])
animal_pts_mat <- rbind(animal_last_pt, animal_pt, animal_next_pt)
animal_pts_mat
})
## Angles
# Other animal angles (11)
other_animal_angles <- 180 - map(animal_pts1, ~trackAngle(.x)) %>% unlist
# Main animal angles (10)
main_animal_angles <- 180 - map(animal_pts2, ~trackAngle(.x)) %>% unlist
## Combining angles info
angles_tbl <- tibble(main = main_animal_angles, other = other_animal_angles[1:10])
## Final dataframe
angles_tbl %>% mutate(tot = main+other)
# A tibble: 10 x 3
main other tot
<dbl> <dbl> <dbl>
1 155. 138. 292.
2 56.0 16.4 72.4
3 23.3 0.451 23.8
4 126. 62.5 189.
5 25.4 167. 192.
6 78.8 175. 254.
7 176. NA NA
8 81.3 68.3 150.
9 131. 13.0 144.
10 134. 141. 275.
请注意,使用此解决方案您得到的角度大于 180,因此这里可能有问题(CRS 可能吗?)。从技术上讲,可以获得大于 180 的值,尽管我不知道这在实践中是否有意义,因为我没有任何领域知识可以让我了解在此设置中可能的角度。
推荐阅读
- flutter - 如何在 Flutter 应用程序中手动清除提供程序的当前状态?
- python - 具有多字段过滤的 Django 搜索栏实现
- javascript - 如何在 JavaScript 中正确比较数字
- retrofit - 带有房间和作业调度器的匕首柄
- javascript - amCharts 5:可以在同一画布上堆叠多个图表并在它们之间共享 xAxis
- java - 暂停和恢复线程的问题
- python - Python - 用多波束数据填充单波束缺失的探测范围
- python - 使用 tf.train.Checkpoint 在 keras 中保存 GAN
- python - Python中用于非平方成本矩阵的匈牙利算法
- java - 我是否需要在 Mongo 的这个 POST 请求中进行事务处理?