OSM Traces (GPX files)¶

This notebook illustrates the use of GPS traces shared publicly by OSM community members in GPX format.
In [1]:
import numpy as np
import pandas as pd
import geopandas as gpd
import movingpandas as mpd
import shapely as shp
import hvplot.pandas
import matplotlib.pyplot as plt
from geopandas import GeoDataFrame, read_file
from shapely.geometry import Point, LineString, Polygon
from datetime import datetime, timedelta
from holoviews import opts, dim
from os.path import exists
from urllib.request import urlretrieve
import warnings
warnings.filterwarnings('ignore')
plot_defaults = {'linewidth':5, 'capstyle':'round', 'figsize':(9,3), 'legend':True}
opts.defaults(opts.Overlay(active_tools=['wheel_zoom'], frame_width=500, frame_height=400))
hvplot_defaults = {'tiles':None, 'cmap':'Viridis', 'colorbar':True}
mpd.show_versions()
MovingPandas 0.17.0 SYSTEM INFO ----------- python : 3.10.12 | packaged by conda-forge | (main, Jun 23 2023, 22:34:57) [MSC v.1936 64 bit (AMD64)] executable : H:\miniconda3\envs\mpd-ex\python.exe machine : Windows-10-10.0.19045-SP0 GEOS, GDAL, PROJ INFO --------------------- GEOS : None GEOS lib : None GDAL : 3.7.0 GDAL data dir: None PROJ : 9.2.1 PROJ data dir: H:\miniconda3\pkgs\proj-9.0.0-h1cfcee9_1\Library\share\proj PYTHON DEPENDENCIES ------------------- geopandas : 0.13.2 pandas : 2.0.3 fiona : 1.9.4 numpy : 1.24.4 shapely : 2.0.1 rtree : 1.0.1 pyproj : 3.6.0 matplotlib : 3.7.2 mapclassify: 2.5.0 geopy : 2.3.0 holoviews : 1.17.0 hvplot : 0.8.3 geoviews : 1.9.6 stonesoup : 1.0
Download OSM traces and generate a GeoDataFrame¶
In [2]:
def get_osm_traces(page=0, bbox='16.18,48.09,16.61,48.32'):
file = 'osm_traces.gpx'
url = f'https://api.openstreetmap.org/api/0.6/trackpoints?bbox={bbox}&page={page}'
if not exists(file):
urlretrieve(url, file)
gdf = gpd.read_file(file, layer='track_points')
# OPTIONAL: dropping empty columns
gdf.drop(columns=['ele', 'course', 'speed', 'magvar', 'geoidheight', 'name', 'cmt', 'desc',
'src', 'url', 'urlname', 'sym', 'type', 'fix', 'sat', 'hdop', 'vdop',
'pdop', 'ageofdgpsdata', 'dgpsid'], inplace=True)
return gdf
TrajectoryCollection from OSM traces GeoDataFrame¶
In [3]:
gdf = get_osm_traces()
osm_traces = mpd.TrajectoryCollection(gdf, 'track_fid', t='time')
print(f'The OSM traces download contains {len(osm_traces)} tracks')
The OSM traces download contains 1 tracks
In [4]:
for track in osm_traces: print(f'Track {track.id}: length={track.get_length(units="km"):.2f} km')
Track 0: length=3.96 km
In [5]:
track.plot()
Out[5]:
<Axes: >
Generalizing and visualizing¶
Generalization is optional but speeds up rendering
In [6]:
osm_traces = mpd.MinTimeDeltaGeneralizer(osm_traces).generalize(tolerance=timedelta(minutes=1))
osm_traces.hvplot(title='OSM Traces', line_width=7, width=700, height=400)
Out[6]:
In [7]:
osm_traces.get_trajectory(0).add_speed(overwrite=True, units=("km","h"))
osm_traces.get_trajectory(0).hvplot(
title='Speed (km/h) along track', c='speed', cmap='RdYlBu',
line_width=7, width=700, height=400, tiles='CartoLight', colorbar=True)
Out[7]: