时空接近


10

我有一些点数据,这些数据代表动物的每日经纬度位置以及相关的时间戳。

我想找出STATIONARY = TRUE的所有点。如果某个点周围100公里的缓冲区与其他(例如)5个时间相邻 点重叠,则该点为固定点。因此,如果第10天是我的关注点,那么我想问一下,在时间上相隔5天是否在该点的100公里范围内。如果第5、6、7、8和9天;或第11、12、13、14和15天;或第8、9、11、12、13天(等等)在缓冲区内,则STATIONARY = TRUE。但是,如果第5、7、9、11和13天在缓冲区内,但间隔之间不是隔天(偶数)天,则STATIONARY = FALSE

我认为某种移动窗口缓冲区将提供解决方案,但我不知道该如何实现。

我一直试图在ArcGIS和R中解决这个问题,但是到目前为止还没有脑筋。这是我最接近解决方案的方法,但是它并不适合,我不认为:标识指定缓冲区中的连续点

这是一些虚拟数据,近似于我的数据结构(尽管实际上我每天有两次位置(中午和午夜),但缺少一些位置-但稍后会担心)

x<-seq(0,15,length.out=20)
y<-seq(10,-10,length.out=20)
t<-seq(as.POSIXct('2013-07-01'), length.out = 20, by = "days")
data<-data.frame(cbind(x,y,t=as.data.frame.POSIXct(t)))


            x           y          t
1   0.0000000  10.0000000 2013-07-01
2   0.7894737   8.9473684 2013-07-02
3   1.5789474   7.8947368 2013-07-03
4   2.3684211   6.8421053 2013-07-04
5   3.1578947   5.7894737 2013-07-05
6   3.9473684   4.7368421 2013-07-06
7   4.7368421   3.6842105 2013-07-07
... ...         ...       ...

1
题?假设所有10个点都在缓冲区内,并且您的日期间隔(从第1天开始)为1-3-4-12-13-20-21-22-29-30,那么您是说您只对选择点感兴趣1,2,3,4&12天?
Hornbydd

不,我只会对1-4天感兴趣。如果动物“离开”缓冲区,然后在第12天(或第6天)返回,则将“取消”该静止期-即动物必须在第1-2-3-4-5天进入缓冲区要计算的缓冲区中心的点。合理?我不确定自己..
汤姆·芬奇2013年

1
仅检查一下,如果兴趣点是第7天,那么您会发现第7、8、9、10和11天的兴趣点在100公里之内?
Hornbydd

如果第8,9,10、11和12天超过100公里,则将选择第7点作为固定点。或第5、6、8、9、10天。因此,如果任何其他5个时间相邻点(前5天,后5天或任一侧的几天)都在缓冲区内,则选择任何一个点。我认为移动窗口是概念化窗口的最佳方法。对于每个“重点”点,可以忘记过去/未来超过5天的任何时间点。我可能会更新我的原始问题,因为我现在对此有了更多了解……
汤姆·芬奇2013年

数据的格式是什么?例如,您是否将每个时间/位置都作为shapefile中的向量点和用于存储时间的属性表?还是每个时间/位置分别存储在不同的shapefile中?数据甚至不是地理空间格式,而是Excel文件吗?知道这一点将有助于我们回答。

Answers:


12

让我们将其分解为简单的部分。这样,所有工作只需六行容易测试的代码即可完成。

首先,您需要计算距离。因为数据在地理坐标中,所以这里有一个函数来计算球形基准上的距离(使用Haversine公式):

#
# Spherical distance.
# `x` and `y` are (long, lat) pairs *in radians*.
dist <- function(x, y, R=1) {
  d <- y - x
  a <- sin(d[2]/2)^2 + cos(x[2])*cos(y[2])*sin(d[1]/2)^2
  return (R * 2*atan2(sqrt(a), sqrt(1-a)))
}

如果需要,可将其替换为您喜欢的实现(例如,使用椭圆形基准的实现)。

接下来,我们将需要计算每个“基点”(被检查是否具有同质性)与其时间邻域之间的距离。这仅仅是申请dist到附近的问题:

#
# Compute the distances between an array of locations and a base location `x`.
dist.array <- function(a, x, ...) apply(a, 1, function(y) dist(x, y, ...))

第三点-这是关键思想-静止点是通过检测连续至少有五个点的11个点的邻域来找到的,这些点的距离足够小。让我们通过确定布尔值逻辑数组中真值的最长子序列的长度来更一般地实现这一点:

#
# Return the length of the longest sequence of true values in `x`.
max.subsequence <- function(x) max(diff(c(0, which(!x), length(x)+1)))

(我们按顺序找到错误值的位置,并计算它们的差值:这是非错误值的子序列的长度。将返回最大的长度。)

第四,我们申请max.subsequence检测静止点。

#
# Determine whether a point `x` is "stationary" relative to a sequence of its
# neighbors `a`.  It is provided there is a sequence of at least `k`
# points in `a` within distance `radius` of `x`, where the earth's radius is
# set to `R`.
is.stationary <- function(x, a, k=floor(length(a)/2), radius=100, R=6378.137) 
  max.subsequence(dist.array(a, x, R) <= radius) >= k

这些就是我们需要的所有工具。


例如,让我们创建一些有趣的数据,其中包含一些固定点。我将在赤道附近随机漫步。

set.seed(17)
n <- 67
theta <- 0:(n-1) / 50 - 1 + rnorm(n, sd=1/2)
rho <- rgamma(n, 2, scale=1/2) * (1 + cos(1:n / n * 6 * pi))
lon <- cumsum(cos(theta) * rho); lat <- cumsum(sin(theta) * rho)

数组lonlat包含n顺序中点的坐标(以度为单位)。在首先转换为弧度后,应用我们的工具非常简单:

p <- cbind(lon, lat) * pi / 180 # Convert from degrees to radians
p.stationary <- sapply(1:n, function(i) 
  is.stationary(p[i,], p[max(1,i-5):min(n,i+5), ], k=5))

该论点p[max(1,i-5):min(n,i+5), ]说,从基点往后看5个时间步长或向前看5个时间步长p[i,]。包括k=5说要在距基准点100公里以内的位置连续查找5个或更多的序列。(将100 km的值设置为默认值,is.stationary但您可以在此处覆盖它。)

输出p.stationary是指示平稳性的逻辑向量:我们有自己的目标。但是,要检查该过程,最好是绘制数据和这些结果,而不是检查值的数组。在下图中,我显示了路线和点。每十分之一点都带有标签,以便您可以估计固定块中可能有多少重叠。固定点以红色重画以突出显示并被其100 km缓冲区包围。

数字

plot(p, type="l", asp=1, col="Gray", 
     xlab="Longitude (radians)", ylab="Latitude (radians)")
points(p)
points(p[p.stationary, ], pch=19, col="Red", cex=0.75)
i <- seq(1, n, by=10)
#
# Because we're near the Equator in this example, buffers will be nearly 
# circular: approximate them.
disk <- function(x, r, n=32) {
  theta <- 1:n / n * 2 * pi
  return (t(rbind(cos(theta), sin(theta))*r + x))
}
r <- 100 / 6378.137  # Buffer radius in radians
apply(p[p.stationary, ], 1, function(x) 
  invisible(polygon(disk(x, r), col="#ff000008", border="#00000040")))
text(p[i,], labels=paste(i), pos=3, offset=1.25, col="Gray")

有关在跟踪数据(包括工作代码)中查找静止点的其他(基于统计的)方法,请访问/mathematica/2711/clustering-of-space-time-data


哇谢谢!期待我能解决这个问题。再次感谢您的时间和精力
Tom Finch
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.