0
# Core Data Structures
1
2
The fundamental classes for representing and managing trajectory data in MovingPandas. These classes provide rich functionality for spatio-temporal analysis, data enhancement, visualization, and conversion operations.
3
4
## Capabilities
5
6
### Trajectory Class
7
8
The core class for representing individual movement trajectories built on top of GeoPandas GeoDataFrame.
9
10
```python { .api }
11
class Trajectory:
12
def __init__(self, df, traj_id, traj_id_col=None, obj_id=None, t=None, x=None, y=None, crs="epsg:4326", parent=None):
13
"""
14
Initialize a Trajectory object.
15
16
Parameters:
17
- df: GeoDataFrame with trajectory data
18
- traj_id: Trajectory identifier
19
- traj_id_col: Column name for trajectory ID
20
- obj_id: Object identifier
21
- t: Time column name (default: auto-detected)
22
- x: X coordinate column name (default: auto-detected)
23
- y: Y coordinate column name (default: auto-detected)
24
- crs: Coordinate reference system (default: "epsg:4326")
25
- parent: Parent trajectory for segments
26
"""
27
```
28
29
#### Basic Properties and Validation
30
31
```python { .api }
32
def size(self):
33
"""Get number of trajectory points."""
34
35
def copy(self):
36
"""Create a deep copy of the trajectory."""
37
38
def is_valid(self):
39
"""Check if trajectory has valid structure."""
40
41
def get_crs(self):
42
"""Get coordinate reference system."""
43
44
def to_crs(self, crs):
45
"""Transform to different coordinate reference system."""
46
47
def is_latlon(self):
48
"""Check if using latitude/longitude coordinates."""
49
```
50
51
#### Temporal Access Methods
52
53
```python { .api }
54
def get_start_time(self):
55
"""Get trajectory start timestamp."""
56
57
def get_end_time(self):
58
"""Get trajectory end timestamp."""
59
60
def get_duration(self):
61
"""Get trajectory duration as timedelta."""
62
63
def get_sampling_interval(self):
64
"""Get average time interval between points."""
65
```
66
67
#### Spatial Access Methods
68
69
```python { .api }
70
def get_start_location(self):
71
"""Get starting point geometry."""
72
73
def get_end_location(self):
74
"""Get ending point geometry."""
75
76
def get_bbox(self):
77
"""Get bounding box of trajectory."""
78
79
def get_direction(self):
80
"""Get overall direction of movement."""
81
82
def get_length(self, units=UNITS()):
83
"""
84
Get trajectory length.
85
86
Parameters:
87
- units: UNITS object specifying distance units
88
89
Returns:
90
Trajectory length as float
91
"""
92
```
93
94
#### Data Retrieval Methods
95
96
```python { .api }
97
def get_row_at(self, t, method="nearest"):
98
"""
99
Get trajectory row at specific time.
100
101
Parameters:
102
- t: Timestamp
103
- method: "nearest" or "interpolated"
104
105
Returns:
106
DataFrame row
107
"""
108
109
def get_position_at(self, t, method="interpolated"):
110
"""
111
Get position at specific time.
112
113
Parameters:
114
- t: Timestamp
115
- method: "interpolated" or "nearest"
116
117
Returns:
118
Point geometry
119
"""
120
121
def interpolate_position_at(self, t):
122
"""Interpolate position at specific time."""
123
```
124
125
#### Geometric Operations
126
127
```python { .api }
128
def to_linestring(self):
129
"""Convert trajectory to LineString geometry."""
130
131
def to_linestringm_wkt(self):
132
"""Convert to LineStringM WKT format."""
133
134
def intersects(self, polygon):
135
"""Check if trajectory intersects polygon."""
136
137
def distance(self, other, units=UNITS()):
138
"""
139
Calculate distance to another trajectory.
140
141
Parameters:
142
- other: Another Trajectory object
143
- units: UNITS object for distance units
144
145
Returns:
146
Distance as float
147
"""
148
149
def hausdorff_distance(self, other, units=UNITS()):
150
"""Calculate Hausdorff distance to another trajectory."""
151
```
152
153
#### Conversion Methods
154
155
```python { .api }
156
def to_point_gdf(self, return_orig_tz=False):
157
"""Convert to point GeoDataFrame."""
158
159
def to_line_gdf(self, columns=None):
160
"""Convert to line GeoDataFrame."""
161
162
def to_traj_gdf(self, wkt=False, agg=False):
163
"""Convert to trajectory GeoDataFrame."""
164
165
def to_mf_json(self, datetime_to_str=True, temporal_columns=None):
166
"""Convert to Moving Features JSON format."""
167
```
168
169
#### Segmentation Methods
170
171
```python { .api }
172
def get_segment_between(self, t1, t2):
173
"""
174
Extract trajectory segment between two times.
175
176
Parameters:
177
- t1: Start time
178
- t2: End time
179
180
Returns:
181
New Trajectory object
182
"""
183
184
def get_linestring_between(self, t1, t2, method="interpolated"):
185
"""Get LineString between two times."""
186
```
187
188
#### Spatial Operations
189
190
```python { .api }
191
def clip(self, polygon, point_based=False):
192
"""Clip trajectory to polygon boundary."""
193
194
def intersection(self, feature, point_based=False):
195
"""Find intersection with geographic feature."""
196
197
def get_mcp(self):
198
"""Get minimum convex polygon (MCP) of trajectory."""
199
```
200
201
#### Data Enhancement Methods
202
203
```python { .api }
204
def add_speed(self, overwrite=False, name="speed", units=UNITS()):
205
"""
206
Add speed column to trajectory.
207
208
Parameters:
209
- overwrite: Whether to overwrite existing column
210
- name: Column name for speed values
211
- units: UNITS object for speed units
212
213
Returns:
214
Modified Trajectory object
215
"""
216
217
def add_direction(self, overwrite=False, name="direction"):
218
"""Add direction/heading column."""
219
220
def add_distance(self, overwrite=False, name="distance", units=None):
221
"""Add distance column (distance between consecutive points)."""
222
223
def add_acceleration(self, overwrite=False, name="acceleration", units=UNITS()):
224
"""Add acceleration column."""
225
226
def add_timedelta(self, overwrite=False, name="timedelta"):
227
"""Add time delta column."""
228
229
def add_angular_difference(self, overwrite=False, name="angular_difference"):
230
"""Add angular difference column."""
231
232
def add_traj_id(self, overwrite=False):
233
"""Add trajectory ID column."""
234
```
235
236
#### Column Access Methods
237
238
```python { .api }
239
def get_min(self, column):
240
"""Get minimum value in column."""
241
242
def get_max(self, column):
243
"""Get maximum value in column."""
244
245
def get_column_names(self):
246
"""Get list of column names."""
247
248
def get_traj_id_col(self):
249
"""Get trajectory ID column name."""
250
251
def get_speed_col(self):
252
"""Get speed column name."""
253
254
def get_distance_col(self):
255
"""Get distance column name."""
256
257
def get_direction_col(self):
258
"""Get direction column name."""
259
260
def get_angular_difference_col(self):
261
"""Get angular difference column name."""
262
263
def get_timedelta_col(self):
264
"""Get timedelta column name."""
265
266
def get_geom_col(self):
267
"""Get geometry column name."""
268
```
269
270
#### Visualization Methods
271
272
```python { .api }
273
def plot(self, *args, **kwargs):
274
"""Create matplotlib plot of trajectory."""
275
276
def explore(self, *args, **kwargs):
277
"""Create interactive Folium map."""
278
279
def hvplot(self, *args, **kwargs):
280
"""Create hvplot visualization."""
281
282
def hvplot_pts(self, *args, **kwargs):
283
"""Create hvplot point visualization."""
284
```
285
286
#### Utility Methods
287
288
```python { .api }
289
def drop(self, **kwargs):
290
"""Drop columns or rows from trajectory."""
291
292
def apply_offset_seconds(self, column, offset):
293
"""Apply time offset in seconds to column."""
294
295
def apply_offset_minutes(self, column, offset):
296
"""Apply time offset in minutes to column."""
297
298
def is_long_enough(self, min_length, units=UNITS()):
299
"""Check if trajectory meets minimum length requirement."""
300
```
301
302
### TrajectoryCollection Class
303
304
Container class for managing and analyzing multiple trajectories simultaneously.
305
306
```python { .api }
307
class TrajectoryCollection:
308
def __init__(self, data, traj_id_col=None, obj_id_col=None, t=None, x=None, y=None, crs="epsg:4326", min_length=0, min_duration=None):
309
"""
310
Initialize a TrajectoryCollection.
311
312
Parameters:
313
- data: GeoDataFrame with multiple trajectory data
314
- traj_id_col: Column name for trajectory IDs
315
- obj_id_col: Column name for object IDs
316
- t: Time column name
317
- x: X coordinate column name
318
- y: Y coordinate column name
319
- crs: Coordinate reference system
320
- min_length: Minimum trajectory length filter
321
- min_duration: Minimum trajectory duration filter
322
"""
323
```
324
325
#### Collection Management
326
327
```python { .api }
328
def copy(self):
329
"""Create deep copy of collection."""
330
331
def drop(self, **kwargs):
332
"""Drop trajectories from collection."""
333
334
def __len__(self):
335
"""Get number of trajectories in collection."""
336
337
def __iter__(self):
338
"""Iterate over trajectories in collection."""
339
```
340
341
#### Data Access
342
343
```python { .api }
344
def get_trajectory(self, traj_id):
345
"""
346
Get specific trajectory by ID.
347
348
Parameters:
349
- traj_id: Trajectory identifier
350
351
Returns:
352
Trajectory object
353
"""
354
355
def get_trajectories(self, obj_id):
356
"""Get all trajectories for specific object ID."""
357
358
def get_column_names(self):
359
"""Get list of column names."""
360
361
def get_traj_id_col(self):
362
"""Get trajectory ID column name."""
363
364
def get_geom_col(self):
365
"""Get geometry column name."""
366
367
def get_speed_col(self):
368
"""Get speed column name."""
369
370
def get_direction_col(self):
371
"""Get direction column name."""
372
```
373
374
#### Conversion Methods
375
376
```python { .api }
377
def to_point_gdf(self):
378
"""Convert to point GeoDataFrame."""
379
380
def to_line_gdf(self, columns=None):
381
"""Convert to line GeoDataFrame."""
382
383
def to_traj_gdf(self, wkt=False, agg=False):
384
"""Convert to trajectory GeoDataFrame."""
385
386
def to_mf_json(self, datetime_to_str=True, temporal_columns=None):
387
"""Convert to Moving Features JSON format."""
388
```
389
390
#### Temporal Operations
391
392
```python { .api }
393
def get_locations_at(self, t, with_direction=False):
394
"""Get locations of all trajectories at specific time."""
395
396
def get_start_locations(self, with_direction=False):
397
"""Get start locations of all trajectories."""
398
399
def get_end_locations(self, with_direction=False):
400
"""Get end locations of all trajectories."""
401
402
def get_segments_between(self, t1, t2):
403
"""Get trajectory segments between two times."""
404
```
405
406
#### Spatial Operations
407
408
```python { .api }
409
def get_intersecting(self, polygon):
410
"""Get trajectories that intersect with polygon."""
411
412
def intersection(self, feature, point_based=False):
413
"""Find intersection with geographic feature."""
414
415
def clip(self, polygon, point_based=False):
416
"""Clip all trajectories to polygon boundary."""
417
```
418
419
#### Filtering
420
421
```python { .api }
422
def filter(self, property_name, property_values):
423
"""
424
Filter trajectories by property values.
425
426
Parameters:
427
- property_name: Column name to filter on
428
- property_values: Values to keep
429
430
Returns:
431
Filtered TrajectoryCollection
432
"""
433
```
434
435
#### Data Enhancement Methods
436
437
```python { .api }
438
def add_speed(self, overwrite=False, name="speed", units=UNITS(), n_processes=1):
439
"""Add speed column to all trajectories."""
440
441
def add_direction(self, overwrite=False, name="direction", n_processes=1):
442
"""Add direction column to all trajectories."""
443
444
def add_angular_difference(self, overwrite=False, name="angular_difference", n_processes=1):
445
"""Add angular difference column to all trajectories."""
446
447
def add_acceleration(self, overwrite=False, name="acceleration", units=UNITS(), n_processes=1):
448
"""Add acceleration column to all trajectories."""
449
450
def add_distance(self, overwrite=False, name="distance", units=None, n_processes=1):
451
"""Add distance column to all trajectories."""
452
453
def add_timedelta(self, overwrite=False, name="timedelta", n_processes=1):
454
"""Add timedelta column to all trajectories."""
455
456
def add_traj_id(self, overwrite=False):
457
"""Add trajectory ID column to all trajectories."""
458
```
459
460
#### Statistics
461
462
```python { .api }
463
def get_min(self, column):
464
"""Get minimum value across all trajectories."""
465
466
def get_max(self, column):
467
"""Get maximum value across all trajectories."""
468
469
def get_crs(self):
470
"""Get coordinate reference system."""
471
472
def is_latlon(self):
473
"""Check if using latitude/longitude coordinates."""
474
```
475
476
#### Visualization Methods
477
478
```python { .api }
479
def plot(self, *args, **kwargs):
480
"""Create matplotlib plot of all trajectories."""
481
482
def explore(self, *args, **kwargs):
483
"""Create interactive Folium map."""
484
485
def hvplot(self, *args, **kwargs):
486
"""Create hvplot visualization."""
487
488
def hvplot_pts(self, *args, **kwargs):
489
"""Create hvplot point visualization."""
490
```
491
492
## Usage Examples
493
494
### Basic Trajectory Creation and Analysis
495
496
```python
497
import movingpandas as mpd
498
import pandas as pd
499
import geopandas as gpd
500
from shapely.geometry import Point
501
from datetime import datetime, timedelta
502
503
# Create sample data
504
data = []
505
base_time = datetime(2023, 1, 1, 12, 0, 0)
506
for i in range(10):
507
data.append({
508
'geometry': Point(i * 0.1, i * 0.1),
509
't': base_time + timedelta(minutes=i * 5),
510
'obj_id': 'A'
511
})
512
513
gdf = gpd.GeoDataFrame(data, crs='EPSG:4326')
514
515
# Create trajectory
516
traj = mpd.Trajectory(gdf, traj_id='traj_1')
517
518
# Analyze trajectory
519
print(f"Duration: {traj.get_duration()}")
520
print(f"Length: {traj.get_length()}")
521
522
# Add computed columns
523
traj = traj.add_speed()
524
traj = traj.add_direction()
525
```
526
527
### TrajectoryCollection Operations
528
529
```python
530
# Create collection from multiple trajectories
531
collection = mpd.TrajectoryCollection(gdf, traj_id_col='obj_id')
532
533
# Filter by spatial bounds
534
from shapely.geometry import Polygon
535
bbox = Polygon([(0, 0), (0.5, 0), (0.5, 0.5), (0, 0.5)])
536
intersecting = collection.get_intersecting(bbox)
537
538
# Get locations at specific time
539
locations = collection.get_locations_at(base_time + timedelta(minutes=20))
540
```