Exporting Trajectories¶
Trajectories and TrajectoryCollections can be converted back to GeoDataFrames that can then be exported to different GIS file formats.
In [1]:
import pandas as pd
import geopandas as gpd
import movingpandas as mpd
import shapely as shp
import hvplot.pandas
from geopandas import GeoDataFrame, read_file
from shapely.geometry import Point, LineString, Polygon
from datetime import datetime, timedelta
from holoviews import opts
import warnings
warnings.filterwarnings("ignore")
opts.defaults(
opts.Overlay(active_tools=["wheel_zoom"], frame_width=500, frame_height=400)
)
mpd.show_versions()
MovingPandas 0.23.0 SYSTEM INFO ----------- python : 3.10.19 | packaged by conda-forge | (main, Jan 26 2026, 23:45:08) [GCC 14.3.0] executable : /home/anita/miniforge3/envs/mpd-ex/bin/python machine : Linux-6.8.0-134-generic-x86_64-with-glibc2.39 PROJ INFO ----------- PROJ : 9.6.2 PROJ data dir: /home/anita/miniforge3/envs/mpd-ex/share/proj PYTHON DEPENDENCIES ------------------- numpy : 1.23.1 geopandas : 1.0.1 geopy : 2.4.1 geoviews : 1.15.1 holoviews : 1.22.1 hvplot : 0.12.2 mapclassify: 2.8.1 matplotlib : 3.10.8 pandas : 2.3.3 pyproj : 3.7.1 shapely : 2.1.2 stonesoup : 1.8
In [2]:
gdf = read_file("../data/geolife_small.gpkg")
tc = mpd.TrajectoryCollection(gdf, "trajectory_id", t="t")
tc
Out[2]:
TrajectoryCollection with 5 trajectories
Trajectory 1 (No. rows: 466 | Length: 6.2 km)
| Start: 2008-12-11 04:42:14 | End: 2008-12-11 05:15:46 | Duration: 0:33:32 |
| Bounds: (116.385602, 39.862378, 116.393553, 39.898723) | CRS: EPSG:4326 | |
| Columns: id (int64), sequence (int64), trajectory_id (int64), tracker (int32) | ||
Data preview
| id | sequence | trajectory_id | tracker | geometry | |
|---|---|---|---|---|---|
| t | |||||
| 2008-12-11 04:42:14 | 1 | 1 | 1 | 19 | POINT (116.3913 39.89857) |
| 2008-12-11 04:42:16 | 2 | 2 | 1 | 19 | POINT (116.39132 39.89862) |
| 2008-12-11 04:43:26 | 3 | 3 | 1 | 19 | POINT (116.39093 39.89861) |
| 2008-12-11 04:43:32 | 4 | 4 | 1 | 19 | POINT (116.39083 39.89864) |
| 2008-12-11 04:43:47 | 5 | 5 | 1 | 19 | POINT (116.38941 39.89872) |
Trajectory 2 (No. rows: 897 | Length: 38.8 km)
| Start: 2009-06-29 07:02:25 | End: 2009-06-29 11:13:12 | Duration: 4:10:47 |
| Bounds: (116.319212, 39.971703, 116.592616, 40.082514) | CRS: EPSG:4326 | |
| Columns: id (int64), sequence (int64), trajectory_id (int64), tracker (int32) | ||
Data preview
| id | sequence | trajectory_id | tracker | geometry | |
|---|---|---|---|---|---|
| t | |||||
| 2009-06-29 07:02:25 | 1556 | 1090 | 2 | 0 | POINT (116.59096 40.07196) |
| 2009-06-29 07:02:30 | 1557 | 1091 | 2 | 0 | POINT (116.5909 40.07201) |
| 2009-06-29 07:02:35 | 1558 | 1092 | 2 | 0 | POINT (116.59088 40.07203) |
| 2009-06-29 07:02:40 | 1559 | 1093 | 2 | 0 | POINT (116.59092 40.072) |
| 2009-06-29 07:02:45 | 1560 | 1094 | 2 | 0 | POINT (116.59096 40.07198) |
Trajectory 3 (No. rows: 1810 | Length: 12.7 km)
| Start: 2009-02-04 04:32:53 | End: 2009-02-04 11:20:12 | Duration: 6:47:19 |
| Bounds: (116.332706, 39.897023, 116.387307, 39.927949) | CRS: EPSG:4326 | |
| Columns: id (int64), sequence (int64), trajectory_id (int64), tracker (int32) | ||
Data preview
| id | sequence | trajectory_id | tracker | geometry | |
|---|---|---|---|---|---|
| t | |||||
| 2009-02-04 04:32:53 | 2453 | 1 | 3 | 2 | POINT (116.38569 39.89977) |
| 2009-02-04 04:32:54 | 2454 | 2 | 3 | 2 | POINT (116.38565 39.89965) |
| 2009-02-04 04:32:55 | 2455 | 3 | 3 | 2 | POINT (116.38555 39.8997) |
| 2009-02-04 04:32:56 | 2456 | 4 | 3 | 2 | POINT (116.38553 39.89963) |
| 2009-02-04 04:32:57 | 2457 | 5 | 3 | 2 | POINT (116.38548 39.89959) |
Trajectory 4 (No. rows: 1864 | Length: 14.4 km)
| Start: 2009-03-10 10:36:45 | End: 2009-03-10 12:01:07 | Duration: 1:24:22 |
| Bounds: (116.327347, 39.896671, 116.389611, 39.927947) | CRS: EPSG:4326 | |
| Columns: id (int64), sequence (int64), trajectory_id (int64), tracker (int32) | ||
Data preview
| id | sequence | trajectory_id | tracker | geometry | |
|---|---|---|---|---|---|
| t | |||||
| 2009-03-10 10:36:45 | 4263 | 1 | 4 | 2 | POINT (116.38805 39.90342) |
| 2009-03-10 10:36:46 | 4264 | 2 | 4 | 2 | POINT (116.38804 39.9035) |
| 2009-03-10 10:36:47 | 4265 | 3 | 4 | 2 | POINT (116.38804 39.90347) |
| 2009-03-10 10:36:48 | 4266 | 4 | 4 | 2 | POINT (116.38806 39.90354) |
| 2009-03-10 10:36:49 | 4267 | 5 | 4 | 2 | POINT (116.38808 39.90359) |
Trajectory 5 (No. rows: 871 | Length: 39.3 km)
| Start: 2009-02-25 09:47:03 | End: 2009-02-25 14:31:24 | Duration: 4:44:21 |
| Bounds: (116.294527, 39.89825, 116.38552, 40.052399) | CRS: EPSG:4326 | |
| Columns: id (int64), sequence (int64), trajectory_id (int64), tracker (int32) | ||
Data preview
| id | sequence | trajectory_id | tracker | geometry | |
|---|---|---|---|---|---|
| t | |||||
| 2009-02-25 09:47:03 | 6127 | 1 | 5 | 2 | POINT (116.38526 39.90027) |
| 2009-02-25 09:47:05 | 6128 | 2 | 5 | 2 | POINT (116.38525 39.90022) |
| 2009-02-25 09:47:06 | 6129 | 3 | 5 | 2 | POINT (116.38537 39.90025) |
| 2009-02-25 09:47:07 | 6130 | 4 | 5 | 2 | POINT (116.38537 39.90026) |
| 2009-02-25 09:47:08 | 6131 | 5 | 5 | 2 | POINT (116.38534 39.90026) |
In [3]:
tc.to_point_gdf()
Out[3]:
| id | sequence | trajectory_id | tracker | geometry | |
|---|---|---|---|---|---|
| t | |||||
| 2008-12-11 04:42:14 | 1 | 1 | 1 | 19 | POINT (116.3913 39.89857) |
| 2008-12-11 04:42:16 | 2 | 2 | 1 | 19 | POINT (116.39132 39.89862) |
| 2008-12-11 04:43:26 | 3 | 3 | 1 | 19 | POINT (116.39093 39.89861) |
| 2008-12-11 04:43:32 | 4 | 4 | 1 | 19 | POINT (116.39083 39.89864) |
| 2008-12-11 04:43:47 | 5 | 5 | 1 | 19 | POINT (116.38941 39.89872) |
| ... | ... | ... | ... | ... | ... |
| 2009-02-25 14:31:04 | 6993 | 867 | 5 | 2 | POINT (116.33719 39.92623) |
| 2009-02-25 14:31:09 | 6994 | 868 | 5 | 2 | POINT (116.33721 39.92624) |
| 2009-02-25 14:31:14 | 6995 | 869 | 5 | 2 | POINT (116.33726 39.92621) |
| 2009-02-25 14:31:19 | 6996 | 870 | 5 | 2 | POINT (116.33729 39.9262) |
| 2009-02-25 14:31:24 | 6997 | 871 | 5 | 2 | POINT (116.33733 39.92619) |
5908 rows × 5 columns
Convert to a line GeoDataFrame¶
In [4]:
tc.to_line_gdf()
Out[4]:
| id | sequence | trajectory_id | tracker | t | prev_t | geometry | |
|---|---|---|---|---|---|---|---|
| 0 | 2 | 2 | 1 | 19 | 2008-12-11 04:42:16 | 2008-12-11 04:42:14 | LINESTRING (116.3913 39.89857, 116.39132 39.89... |
| 1 | 3 | 3 | 1 | 19 | 2008-12-11 04:43:26 | 2008-12-11 04:42:16 | LINESTRING (116.39132 39.89862, 116.39093 39.8... |
| 2 | 4 | 4 | 1 | 19 | 2008-12-11 04:43:32 | 2008-12-11 04:43:26 | LINESTRING (116.39093 39.89861, 116.39083 39.8... |
| 3 | 5 | 5 | 1 | 19 | 2008-12-11 04:43:47 | 2008-12-11 04:43:32 | LINESTRING (116.39083 39.89864, 116.38941 39.8... |
| 4 | 6 | 6 | 1 | 19 | 2008-12-11 04:43:50 | 2008-12-11 04:43:47 | LINESTRING (116.38941 39.89872, 116.39052 39.8... |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 5898 | 6993 | 867 | 5 | 2 | 2009-02-25 14:31:04 | 2009-02-25 14:31:02 | LINESTRING (116.33715 39.92631, 116.33719 39.9... |
| 5899 | 6994 | 868 | 5 | 2 | 2009-02-25 14:31:09 | 2009-02-25 14:31:04 | LINESTRING (116.33719 39.92623, 116.33721 39.9... |
| 5900 | 6995 | 869 | 5 | 2 | 2009-02-25 14:31:14 | 2009-02-25 14:31:09 | LINESTRING (116.33721 39.92624, 116.33726 39.9... |
| 5901 | 6996 | 870 | 5 | 2 | 2009-02-25 14:31:19 | 2009-02-25 14:31:14 | LINESTRING (116.33726 39.92621, 116.33729 39.9... |
| 5902 | 6997 | 871 | 5 | 2 | 2009-02-25 14:31:24 | 2009-02-25 14:31:19 | LINESTRING (116.33729 39.9262, 116.33733 39.92... |
5903 rows × 7 columns
Convert to a trajectory GeoDataFrame¶
In [5]:
tc.to_traj_gdf(wkt=True)
Out[5]:
| trajectory_id | start_t | end_t | geometry | length | direction | wkt | |
|---|---|---|---|---|---|---|---|
| 0 | 1 | 2008-12-11 04:42:14 | 2008-12-11 05:15:46 | LINESTRING (116.3913 39.89857, 116.39132 39.89... | 6207.020261 | 186.681376 | LINESTRING M (116.391305 39.898573 1228970534.... |
| 1 | 2 | 2009-06-29 07:02:25 | 2009-06-29 11:13:12 | LINESTRING (116.59096 40.07196, 116.5909 40.07... | 38764.575483 | 250.585295 | LINESTRING M (116.590957 40.071961 1246258945.... |
| 2 | 3 | 2009-02-04 04:32:53 | 2009-02-04 11:20:12 | LINESTRING (116.38569 39.89977, 116.38565 39.8... | 12745.157506 | 304.115160 | LINESTRING M (116.385689 39.899773 1233721973.... |
| 3 | 4 | 2009-03-10 10:36:45 | 2009-03-10 12:01:07 | LINESTRING (116.38805 39.90342, 116.38804 39.9... | 14363.780551 | 300.732843 | LINESTRING M (116.388053 39.903418 1236681405.... |
| 4 | 5 | 2009-02-25 09:47:03 | 2009-02-25 14:31:24 | LINESTRING (116.38526 39.90027, 116.38525 39.9... | 39259.779560 | 305.200501 | LINESTRING M (116.385256 39.90027 1235555223.0... |
In [6]:
tc.to_traj_gdf(agg={"tracker": "mode", "sequence": ["min", "max"]})
Out[6]:
| trajectory_id | start_t | end_t | geometry | length | direction | tracker_mode | sequence_min | sequence_max | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2008-12-11 04:42:14 | 2008-12-11 05:15:46 | LINESTRING (116.3913 39.89857, 116.39132 39.89... | 6207.020261 | 186.681376 | 19 | 1 | 466 |
| 1 | 2 | 2009-06-29 07:02:25 | 2009-06-29 11:13:12 | LINESTRING (116.59096 40.07196, 116.5909 40.07... | 38764.575483 | 250.585295 | 0 | 1090 | 1986 |
| 2 | 3 | 2009-02-04 04:32:53 | 2009-02-04 11:20:12 | LINESTRING (116.38569 39.89977, 116.38565 39.8... | 12745.157506 | 304.115160 | 2 | 1 | 1810 |
| 3 | 4 | 2009-03-10 10:36:45 | 2009-03-10 12:01:07 | LINESTRING (116.38805 39.90342, 116.38804 39.9... | 14363.780551 | 300.732843 | 2 | 1 | 1864 |
| 4 | 5 | 2009-02-25 09:47:03 | 2009-02-25 14:31:24 | LINESTRING (116.38526 39.90027, 116.38525 39.9... | 39259.779560 | 305.200501 | 2 | 1 | 871 |
Exporting to GIS file formats¶
These GeoDataFrames can be exported to different file formats using GeoPandas, as documented in https://geopandas.org/docs/user_guide/io.html
In [7]:
export_gdf = tc.to_traj_gdf(agg={"sequence": ["min", "max"]})
export_gdf.to_file("temp.gpkg", layer="trajectories", driver="GPKG")
In [8]:
read_file("temp.gpkg").plot()
Out[8]:
<Axes: >
In [9]:
read_file("temp.gpkg")
Out[9]:
| trajectory_id | start_t | end_t | length | direction | sequence_min | sequence_max | geometry | |
|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2008-12-11 04:42:14 | 2008-12-11 05:15:46 | 6207.020261 | 186.681376 | 1 | 466 | LINESTRING (116.3913 39.89857, 116.39132 39.89... |
| 1 | 2 | 2009-06-29 07:02:25 | 2009-06-29 11:13:12 | 38764.575483 | 250.585295 | 1090 | 1986 | LINESTRING (116.59096 40.07196, 116.5909 40.07... |
| 2 | 3 | 2009-02-04 04:32:53 | 2009-02-04 11:20:12 | 12745.157506 | 304.115160 | 1 | 1810 | LINESTRING (116.38569 39.89977, 116.38565 39.8... |
| 3 | 4 | 2009-03-10 10:36:45 | 2009-03-10 12:01:07 | 14363.780551 | 300.732843 | 1 | 1864 | LINESTRING (116.38805 39.90342, 116.38804 39.9... |
| 4 | 5 | 2009-02-25 09:47:03 | 2009-02-25 14:31:24 | 39259.779560 | 305.200501 | 1 | 871 | LINESTRING (116.38526 39.90027, 116.38525 39.9... |
In [ ]: