首页 > 解决方案 > 计算经纬度坐标与移动动物之间的角度

问题描述

我想弄清楚图表上的绿色和黄色角度是什么。红线是动物 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

标签: rgpsangle

解决方案


这是我的解决方案,基于您提供的矩阵的简化版本。归功于@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 的值,尽管我不知道这在实践中是否有意义,因为我没有任何领域知识可以让我了解在此设置中可能的角度。


推荐阅读