-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathiterationsSpeedFilter.R
129 lines (118 loc) · 3.94 KB
/
iterationsSpeedFilter.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
extra.speedfilter <- function (x, max.speed = NULL, test = FALSE)
{
extrares <- list()
if (!is(x, "trip"))
stop("only trip objects supported")
projected <- is.projected(x)
if (is.na(projected)) {
projected <- FALSE
warning("coordinate system is NA, assuming longlat . . .")
}
FUN <- function(x, aadBUG = FALSE) {
sqrt(sum((x)^2, na.rm = FALSE)/(if (aadBUG) 1 else length(x)))
}
if (is.null(max.speed)) {
print("no max.speed given, nothing to do here")
return(x)
}
longlat <- !projected
coords <- coordinates(x)
time = x[[[email protected][1]]]
id = factor(x[[[email protected][2]]])
x <- coords[, 1]
y <- coords[, 2]
aadBUG = FALSE
pprm <- 3
grps <- levels(id)
if (length(x) != length(y))
stop("x and y vectors must be of same\nlength")
if (length(x) != length(time))
stop("Length of times not equal to number of points")
okFULL <- NULL
if (test)
res <- list(speed = numeric(0), rms = numeric(0))
for (sub in grps) {
ind <- id == sub
xy <- matrix(c(x[ind], y[ind]), ncol = 2)
tms <- time[ind]
npts <- nrow(xy)
if (pprm%%2 == 0 || pprm < 3)
stop("Points per running mean should be odd and greater than 3, pprm = 3")
RMS <- rep(max.speed + 1, npts)
offset <- pprm - 1
ok <- rep(TRUE, npts)
if (npts < (pprm + 1)) {
warning("Not enough points to filter ID: \"", sub,
"\"\n continuing . . . \n")
okFULL <- c(okFULL, ok)
next
}
index <- 1:npts
iter <- 1
while (any(RMS > max.speed, na.rm = TRUE)) {
n <- length(which(ok))
speed1 <- OLDtrackDistance(xy[ok, ], longlat = longlat)/(diff(unclass(tms[ok]))/3600)
speed2 <- OLDtrackDistance(xy[ok, ], longlat = longlat,
push = 2)/((unclass(tms[ok][-c(1, 2)]) - unclass(tms[ok][-c(n -
1, n)]))/3600)
thisIndex <- index[ok]
npts <- length(speed1)
if (npts < pprm) {
next
}
sub1 <- rep(1:2, npts - offset) + rep(1:(npts - offset),
each = 2)
sub2 <- rep(c(0, 2), npts - offset) + rep(1:(npts -
offset), each = 2)
rmsRows <- cbind(matrix(speed1[sub1], ncol = offset,
byrow = TRUE), matrix(speed2[sub2], ncol = offset,
byrow = TRUE))
RMS <- c(rep(0, offset), apply(rmsRows, 1, FUN, aadBUG = aadBUG))
if (iter == 1) rms <- RMS
if (test & iter == 1) {
res$speed <- c(res$speed, 0, speed1)
res$rms <- c(res$rms, 0, RMS)
break
}
iter <- iter + 1
bad <- RMS > max.speed
bad[is.na(bad)] <- FALSE
segs <- cumsum(c(0, abs(diff(bad))))
segs[RMS <= max.speed] <- NA
peaks <- tapply(RMS, segs, which.max)
for (i in levels(as.factor(segs))) {
RMS[segs == i & !is.na(segs)][peaks[[i]]] <- NA
}
RMS[1] <- 0
RMS[length(RMS)] <- 0
rms[thisIndex] <- c(0, RMS)
rms[-thisIndex] <- 0
extrares[[iter]] <- rms
ok[thisIndex][is.na(RMS)] <- FALSE
}
okFULL <- c(okFULL, ok)
}
if (test)
return(res)
filt <- okFULL
filt
return(extrares)
}
OLDtrackDistance <-
function (track, longlat = FALSE, push = 1)
{
#print(longlat)
#track <- coordinates(spData)
if (!is.matrix(track))
stop("track must be two-column matrix")
if (ncol(track) != 2)
stop("track must be two-column matrix")
n1 <- nrow(track) - 1
if (n1 < 1)
stop("less than two points")
res <- numeric(n1 - push + 1)
for (i in seq(along = res))
res[i] <- spDistsN1(track[i,,drop = FALSE],
track[(i + push),,drop = FALSE ], longlat = longlat)
res
}