0
# Trajectory Processing
1
2
Advanced algorithms for trajectory generalization, splitting, cleaning, and smoothing. These specialized classes provide methods for preparing and analyzing movement data through various processing techniques.
3
4
## Capabilities
5
6
### Trajectory Generalization
7
8
Classes for reducing trajectory complexity while preserving important characteristics.
9
10
#### TrajectoryGeneralizer Base Class
11
12
```python { .api }
13
class TrajectoryGeneralizer:
14
def __init__(self, traj):
15
"""
16
Base class for trajectory generalization algorithms.
17
18
Parameters:
19
- traj: Trajectory object to generalize
20
"""
21
22
def generalize(self, tolerance):
23
"""
24
Generalize trajectory using algorithm-specific method.
25
26
Parameters:
27
- tolerance: Algorithm-specific tolerance parameter
28
29
Returns:
30
Generalized Trajectory object
31
"""
32
```
33
34
#### Douglas-Peucker Generalization
35
36
```python { .api }
37
class DouglasPeuckerGeneralizer(TrajectoryGeneralizer):
38
def __init__(self, traj):
39
"""Classic Douglas-Peucker algorithm using shapely."""
40
41
def generalize(self, tolerance=1.0):
42
"""
43
Generalize using Douglas-Peucker algorithm.
44
45
Parameters:
46
- tolerance: Distance threshold in coordinate units
47
48
Returns:
49
Generalized Trajectory
50
"""
51
```
52
53
#### Distance-Based Generalization
54
55
```python { .api }
56
class MaxDistanceGeneralizer(TrajectoryGeneralizer):
57
def __init__(self, traj):
58
"""Douglas-Peucker-like algorithm checking distance threshold."""
59
60
def generalize(self, tolerance=1.0):
61
"""
62
Generalize by maximum distance threshold.
63
64
Parameters:
65
- tolerance: Maximum distance threshold
66
"""
67
68
class MinDistanceGeneralizer(TrajectoryGeneralizer):
69
def __init__(self, traj):
70
"""Ensures consecutive locations are at least a certain distance apart."""
71
72
def generalize(self, tolerance=1.0):
73
"""
74
Generalize by minimum distance threshold.
75
76
Parameters:
77
- tolerance: Minimum distance between consecutive points
78
"""
79
```
80
81
#### Time-Based Generalization
82
83
```python { .api }
84
class MinTimeDeltaGeneralizer(TrajectoryGeneralizer):
85
def __init__(self, traj):
86
"""Ensures consecutive rows are at least a certain timedelta apart."""
87
88
def generalize(self, tolerance):
89
"""
90
Generalize by minimum time difference.
91
92
Parameters:
93
- tolerance: timedelta object specifying minimum time difference
94
"""
95
96
class TopDownTimeRatioGeneralizer(TrajectoryGeneralizer):
97
def __init__(self, traj):
98
"""Spatiotemporal generalization based on Meratnia & de By (2004)."""
99
100
def generalize(self, tolerance=1.0):
101
"""
102
Generalize using top-down time ratio algorithm.
103
104
Parameters:
105
- tolerance: Distance threshold for spatiotemporal analysis
106
"""
107
```
108
109
### Trajectory Splitting
110
111
Classes for dividing trajectories into segments based on various criteria.
112
113
#### TrajectorySplitter Base Class
114
115
```python { .api }
116
class TrajectorySplitter:
117
def __init__(self, traj):
118
"""
119
Base class for trajectory splitting algorithms.
120
121
Parameters:
122
- traj: Trajectory object to split
123
"""
124
125
def split(self, n_processes=1, **kwargs):
126
"""
127
Split trajectory using algorithm-specific method.
128
129
Parameters:
130
- n_processes: Number of processes for parallel computation
131
- **kwargs: Algorithm-specific parameters
132
133
Returns:
134
TrajectoryCollection with split trajectories
135
"""
136
```
137
138
#### Temporal Splitting
139
140
```python { .api }
141
class TemporalSplitter(TrajectorySplitter):
142
def __init__(self, traj):
143
"""Split trajectories using regular time intervals."""
144
145
def split(self, mode="day", min_length=0):
146
"""
147
Split by temporal intervals.
148
149
Parameters:
150
- mode: Time interval ("hour", "day", "month", "year")
151
- min_length: Minimum length for resulting segments
152
153
Returns:
154
TrajectoryCollection with temporally split trajectories
155
"""
156
```
157
158
#### Gap-Based Splitting
159
160
```python { .api }
161
class ObservationGapSplitter(TrajectorySplitter):
162
def __init__(self, traj):
163
"""Split whenever there's a gap in observations."""
164
165
def split(self, gap, min_length=0):
166
"""
167
Split on observation gaps.
168
169
Parameters:
170
- gap: timedelta object defining gap threshold
171
- min_length: Minimum length for resulting segments
172
173
Returns:
174
TrajectoryCollection with gap-split trajectories
175
"""
176
```
177
178
#### Speed-Based Splitting
179
180
```python { .api }
181
class SpeedSplitter(TrajectorySplitter):
182
def __init__(self, traj):
183
"""Split based on speed thresholds and duration."""
184
185
def split(self, speed, duration, min_length=0, max_speed=float('inf')):
186
"""
187
Split based on speed criteria.
188
189
Parameters:
190
- speed: Speed threshold
191
- duration: Duration threshold
192
- min_length: Minimum length for resulting segments
193
- max_speed: Maximum speed threshold
194
195
Returns:
196
TrajectoryCollection with speed-based splits
197
"""
198
```
199
200
#### Stop-Based Splitting
201
202
```python { .api }
203
class StopSplitter(TrajectorySplitter):
204
def __init__(self, traj):
205
"""Split at detected stops."""
206
207
def split(self, max_diameter, min_duration, min_length=0):
208
"""
209
Split at stop locations.
210
211
Parameters:
212
- max_diameter: Maximum diameter for stop detection
213
- min_duration: Minimum duration to qualify as stop
214
- min_length: Minimum length for resulting segments
215
216
Returns:
217
TrajectoryCollection with stop-based splits
218
"""
219
```
220
221
#### Directional Splitting
222
223
```python { .api }
224
class AngleChangeSplitter(TrajectorySplitter):
225
def __init__(self, traj):
226
"""Split on heading angle changes."""
227
228
def split(self, min_angle=45, min_speed=0, min_length=0):
229
"""
230
Split on angle changes.
231
232
Parameters:
233
- min_angle: Minimum angle change in degrees
234
- min_speed: Minimum speed threshold
235
- min_length: Minimum length for resulting segments
236
237
Returns:
238
TrajectoryCollection with angle-based splits
239
"""
240
```
241
242
#### Value-Based Splitting
243
244
```python { .api }
245
class ValueChangeSplitter(TrajectorySplitter):
246
def __init__(self, traj):
247
"""Split on column value changes."""
248
249
def split(self, col_name, min_length=0):
250
"""
251
Split when column values change.
252
253
Parameters:
254
- col_name: Column name to monitor for changes
255
- min_length: Minimum length for resulting segments
256
257
Returns:
258
TrajectoryCollection with value-change splits
259
"""
260
```
261
262
### Trajectory Cleaning
263
264
Classes for detecting and removing outliers from trajectory data.
265
266
#### TrajectoryCleaner Base Class
267
268
```python { .api }
269
class TrajectoryCleaner:
270
def __init__(self, traj):
271
"""
272
Base class for trajectory cleaning algorithms.
273
274
Parameters:
275
- traj: Trajectory object to clean
276
"""
277
278
def clean(self, **kwargs):
279
"""
280
Clean trajectory using algorithm-specific method.
281
282
Returns:
283
Cleaned Trajectory object
284
"""
285
```
286
287
#### Statistical Outlier Removal
288
289
```python { .api }
290
class IqrCleaner(TrajectoryCleaner):
291
def __init__(self, traj):
292
"""Interquartile range (IQR) based outlier cleaner."""
293
294
def clean(self, columns):
295
"""
296
Clean using IQR method.
297
298
Parameters:
299
- columns: Dict mapping column names to alpha values for IQR calculation
300
301
Returns:
302
Cleaned Trajectory object
303
"""
304
```
305
306
#### Speed-Based Outlier Removal
307
308
```python { .api }
309
class OutlierCleaner(TrajectoryCleaner):
310
def __init__(self, traj):
311
"""Speed-based outlier cleaner."""
312
313
def clean(self, v_max=None, units=None, alpha=3):
314
"""
315
Clean using speed-based outlier detection.
316
317
Parameters:
318
- v_max: Maximum speed threshold
319
- units: UNITS object for speed units
320
- alpha: Standard deviation multiplier for outlier detection
321
322
Returns:
323
Cleaned Trajectory object
324
"""
325
```
326
327
### Stop Detection
328
329
Specialized class for detecting stationary periods in trajectories.
330
331
```python { .api }
332
class TrajectoryStopDetector:
333
def __init__(self, traj, n_processes=1):
334
"""
335
Detects stops in trajectories based on area size and duration.
336
337
Parameters:
338
- traj: Trajectory object to analyze
339
- n_processes: Number of processes for parallel computation
340
"""
341
342
def get_stop_time_ranges(self, max_diameter, min_duration):
343
"""
344
Get time ranges of detected stops.
345
346
Parameters:
347
- max_diameter: Maximum diameter for stop area
348
- min_duration: Minimum duration to qualify as stop
349
350
Returns:
351
List of (start_time, end_time) tuples
352
"""
353
354
def get_stop_segments(self, max_diameter, min_duration):
355
"""
356
Get trajectory segments representing stops.
357
358
Parameters:
359
- max_diameter: Maximum diameter for stop area
360
- min_duration: Minimum duration to qualify as stop
361
362
Returns:
363
TrajectoryCollection with stop segments
364
"""
365
366
def get_stop_points(self, max_diameter, min_duration):
367
"""
368
Get representative points for detected stops.
369
370
Parameters:
371
- max_diameter: Maximum diameter for stop area
372
- min_duration: Minimum duration to qualify as stop
373
374
Returns:
375
GeoDataFrame with stop points
376
"""
377
```
378
379
### Trajectory Smoothing
380
381
Classes for smoothing noisy trajectory data using filtering techniques.
382
383
#### TrajectorySmoother Base Class
384
385
```python { .api }
386
class TrajectorySmoother:
387
def __init__(self, traj):
388
"""
389
Base class for trajectory smoothing algorithms.
390
391
Parameters:
392
- traj: Trajectory object to smooth
393
"""
394
395
def smooth(self, **kwargs):
396
"""
397
Smooth trajectory using algorithm-specific method.
398
399
Returns:
400
Smoothed Trajectory object
401
"""
402
```
403
404
#### Kalman Filter Smoothing
405
406
```python { .api }
407
class KalmanSmootherCV(TrajectorySmoother):
408
def __init__(self, traj):
409
"""
410
Kalman Filter with Constant Velocity model.
411
412
Note: Requires Stone Soup dependency (install with pip install stonesoup)
413
"""
414
415
def smooth(self, process_noise_std=0.5, measurement_noise_std=1):
416
"""
417
Smooth using Kalman filter.
418
419
Parameters:
420
- process_noise_std: Process noise standard deviation
421
- measurement_noise_std: Measurement noise standard deviation
422
423
Returns:
424
Smoothed Trajectory object
425
"""
426
```
427
428
## Usage Examples
429
430
### Trajectory Generalization
431
432
```python
433
import movingpandas as mpd
434
435
# Create trajectory (assume 'traj' exists)
436
# traj = mpd.Trajectory(...)
437
438
# Douglas-Peucker generalization
439
generalizer = mpd.DouglasPeuckerGeneralizer(traj)
440
simplified_traj = generalizer.generalize(tolerance=10.0) # 10 meter tolerance
441
442
# Minimum distance generalization
443
min_dist_gen = mpd.MinDistanceGeneralizer(traj)
444
filtered_traj = min_dist_gen.generalize(tolerance=5.0) # 5 meter minimum distance
445
```
446
447
### Trajectory Splitting
448
449
```python
450
# Split by day
451
temporal_splitter = mpd.TemporalSplitter(traj)
452
daily_segments = temporal_splitter.split(mode="day", min_length=100)
453
454
# Split on stops
455
stop_splitter = mpd.StopSplitter(traj)
456
segments = stop_splitter.split(
457
max_diameter=50, # 50 meter diameter
458
min_duration=pd.Timedelta("5 minutes"),
459
min_length=10
460
)
461
462
# Split on speed changes
463
speed_splitter = mpd.SpeedSplitter(traj)
464
speed_segments = speed_splitter.split(
465
speed=2.0, # 2 m/s threshold
466
duration=pd.Timedelta("30 seconds")
467
)
468
```
469
470
### Trajectory Cleaning
471
472
```python
473
# Remove speed-based outliers
474
cleaner = mpd.OutlierCleaner(traj)
475
clean_traj = cleaner.clean(v_max=50, alpha=3) # Max 50 m/s, 3 std devs
476
477
# IQR-based cleaning
478
iqr_cleaner = mpd.IqrCleaner(traj)
479
clean_traj = iqr_cleaner.clean(columns={'speed': 1.5}) # 1.5 * IQR for speed
480
```
481
482
### Stop Detection
483
484
```python
485
# Detect stops
486
stop_detector = mpd.TrajectoryStopDetector(traj)
487
488
# Get stop time ranges
489
stop_times = stop_detector.get_stop_time_ranges(
490
max_diameter=100, # 100 meter diameter
491
min_duration=pd.Timedelta("10 minutes")
492
)
493
494
# Get stop segments as trajectories
495
stop_segments = stop_detector.get_stop_segments(
496
max_diameter=100,
497
min_duration=pd.Timedelta("10 minutes")
498
)
499
500
# Get stop points
501
stop_points = stop_detector.get_stop_points(
502
max_diameter=100,
503
min_duration=pd.Timedelta("10 minutes")
504
)
505
```
506
507
### Trajectory Smoothing
508
509
```python
510
# Kalman filter smoothing (requires Stone Soup)
511
try:
512
smoother = mpd.KalmanSmootherCV(traj)
513
smooth_traj = smoother.smooth(
514
process_noise_std=0.5,
515
measurement_noise_std=1.0
516
)
517
except ImportError:
518
print("Stone Soup package required for Kalman smoothing")
519
```