Select a subset of fixes spaced by cumulative along-track distance,
returning the move2 object whole with a logical column
thin_selected marking retained fixes. Two methods are offered:
Arguments
- x
A
move2object.- distance
The target along-track distance step, in metres. Accepts a numeric scalar or a
unitsobject convertible to metres (e.g.units::set_units(0.5, "km")).- tolerance
Half-width of the acceptance window around
distance, in metres. Used only bymethod = "interval"; ignored (with a warning if set) bymethod = "step". Defaults todistance / 10.- criterion
Tie-breaking rule for
method = "interval"when multiple chains of equal length exist:"closest"(minimum total deviation from the target, default) or"first"(earliest-starting chain). Ignored bymethod = "step".- method
Thinning rule:
"step"(default, greedy minimum-spacing) or"interval"(tolerance-constrained longest chain).- remove
Logical. If
TRUE, return only the retained fixes. DefaultFALSE– the full object is returned with a logicalthin_selectedcolumn.
Value
A move2 object. With remove = FALSE, the input is
returned unchanged except for a new logical column
thin_selected. With remove = TRUE, only rows with
thin_selected == TRUE are returned.
Details
method = "step"(default) walks the track from the first fix and retains a fix each time the cumulative distance since the last retained fix reachesdistance. Every retained pair is therefore at leastdistanceof travel apart – the intuitive "give me one fix perdistanceof travel" behaviour.method = "interval"is the distance-space twin ofmt_thin_time(): it finds the largest subset such that every successive retained pair is within[distance - tolerance, distance + tolerance]of along-track travel. This is the faithfulmove2analogue ofmove::thinDistanceAlongTrack(), which is itself the distance counterpart ofmove::thinTrackTime().
Per-segment distance comes from move2::mt_distance(units = "m"), so
distance (and tolerance) are always in metres regardless of the
input CRS's linear unit. Geographic (lon/lat) data are thinned
against great-circle distance and projected data against planar
distance, so the two can differ slightly at the same metre threshold;
project to an equal-area metric CRS first if you need the result to be
identical across coordinate systems. Multi-track input is thinned
independently per individual.
For method = "step", the first fix of each track is always retained,
and – because the threshold is crossed mid-segment and we do not
interpolate – the realised distance between successive retained fixes
can exceed distance (it never falls below it). Use
move2::mt_interpolate() first if you need exact-distance spacing.
For method = "interval", the track is pre-split at any single step
longer than distance + tolerance (thinning never bridges such a
step), and the longest tolerance-admissible chain is selected by the
same dynamic-programming sweep used by mt_thin_time(). The first fix
is not guaranteed to be retained, and no retained pair is closer than
distance - tolerance.
See also
mt_thin_time() for time-based thinning (same DP machinery);
move2::mt_interpolate() to first regularise the track in time or
along a target line; move2::mt_distance() for the underlying
distance.
Examples
# \donttest{
library(move2)
fishers <- mt_read(mt_example())
fishers <- fishers[!sf::st_is_empty(fishers), ]
leroy <- fishers[mt_track_id(fishers) == "M4", ][seq_len(500), ]
## one fix per ~300 m of travel (minimum spacing guaranteed)
out <- mt_thin_distance(leroy, distance = 300)
table(out$thin_selected)
#>
#> FALSE TRUE
#> 443 57
## tolerance-constrained: retained pairs ~300 m +/- 30 m apart
out2 <- mt_thin_distance(leroy, distance = 300, tolerance = 30,
method = "interval")
table(out2$thin_selected)
#>
#> FALSE TRUE
#> 448 52
# }