API Reference¶
gpx.gpx Module¶
GPX model for GPX data.
This module provides the GPX model representing the root GPX document, following the GPX 1.1 specification.
- gpx.gpx.GPX_NAMESPACE = 'http://www.topografix.com/GPX/1/1'¶
GPX 1.1 namespace
- gpx.gpx.XSI_NAMESPACE = 'http://www.w3.org/2001/XMLSchema-instance'¶
XML Schema instance namespace
- class gpx.gpx.GPX(creator='https://github.com/sgraaf/gpx', *, metadata=None, wpt=<factory>, rte=<factory>, trk=<factory>, extensions=None, nsmap=None)¶
Bases:
GeoGPXModelThe root GPX document.
GPX documents contain a metadata header, followed by waypoints, routes, and tracks. You can add your own elements to the extensions section of the GPX document.
Note: The GPX version is always “1.1” per the specification and is automatically set during XML serialization.
- Parameters:
creator (str) – The name or URL of the software that created the GPX document. Defaults to “https://github.com/sgraaf/gpx”.
metadata (Metadata | None) – Metadata about the file. Defaults to None.
wpt (list[Waypoint]) – List of waypoints. Defaults to empty list.
extensions (Extensions | None) – Extension elements from other XML namespaces. Defaults to None.
nsmap (dict[str, str] | None) – Namespace prefix mappings from the original XML. Defaults to None. This is used internally to preserve namespace prefixes during round-trip parsing. Users typically don’t need to set this.
- property __geo_interface__: dict[str, Any]¶
Return the GPX as a GeoJSON-like FeatureCollection.
- Returns:
A dictionary representing a GeoJSON FeatureCollection containing all waypoints, routes, and tracks.
- to_xml(tag=None, nsmap=None)¶
Convert the GPX to an XML element.
- Parameters:
tag (str | None) – The XML tag name. Defaults to “gpx”.
nsmap (dict[str | None, str] | None) – Optional namespace mapping. Defaults to GPX 1.1 namespace with XML Schema instance namespace. If the GPX instance has stored namespace mappings (from parsing), those will be used to preserve original namespace prefixes.
- Returns:
The XML element.
- Return type:
- to_string(*, pretty_print=True)¶
Serialize the GPX instance to a string.
- Parameters:
pretty_print (bool) – Whether to format the output with indentation. Defaults to True.
- Returns:
The GPX data as a string.
- Return type:
Example
>>> from gpx import GPX >>> gpx = GPX(creator="MyApp") >>> xml_string = gpx.to_string() >>> print(xml_string[:50]) <?xml version='1.0' encoding='UTF-8'?> <gpx ve
- write_gpx(file_path, *, pretty_print=True)¶
Write the GPX to a file.
- Parameters:
Example
>>> from gpx import GPX >>> gpx = GPX(creator="MyApp") >>> gpx.write_gpx("output.gpx")
- write_geojson(file_path, *, indent=2)¶
Write the GPX to a GeoJSON file.
- Parameters:
Example
>>> from gpx import GPX >>> gpx = GPX() >>> gpx.write_geojson("output.geojson")
- write_kml(file_path, *, pretty_print=True)¶
Write the GPX to a KML file.
- Parameters:
Example
>>> from gpx import GPX >>> gpx = GPX() >>> gpx.write_kml("output.kml")
- to_wkt()¶
Convert the GPX to a WKT (Well-Known Text) string.
Returns a GeometryCollection containing all waypoints, routes, and tracks.
- Returns:
A WKT string representation of the GPX data.
- Return type:
Example
>>> from gpx import GPX, Waypoint >>> from decimal import Decimal >>> gpx = GPX(wpt=[Waypoint(Decimal("52.0"), Decimal("4.0"))]) >>> print(gpx.to_wkt()) GEOMETRYCOLLECTION (POINT (4.0 52.0))
- to_wkb(*, byte_order='little')¶
Convert the GPX to WKB (Well-Known Binary).
Returns a GeometryCollection containing all waypoints, routes, and tracks.
- Parameters:
byte_order (str) – Byte order for the binary data. Either “little” (NDR) or “big” (XDR). Defaults to “little”.
- Returns:
WKB bytes representation of the GPX data.
- Return type:
Example
>>> from gpx import GPX, Waypoint >>> from decimal import Decimal >>> gpx = GPX(wpt=[Waypoint(Decimal("52.0"), Decimal("4.0"))]) >>> wkb = gpx.to_wkb()
gpx.metadata Module¶
Metadata model for GPX data.
This module provides the Metadata model containing information about the GPX file, author, and copyright restrictions, following the GPX 1.1 specification.
- class gpx.metadata.Metadata(*, name=None, desc=None, author=None, copyright=None, link=<factory>, time=None, keywords=None, bounds=None, extensions=None)¶
Bases:
GPXModelInformation about the GPX file, author, and copyright restrictions.
Providing rich, meaningful information about your GPX files allows others to search for and use your GPS data.
- Parameters:
name (str | None) – The name of the GPX file. Defaults to None.
desc (str | None) – A description of the contents of the GPX file. Defaults to None.
author (Person | None) – The person or organization who created the GPX file. Defaults to None.
copyright (Copyright | None) – Copyright and license information governing use of the file. Defaults to None.
link (list[Link]) – URLs associated with the location described in the file. Defaults to empty list.
time (datetime | None) – The creation date of the file. Defaults to None.
keywords (str | None) – Keywords associated with the file. Search engines or databases can use this information to classify the data. Defaults to None.
bounds (Bounds | None) – Minimum and maximum coordinates which describe the extent of the coordinates in the file. Defaults to None.
extensions (Extensions | None) – Extension elements from other XML namespaces. Defaults to None.
gpx.waypoint Module¶
Waypoint model for GPX data.
This module provides the Waypoint model representing a waypoint, point of interest, or named feature on a map, following the GPX 1.1 specification.
- class gpx.waypoint.Waypoint(lat, lon, *, ele=None, time=None, magvar=None, geoidheight=None, name=None, cmt=None, desc=None, src=None, link=<factory>, sym=None, type=None, fix=None, sat=None, hdop=None, vdop=None, pdop=None, ageofdgpsdata=None, dgpsid=None, extensions=None)¶
Bases:
GeoGPXModelA waypoint, point of interest, or named feature on a map.
- Parameters:
lat (Latitude) – Latitude of the point in decimal degrees, WGS84 datum.
lon (Longitude) – Longitude of the point in decimal degrees, WGS84 datum.
ele (Decimal | None) – Elevation (in meters) of the point. Defaults to None.
time (datetime | None) – Creation/modification timestamp for element (UTC). Defaults to None.
magvar (Degrees | None) – Magnetic variation (in degrees) at the point. Defaults to None.
geoidheight (Decimal | None) – Height (in meters) of geoid (mean sea level) above WGS84 earth ellipsoid. Defaults to None.
name (str | None) – GPS name of the waypoint. Defaults to None.
cmt (str | None) – GPS waypoint comment. Defaults to None.
desc (str | None) – Text description of the element. Defaults to None.
src (str | None) – Source of data. Defaults to None.
link (list[Link]) – Links to additional information about the waypoint. Defaults to empty list.
sym (str | None) – Text of GPS symbol name. Defaults to None.
type (str | None) – Type (classification) of the waypoint. Defaults to None.
fix (Fix | None) – Type of GPX fix. Defaults to None.
sat (int | None) – Number of satellites used to calculate the GPX fix. Defaults to None.
hdop (Decimal | None) – Horizontal dilution of precision. Defaults to None.
vdop (Decimal | None) – Vertical dilution of precision. Defaults to None.
pdop (Decimal | None) – Position dilution of precision. Defaults to None.
ageofdgpsdata (Decimal | None) – Number of seconds since last DGPS update. Defaults to None.
dgpsid (DGPSStation | None) – ID of DGPS station used in differential correction. Defaults to None.
extensions (Extensions | None) – Extension elements from other XML namespaces. Defaults to None.
- property __geo_interface__: dict[str, Any]¶
Return the waypoint as a GeoJSON-like Point geometry or Feature.
Returns a Feature if any optional fields (excluding ele) are set, otherwise returns a pure Point geometry.
- Returns:
A dictionary representing either a GeoJSON Point geometry or Feature.
- distance_to(other, radius=6378137)¶
Return the distance to another waypoint using the haversine formula.
Uses a simple spherical earth model (haversine formula).
- duration_to(other)¶
Return the duration to another waypoint.
- speed_to(other)¶
Return the speed to another waypoint.
- gain_to(other)¶
Return the elevation gain to another waypoint.
gpx.route Module¶
Route model for GPX data.
This module provides the Route model representing an ordered list of waypoints representing a series of turn points leading to a destination, following the GPX 1.1 specification.
- class gpx.route.Route(*, name=None, cmt=None, desc=None, src=None, link=<factory>, number=None, type=None, extensions=None, rtept=<factory>)¶
Bases:
PointsMixin,GeoGPXModelAn ordered list of waypoints representing a series of turn points.
A route represents waypoints leading to a destination.
- Parameters:
name (str | None) – GPS name of route. Defaults to None.
cmt (str | None) – GPS comment for route. Defaults to None.
desc (str | None) – Text description of route for user. Defaults to None.
src (str | None) – Source of data. Defaults to None.
link (list[Link]) – Links to external information about the route. Defaults to empty list.
number (int | None) – GPS route number. Defaults to None.
type (str | None) – Type (classification) of route. Defaults to None.
extensions (Extensions | None) – Extension elements from other XML namespaces. Defaults to None.
rtept (list[Waypoint]) – List of route points. Defaults to empty list.
gpx.track Module¶
Track model for GPX data.
This module provides the Track model representing an ordered list of points describing a path, following the GPX 1.1 specification.
- class gpx.track.Track(*, name=None, cmt=None, desc=None, src=None, link=<factory>, number=None, type=None, extensions=None, trkseg=<factory>)¶
Bases:
PointsMixin,GeoGPXModelAn ordered list of points describing a path.
A track represents a GPS track consisting of track segments.
- Parameters:
name (str | None) – GPS name of track. Defaults to None.
cmt (str | None) – GPS comment for track. Defaults to None.
desc (str | None) – User description of track. Defaults to None.
src (str | None) – Source of data. Defaults to None.
link (list[Link]) – Links to external information about track. Defaults to empty list.
number (int | None) – GPS track number. Defaults to None.
type (str | None) – Type (classification) of track. Defaults to None.
extensions (Extensions | None) – Extension elements from other XML namespaces. Defaults to None.
trkseg (list[TrackSegment]) – List of track segments. Defaults to empty list.
- property __geo_interface__: dict[str, Any]¶
Return the track as a GeoJSON-like MultiLineString geometry or Feature.
Returns a Feature if any optional fields are set, otherwise returns a pure MultiLineString geometry.
- Returns:
A dictionary representing either a GeoJSON MultiLineString geometry or Feature.
- property moving_duration: timedelta¶
The moving duration of the track.
The moving duration is the total duration with a speed greater than 0.5 km/h.
gpx.extensions Module¶
GPX Extensions container for arbitrary namespace extensions.
This module provides the Extensions class that stores raw XML elements from any namespace, enabling lossless round-trip parsing while providing convenient accessor methods for reading and writing extension data.
- class gpx.extensions.Extensions(elements=<factory>)¶
Bases:
objectContainer for GPX extension elements from any namespace.
Stores raw XML elements from extension namespaces (non-GPX namespaces), enabling lossless round-trip parsing. Provides convenient accessor methods for reading and writing extension data without requiring knowledge of specific extension schemas.
This class is schema-agnostic and works with ANY GPX extension, including but not limited to Garmin, Strava, Cluetrust, and custom extensions.
Example
Reading extension data:
from gpx import read_gpx gpx = read_gpx("activity.gpx") # Define namespace for the extension you're looking for GARMIN_TPX = "http://www.garmin.com/xmlschemas/TrackPointExtension/v2" for track in gpx.tracks: for segment in track.segments: for point in segment.points: if point.extensions: hr = point.extensions.get_text("hr", namespace=GARMIN_TPX) if hr: print(f"Heart rate: {hr} bpm")
Creating extension data:
import xml.etree.ElementTree as ET from gpx import Waypoint, Extensions # Register namespace prefix GARMIN_TPX = "http://www.garmin.com/xmlschemas/TrackPointExtension/v2" ET.register_namespace("gpxtpx", GARMIN_TPX) # Create extension element tpx = ET.Element(f"{{{GARMIN_TPX}}}TrackPointExtension") hr = ET.SubElement(tpx, f"{{{GARMIN_TPX}}}hr") hr.text = "142" # Attach to waypoint point = Waypoint(lat=..., lon=..., extensions=Extensions(elements=[tpx]))
- copy()¶
Create a deep copy of this Extensions instance.
- Returns:
A new Extensions instance with copies of all elements.
- Return type:
- find(path, namespaces=None)¶
Find a child element using XPath.
Searches through all top-level extension elements for a matching descendant.
- Parameters:
- Returns:
The first matching element, or None if not found.
- Return type:
Element | None
Example
>>> ns = {"gpxtpx": "http://www.garmin.com/xmlschemas/TrackPointExtension/v2"} >>> hr_elem = extensions.find("gpxtpx:TrackPointExtension/gpxtpx:hr", ns)
- findall(path, namespaces=None)¶
Find all matching child elements using XPath.
- get_text(tag, namespace=None, default=None)¶
Get text content of an extension element.
Searches through all extension elements and their descendants for an element with the specified tag name.
- Parameters:
- Returns:
The text content of the element, or the default value.
- Return type:
str | None
Example
>>> # Get heart rate from Garmin extension >>> GARMIN_TPX = "http://www.garmin.com/xmlschemas/TrackPointExtension/v2" >>> hr = extensions.get_text("hr", namespace=GARMIN_TPX) >>> print(f"Heart rate: {hr} bpm")
>>> # Search any namespace >>> hr = extensions.get_text("hr")
- get_int(tag, namespace=None, default=None)¶
Get integer value of an extension element.
- Parameters:
- Returns:
The integer value, or the default value.
- Return type:
int | None
Example
>>> hr = extensions.get_int("hr", namespace=GARMIN_TPX) >>> print(f"Heart rate: {hr} bpm")
- get_float(tag, namespace=None, default=None)¶
Get float value of an extension element.
- Parameters:
- Returns:
The float value, or the default value.
- Return type:
float | None
Example
>>> temp = extensions.get_float("atemp", namespace=GARMIN_TPX) >>> print(f"Temperature: {temp}C")
- set_text(tag, value, namespace, parent_tag=None)¶
Set text content of an extension element, creating it if needed.
If the element exists, updates its text content. If it doesn’t exist, creates a new element with the specified namespace.
- Parameters:
tag (str) – The element tag name (local name).
value (str) – The text content to set.
namespace (str) – The namespace URI (required for creation).
parent_tag (str | None) – Optional parent element tag. If specified and the parent exists, the new element is added as a child of the parent. Otherwise, a new top-level element is created.
Example
>>> GARMIN_TPX = "http://www.garmin.com/xmlschemas/TrackPointExtension/v2" >>> extensions.set_text("hr", "145", namespace=GARMIN_TPX, ... parent_tag="TrackPointExtension")
- remove(tag, namespace=None)¶
Remove an extension element.
Removes the first matching element with the specified tag.
- clear()¶
Remove all extension elements.
- append(element)¶
Append an extension element.
- Parameters:
element (Element) – The XML element to append.
- extend(elements)¶
Extend with multiple extension elements.
- get_namespaces()¶
Get all namespaces used in extension elements.
Example
>>> namespaces = extensions.get_namespaces() >>> for ns in namespaces: ... print(f"Found extension namespace: {ns}")
- classmethod from_xml(element)¶
Parse extensions from an XML <extensions> element.
Creates deep copies of all child elements to ensure the parsed extensions are independent of the source XML tree.
- Parameters:
element (Element) – The <extensions> XML element.
- Returns:
An Extensions instance containing copies of all child elements.
- Return type:
- to_xml(tag=None, nsmap=None)¶
Convert to an XML <extensions> element.
gpx.track_segment Module¶
TrackSegment model for GPX data.
This module provides the TrackSegment model representing a list of track points which are logically connected in order, following the GPX 1.1 specification.
- class gpx.track_segment.TrackSegment(*, trkpt=<factory>, extensions=None)¶
Bases:
PointsMixin,GeoGPXModelA track segment holding a list of logically connected track points.
A Track Segment holds a list of Track Points which are logically connected in order. To represent a single GPS track where GPS reception was lost, or the GPS receiver was turned off, start a new Track Segment for each continuous span of track data.
- Parameters:
trkpt (list[Waypoint]) – List of track points. Defaults to empty list.
extensions (Extensions | None) – Extension elements from other XML namespaces. Defaults to None.
gpx.copyright Module¶
Copyright model for GPX data.
This module provides the Copyright model containing information about the copyright holder and any license governing use of the GPX data, following the GPX 1.1 specification.
gpx.link Module¶
Link model for GPX data.
This module provides the Link model representing a link to an external resource (Web page, digital photo, video clip, etc) with additional information, following the GPX 1.1 specification.
gpx.email Module¶
Email model for GPX data.
This module provides the Email model representing an email address broken into two parts (id and domain) to help prevent email harvesting, following the GPX 1.1 specification.
gpx.person Module¶
Person model for GPX data.
This module provides the Person model representing a person or organization, following the GPX 1.1 specification.
gpx.bounds Module¶
Bounds model for GPX data.
This module provides the Bounds model representing two lat/lon pairs defining the extent of an element, following the GPX 1.1 specification.
- class gpx.bounds.Bounds(minlat, minlon, maxlat, maxlon)¶
Bases:
GeoGPXModelTwo lat/lon pairs defining the extent of an element.
- Parameters:
- property __geo_interface__: dict[str, Any]¶
Return the Bounds as a GeoJSON-like Polygon.
The bounds are represented as a rectangular Polygon following the GeoJSON specification.
- Returns:
A dictionary with ‘type’ and ‘coordinates’ keys representing the bounds as a Polygon. Coordinates use [longitude, latitude] order as per GeoJSON convention.
gpx.types Module¶
This module provides simple type objects to contain various GPX data.
- class gpx.types.Latitude(value)¶
Bases:
DecimalA latitude class for the GPX data format.
The latitude of the point. Decimal degrees, WGS84 datum.
- Parameters:
- Raises:
ValueError – If the value is not a valid latitude (i.e. between [-90.0, 90.0]).
- class gpx.types.Longitude(value)¶
Bases:
DecimalA longitude class for the GPX data format.
The longitude of the point. Decimal degrees, WGS84 datum.
- Parameters:
- Raises:
ValueError – If the value is not a valid latitude (i.e. between [-180.0, 180.0]).
- class gpx.types.Degrees(value)¶
Bases:
DecimalA degrees class for the GPX data format.
Used for bearing, heading, course. Units are decimal degrees, true (not magnetic).
- Parameters:
- Raises:
ValueError – If the value is not a valid latitude (i.e. between [0.0, 360.0)).
- class gpx.types.Fix(value)¶
Bases:
strA fix class for the GPX data format.
Type of GPS fix. None means GPS had no fix. To signify “the fix info is unknown”, leave out fix entirely. pps = military signal used.
- Parameters:
value (str) – The fix value.
- Raises:
ValueError – If the value is not a valid fix (i.e. one of none, 2d, 3d, dgps, pps).
- class gpx.types.DGPSStation(value)¶
Bases:
intA DGPS station class for the GPX data format.
Represents a differential GPS station.
- Parameters:
- Raises:
ValueError – If the value is not a valid DGPS station (i.e. between [0, 1023]).
gpx.base Module¶
Base class for GPX dataclass models.
This module provides the base class that all GPX dataclass models inherit from, implementing common XML parsing and serialization logic.
- gpx.base.GPX_NAMESPACE = 'http://www.topografix.com/GPX/1/1'¶
GPX 1.1 namespace
- class gpx.base.GPXModel¶
Bases:
objectBase class for GPX dataclass models.
Provides common XML parsing and serialization methods. Subclasses must define the _tag class attribute to specify the default XML tag name.
- classmethod from_xml(element)¶
Parse the model from an XML element.
- Parameters:
element (Element) – The XML element to parse.
- Returns:
The parsed model instance.
- Raises:
ValueError – If required attributes are missing.
- Return type:
- to_xml(tag=None, nsmap=None)¶
Convert the model to an XML element.
- class gpx.base.GeoGPXModel¶
-
Base class for GPX dataclass models that carry geometric data.
Subclasses must implement
__geo_interface__to expose their geometry as a GeoJSON-compatible mapping. Inheriting from this class makes “this GPX model has geometry” expressible viaisinstance()and type hints.
gpx.mixins Module¶
This module provides mixin classes.
- class gpx.mixins.PointsMixin¶
Bases:
objectA mixin class to provide various statistics to an object’s points.
Implementing classes must provide
_points, returning a flat list of waypoints to aggregate over. The mixin intentionally does not define__iter__,__getitem__or__len__— those depend on the semantics of the host class (e.g.Trackiterates segments whileRoute/TrackSegmentiterate points) and belong on the host.- property __geo_interface__: dict[str, Any]¶
Return the route/track segment as a GeoJSON-like LineString geometry or Feature.
Returns a Feature if any optional fields are set, otherwise returns a pure LineString geometry.
- Returns:
A dictionary representing either a GeoJSON LineString geometry or Feature.
- property bounds: tuple[Latitude, Longitude, Latitude, Longitude]¶
The bounds of the route/track segment.
- property moving_duration: timedelta¶
The moving duration.
The moving duration is the total duration with a speed greater than 0.5 km/h.
gpx.convert Module¶
Conversion functions for converting data formats to GPX.
This module provides functions for converting from GeoJSON-like objects, WKB, and WKT data formats to GPX objects.
- gpx.convert.WKB_POINT = 1¶
WKB geometry type codes
- gpx.convert.WKB_Z_FLAG = 1000¶
Z dimension flag (add to base type for 3D)
- gpx.convert.EWKB_Z_FLAG = 2147483648¶
EWKB Z flag (high bit)
- gpx.convert.from_string(gpx_str, *, strict=False)¶
Create a GPX instance from a string.
- Parameters:
gpx_str (str) – The string containing the GPX data.
strict (bool) – If True, validate the GPX against the GPX 1.1 schema before parsing and raise
InvalidGPXErrorif any errors are found. Defaults to False (lenient parsing).
- Returns:
The GPX instance with namespace prefixes preserved.
- Raises:
InvalidGPXError – If
strictis True and the GPX data has schema errors.- Return type:
Example
>>> from gpx import from_string >>> gpx = from_string('''<?xml version="1.0"?> ... <gpx version="1.1" creator="MyApp"> ... <metadata><name>My Track</name></metadata> ... </gpx>''') >>> print(gpx.creator) MyApp
- gpx.convert.from_geo_interface(geo, *, creator=None)¶
Convert a GeoJSON-like object (with __geo_interface__ property) to GPX.
This function supports Python objects that implement the __geo_interface__ protocol (e.g., Shapely geometries) as well as raw GeoJSON dictionaries.
- Parameters:
geo (dict[str, Any] | SupportsGeoInterface) – A dictionary with GeoJSON structure or an object with __geo_interface__ property.
creator (str | None) – The creator string for the GPX. Defaults to None (uses default).
- Returns:
A GPX object.
- Raises:
ValueError – If the geometry type is not supported.
- Return type:
Example
>>> from shapely.geometry import Point >>> from gpx import from_geo_interface >>> point = Point(4.0, 52.0) >>> gpx = from_geo_interface(point)
- gpx.convert.from_wkb(wkb, *, creator=None)¶
Convert Well-Known Binary (WKB) to GPX.
Supports both standard WKB and EWKB (Extended WKB) with Z coordinates.
- Parameters:
- Returns:
A GPX object.
- Raises:
ValueError – If the WKB format is invalid or geometry type is unsupported.
- Return type:
Example
>>> from gpx import from_wkb >>> # WKB for POINT(4.0 52.0) >>> wkb = bytes.fromhex("0101000000000000000000104000000000004a4a40") >>> gpx = from_wkb(wkb)
- gpx.convert.from_wkt(wkt, *, creator=None)¶
Convert Well-Known Text (WKT) to GPX.
- Parameters:
- Returns:
A GPX object.
- Raises:
ValueError – If the WKT format is invalid or geometry type is unsupported.
- Return type:
Example
>>> from gpx import from_wkt >>> gpx = from_wkt("POINT (4.0 52.0)")
gpx.io Module¶
I/O functions for reading and converting file formats.
This module provides functions for reading GPX, GeoJSON, and KML files from disk and returning GPX objects, as well as for converting files between these formats.
- gpx.io.KML_NAMESPACE = 'http://www.opengis.net/kml/2.2'¶
KML namespace
- gpx.io.read_gpx(file_path, *, strict=False)¶
Read a GPX file and return a GPX object.
- Parameters:
strict (bool) – If True, validate the file against the GPX 1.1 schema before parsing and raise
InvalidGPXErrorif any errors are found. Defaults to False (lenient parsing).
- Returns:
A GPX object with namespace prefixes preserved.
- Raises:
InvalidGPXError – If
strictis True and the file has schema errors.- Return type:
Example
>>> from gpx import read_gpx >>> gpx = read_gpx("path/to/file.gpx")
- gpx.io.read_geojson(file_path, *, creator=None)¶
Read a GeoJSON file and return a GPX object.
- Parameters:
- Returns:
A GPX object.
- Return type:
Example
>>> from gpx import read_geojson >>> gpx = read_geojson("path/to/file.geojson")
- gpx.io.read_kml(file_path, *, creator=None)¶
Read a KML file and return a GPX object.
- Parameters:
- Returns:
A GPX object.
- Return type:
Example
>>> from gpx import read_kml >>> gpx = read_kml("path/to/file.kml")
- gpx.io.detect_format(file_path)¶
Detect the file format from a file path’s extension.
- Parameters:
file_path (str | Path) – The file path to detect the format of.
- Returns:
The detected format (“gpx”, “geojson” or “kml”), or None if the extension is not recognized.
- Return type:
str | None
Example
>>> from gpx import detect_format >>> detect_format("route.kml") 'kml'
- gpx.io.convert_file(input_file, output_file, *, input_format=None, output_format=None)¶
Convert a file between the GPX, GeoJSON and KML file formats.
- Parameters:
- Returns:
A tuple of the input and output formats used.
- Raises:
ValueError – If a format is not given and cannot be detected, or if a format is not supported.
- Return type:
Example
>>> from gpx import convert_file >>> convert_file("input.gpx", "output.geojson") ('gpx', 'geojson')
gpx.operations Module¶
Operations for editing and merging GPX models.
This module provides the operations behind the gpx edit and gpx merge
CLI commands as a reusable, importable API.
All operations are pure: they never mutate the input, but return a new
GPX instance instead. Namespace mappings (nsmap) and
extensions are preserved.
- gpx.operations.filter_points(gpx, predicate)¶
Return a new GPX with each point list filtered by
predicate.Waypoints, route points and track points for which
predicatereturns False are dropped. Routes, track segments and tracks that end up empty are dropped as well.- Parameters:
- Returns:
A new GPX instance with the filtered points.
- Return type:
Example
>>> from gpx import filter_points, read_gpx >>> gpx = read_gpx("path/to/file.gpx") >>> with_ele = filter_points(gpx, lambda point: point.ele is not None)
- gpx.operations.crop(gpx, *, min_lat=None, max_lat=None, min_lon=None, max_lon=None)¶
Crop a GPX to a geographic bounding box.
Points outside the given bounds are dropped. Bounds that are None are not enforced. Routes, track segments and tracks that end up empty are dropped as well.
- Parameters:
gpx (GPX) – The GPX instance to crop.
min_lat (float | None) – Minimum latitude. Defaults to None (no minimum).
max_lat (float | None) – Maximum latitude. Defaults to None (no maximum).
min_lon (float | None) – Minimum longitude. Defaults to None (no minimum).
max_lon (float | None) – Maximum longitude. Defaults to None (no maximum).
- Returns:
A new GPX instance cropped to the given bounds.
- Return type:
Example
>>> from gpx import crop, read_gpx >>> gpx = read_gpx("path/to/file.gpx") >>> cropped = crop(gpx, min_lat=52.0, max_lat=53.0)
- gpx.operations.trim(gpx, *, start=None, end=None)¶
Trim a GPX to a date/time range.
Points with a timestamp outside the given range are dropped; points without a timestamp are kept. Routes, track segments and tracks that end up empty are dropped as well.
- Parameters:
gpx (GPX) – The GPX instance to trim.
start (dt.datetime | None) – Start of the time range. Defaults to None (no start).
end (dt.datetime | None) – End of the time range. Defaults to None (no end).
- Returns:
A new GPX instance trimmed to the given time range.
- Return type:
Example
>>> import datetime as dt >>> from gpx import read_gpx, trim >>> gpx = read_gpx("path/to/file.gpx") >>> trimmed = trim(gpx, start=dt.datetime(2024, 1, 1, tzinfo=dt.UTC))
- gpx.operations.reverse(gpx, *, routes=True, tracks=True)¶
Reverse the routes and/or tracks of a GPX.
For tracks, both the order of the segments and the order of the points within each segment are reversed.
- Parameters:
- Returns:
A new GPX instance with the routes and/or tracks reversed.
- Return type:
Example
>>> from gpx import read_gpx, reverse >>> gpx = read_gpx("path/to/file.gpx") >>> reversed_gpx = reverse(gpx)
- gpx.operations.strip_metadata(gpx, *, name=False, desc=False, author=False, copyright=False, time=False, keywords=False, links=False)¶
Strip metadata (fields) from a GPX.
When no field flags are given, the entire metadata element is removed. Otherwise, only the selected fields are removed from the metadata.
- Parameters:
gpx (GPX) – The GPX instance to strip metadata from.
name (bool) – Whether to strip the metadata name. Defaults to False.
desc (bool) – Whether to strip the metadata description. Defaults to False.
author (bool) – Whether to strip the metadata author. Defaults to False.
copyright (bool) – Whether to strip the metadata copyright. Defaults to False.
time (bool) – Whether to strip the metadata time. Defaults to False.
keywords (bool) – Whether to strip the metadata keywords. Defaults to False.
links (bool) – Whether to strip the metadata links. Defaults to False.
- Returns:
A new GPX instance with the metadata (fields) stripped.
- Return type:
Example
>>> from gpx import read_gpx, strip_metadata >>> gpx = read_gpx("path/to/file.gpx") >>> anonymous = strip_metadata(gpx, author=True, copyright=True) >>> bare = strip_metadata(gpx) # removes all metadata
- gpx.operations.reduce_precision(gpx, *, coordinate_precision=None, elevation_precision=None)¶
Reduce the precision of the coordinates and/or elevations of a GPX.
- Parameters:
- Returns:
A new GPX instance with the precision reduced.
- Return type:
Example
>>> from gpx import read_gpx, reduce_precision >>> gpx = read_gpx("path/to/file.gpx") >>> reduced = reduce_precision(gpx, coordinate_precision=6)
- gpx.operations.split(gpx, *, time_gap=None, distance_gap=None)¶
Split track segments at time and/or distance gaps.
Each track segment is split into multiple segments wherever the gap between two consecutive track points exceeds
time_gapand/ordistance_gap. This is useful when a GPS device kept recording across a pause or signal loss, since the GPX 1.1 specification calls for a new track segment for each continuous span of track data.Points without a timestamp never trigger a time-based split. Each resulting segment keeps the original segment’s extensions. Waypoints and routes are left unchanged.
- Parameters:
gpx (GPX) – The GPX instance to split.
time_gap (dt.timedelta | None) – Split where the time between consecutive points exceeds this duration. Defaults to None (no time-based splitting).
distance_gap (float | None) – Split where the distance between consecutive points exceeds this many metres. Defaults to None (no distance-based splitting).
- Returns:
A new GPX instance with the track segments split.
- Raises:
ValueError – If neither
time_gapnordistance_gapis given.- Return type:
Example
>>> import datetime as dt >>> from gpx import read_gpx, split >>> gpx = read_gpx("path/to/file.gpx") >>> split_gpx = split(gpx, time_gap=dt.timedelta(minutes=10))
- gpx.operations.simplify(gpx, tolerance)¶
Simplify the tracks and routes of a GPX.
Reduces the number of route points and track points using the Ramer-Douglas-Peucker algorithm: points closer than
toleranceto the line between their surviving neighbors are dropped, while the overall shape is preserved. The first and last point of each route and track segment are always kept. Waypoints are left unchanged.- Parameters:
- Returns:
A new GPX instance with the tracks and routes simplified.
- Raises:
ValueError – If
toleranceis not positive.- Return type:
Example
>>> from gpx import read_gpx, simplify >>> gpx = read_gpx("path/to/file.gpx") >>> simplified = simplify(gpx, tolerance=10.0)
- gpx.operations.smooth(gpx, *, window=5, coordinates=True, elevations=True)¶
Smooth the tracks and routes of a GPX with a moving average.
Applies a centered moving average to the coordinates and/or elevations of route points and track points, reducing GPS noise. The window shrinks symmetrically near the start and end of each route and track segment, so the first and last point are always left unchanged. Points without elevation are skipped during elevation smoothing (and do not contribute to their neighbors’ averages). Waypoints are left unchanged.
- Parameters:
- Returns:
A new GPX instance with the tracks and routes smoothed.
- Raises:
ValueError – If
windowis not an odd integer of at least 3.- Return type:
Example
>>> from gpx import read_gpx, smooth >>> gpx = read_gpx("path/to/file.gpx") >>> smoothed = smooth(gpx, window=5)
- gpx.operations.shift_time(gpx, delta)¶
Shift all point timestamps of a GPX by a time delta.
The timestamps of all waypoints, route points and track points are shifted by
delta; points without a timestamp are left unchanged. This is useful for fixing timezone mistakes or GPS clock drift. The metadata timestamp (the file creation time) is not shifted.- Parameters:
gpx (GPX) – The GPX instance to shift the timestamps of.
delta (dt.timedelta) – The time delta to shift by (may be negative).
- Returns:
A new GPX instance with the timestamps shifted.
- Return type:
Example
>>> import datetime as dt >>> from gpx import read_gpx, shift_time >>> gpx = read_gpx("path/to/file.gpx") >>> shifted = shift_time(gpx, dt.timedelta(hours=-2))
- gpx.operations.strip_extensions(gpx)¶
Strip all extensions from a GPX.
Removes the extension elements from the GPX itself, its metadata, and all waypoints, routes, route points, tracks, track segments and track points. This is useful for removing vendor-specific data (e.g. heart rate, cadence, temperature) for privacy or to reduce file size.
- Parameters:
gpx (GPX) – The GPX instance to strip the extensions from.
- Returns:
A new GPX instance without extensions.
- Return type:
Example
>>> from gpx import read_gpx, strip_extensions >>> gpx = read_gpx("path/to/file.gpx") >>> stripped = strip_extensions(gpx)
- gpx.operations.merge(gpxs, *, creator=None)¶
Merge multiple GPX instances into one.
The waypoints, routes and tracks of all instances are concatenated, in order, into a single new GPX instance.
- Parameters:
- Returns:
A new GPX instance with the merged contents.
- Return type:
Example
>>> from gpx import merge, read_gpx >>> merged = merge([read_gpx("one.gpx"), read_gpx("two.gpx")])
gpx.validation Module¶
GPX 1.1 schema validation.
This module validates GPX data against the GPX 1.1 schema (gpx.xsd) using a
pure-Python, declarative rule table (no XSD engine, no extra dependencies).
Validation operates on the raw XML tree, before and independent of dataclass parsing. This is essential: most schema violations (unknown elements, duplicates, ordering) are invisible after parsing, because the dataclass parser only looks for known fields and silently ignores the rest.
The public entry point is validate(), which accepts a file path, a string
of GPX content, or a GPX instance and returns a
ValidationResult.
Example
>>> from gpx import validate
>>> result = validate("track.gpx")
>>> result.is_valid
True
- gpx.validation.GPX_10_NAMESPACE = 'http://www.topografix.com/GPX/1/0'¶
GPX 1.0 namespace (unsupported; only used to give a helpful hint).
- gpx.validation.ContentValidator¶
A content validator takes element text and returns an issue tuple or
None.
- class gpx.validation.ValidationIssue(severity, message, path, line=None)¶
Bases:
objectA single GPX schema validation issue.
- Parameters:
severity (Severity) – Whether the issue is an error or a warning.
message (str) – A human-readable description of the issue.
path (str) – A breadcrumb path to the offending element (e.g.
gpx > trk[0] > trkseg[2] > trkpt[14]).line (int | None) – The 1-based source line number, when available. Defaults to None.
- to_dict()¶
Return a JSON-serializable representation of the issue.
- class gpx.validation.ValidationResult(issues=<factory>)¶
Bases:
objectThe result of validating GPX data against the GPX 1.1 schema.
- Parameters:
issues (list[ValidationIssue]) – All issues found during validation. Defaults to empty list.
- property errors: list[ValidationIssue]¶
All issues with error severity.
- property warnings: list[ValidationIssue]¶
All issues with warning severity.
- exception gpx.validation.InvalidGPXError(result)¶
Bases:
ValueErrorRaised when strict parsing encounters an invalid GPX document.
- Parameters:
result (ValidationResult) – The validation result carrying all errors and warnings.
- result¶
The
ValidationResultwith all issues.
- issues¶
Shortcut for
result.errors.
- class gpx.validation.AttrRule(name, validator=None)¶
Bases:
objectA required XML attribute and its optional content validator.
- class gpx.validation.ChildRule(tag, max_occurs=1, content=None, type_name=None)¶
Bases:
objectA child element rule within an
xsd:sequence.- Parameters:
tag (str) – The local element name.
max_occurs (int | None) – Maximum occurrences (
Nonemeans unbounded). Defaults to 1.content (Callable[[str], tuple[Severity, str] | None] | None) – Validator for a leaf element’s text. Defaults to None.
type_name (str | None) – Complex type to recurse into for this child. Defaults to None.
- class gpx.validation.ComplexType(attrs=(), children=())¶
Bases:
objectA GPX complex type: its required attributes and ordered children.
- gpx.validation.SCHEMA: dict[str, ComplexType] = {'bounds': ComplexType(attrs=(AttrRule(name='minlat', validator=<function _latitude>), AttrRule(name='minlon', validator=<function _longitude>), AttrRule(name='maxlat', validator=<function _latitude>), AttrRule(name='maxlon', validator=<function _longitude>)), children=()), 'copyright': ComplexType(attrs=(AttrRule(name='author', validator=None),), children=(ChildRule(tag='year', max_occurs=1, content=<function _gyear>, type_name=None), ChildRule(tag='license', max_occurs=1, content=None, type_name=None))), 'email': ComplexType(attrs=(AttrRule(name='id', validator=None), AttrRule(name='domain', validator=None)), children=()), 'gpx': ComplexType(attrs=(AttrRule(name='version', validator=<function _version>), AttrRule(name='creator', validator=None)), children=(ChildRule(tag='metadata', max_occurs=1, content=None, type_name='metadata'), ChildRule(tag='wpt', max_occurs=None, content=None, type_name='wpt'), ChildRule(tag='rte', max_occurs=None, content=None, type_name='rte'), ChildRule(tag='trk', max_occurs=None, content=None, type_name='trk'), ChildRule(tag='extensions', max_occurs=1, content=None, type_name='extensions'))), 'link': ComplexType(attrs=(AttrRule(name='href', validator=None),), children=(ChildRule(tag='text', max_occurs=1, content=None, type_name=None), ChildRule(tag='type', max_occurs=1, content=None, type_name=None))), 'metadata': ComplexType(attrs=(), children=(ChildRule(tag='name', max_occurs=1, content=None, type_name=None), ChildRule(tag='desc', max_occurs=1, content=None, type_name=None), ChildRule(tag='author', max_occurs=1, content=None, type_name='person'), ChildRule(tag='copyright', max_occurs=1, content=None, type_name='copyright'), ChildRule(tag='link', max_occurs=None, content=None, type_name='link'), ChildRule(tag='time', max_occurs=1, content=<function _time>, type_name=None), ChildRule(tag='keywords', max_occurs=1, content=None, type_name=None), ChildRule(tag='bounds', max_occurs=1, content=None, type_name='bounds'), ChildRule(tag='extensions', max_occurs=1, content=None, type_name='extensions'))), 'person': ComplexType(attrs=(), children=(ChildRule(tag='name', max_occurs=1, content=None, type_name=None), ChildRule(tag='email', max_occurs=1, content=None, type_name='email'), ChildRule(tag='link', max_occurs=1, content=None, type_name='link'))), 'rte': ComplexType(attrs=(), children=(ChildRule(tag='name', max_occurs=1, content=None, type_name=None), ChildRule(tag='cmt', max_occurs=1, content=None, type_name=None), ChildRule(tag='desc', max_occurs=1, content=None, type_name=None), ChildRule(tag='src', max_occurs=1, content=None, type_name=None), ChildRule(tag='link', max_occurs=None, content=None, type_name='link'), ChildRule(tag='number', max_occurs=1, content=<function _non_negative_int>, type_name=None), ChildRule(tag='type', max_occurs=1, content=None, type_name=None), ChildRule(tag='extensions', max_occurs=1, content=None, type_name='extensions'), ChildRule(tag='rtept', max_occurs=None, content=None, type_name='wpt'))), 'trk': ComplexType(attrs=(), children=(ChildRule(tag='name', max_occurs=1, content=None, type_name=None), ChildRule(tag='cmt', max_occurs=1, content=None, type_name=None), ChildRule(tag='desc', max_occurs=1, content=None, type_name=None), ChildRule(tag='src', max_occurs=1, content=None, type_name=None), ChildRule(tag='link', max_occurs=None, content=None, type_name='link'), ChildRule(tag='number', max_occurs=1, content=<function _non_negative_int>, type_name=None), ChildRule(tag='type', max_occurs=1, content=None, type_name=None), ChildRule(tag='extensions', max_occurs=1, content=None, type_name='extensions'), ChildRule(tag='trkseg', max_occurs=None, content=None, type_name='trkseg'))), 'trkseg': ComplexType(attrs=(), children=(ChildRule(tag='trkpt', max_occurs=None, content=None, type_name='wpt'), ChildRule(tag='extensions', max_occurs=1, content=None, type_name='extensions'))), 'wpt': ComplexType(attrs=(AttrRule(name='lat', validator=<function _latitude>), AttrRule(name='lon', validator=<function _longitude>)), children=(ChildRule(tag='ele', max_occurs=1, content=<function _decimal>, type_name=None), ChildRule(tag='time', max_occurs=1, content=<function _time>, type_name=None), ChildRule(tag='magvar', max_occurs=1, content=<function _degrees>, type_name=None), ChildRule(tag='geoidheight', max_occurs=1, content=<function _decimal>, type_name=None), ChildRule(tag='name', max_occurs=1, content=None, type_name=None), ChildRule(tag='cmt', max_occurs=1, content=None, type_name=None), ChildRule(tag='desc', max_occurs=1, content=None, type_name=None), ChildRule(tag='src', max_occurs=1, content=None, type_name=None), ChildRule(tag='link', max_occurs=None, content=None, type_name='link'), ChildRule(tag='sym', max_occurs=1, content=None, type_name=None), ChildRule(tag='type', max_occurs=1, content=None, type_name=None), ChildRule(tag='fix', max_occurs=1, content=<function _fix>, type_name=None), ChildRule(tag='sat', max_occurs=1, content=<function _non_negative_int>, type_name=None), ChildRule(tag='hdop', max_occurs=1, content=<function _decimal>, type_name=None), ChildRule(tag='vdop', max_occurs=1, content=<function _decimal>, type_name=None), ChildRule(tag='pdop', max_occurs=1, content=<function _decimal>, type_name=None), ChildRule(tag='ageofdgpsdata', max_occurs=1, content=<function _decimal>, type_name=None), ChildRule(tag='dgpsid', max_occurs=1, content=<function _dgpsid>, type_name=None), ChildRule(tag='extensions', max_occurs=1, content=None, type_name='extensions')))}¶
Declarative GPX 1.1 schema, keyed by complex type name.
- gpx.validation.validate(source)¶
Validate GPX data against the GPX 1.1 schema.
- Parameters:
source (str | Path | Any) – The GPX data to validate. May be a file path (
strorPath), a string of GPX content, or aGPXinstance (which is serialized first).- Returns:
A
ValidationResultholding all errors and warnings found.- Return type:
Example
>>> from gpx import validate >>> result = validate("track.gpx") >>> if not result.is_valid: ... for issue in result.errors: ... print(issue)
gpx.utils Module¶
Utilities for GPX models.
This module provides utilities for automatic XML parsing and serialization based on dataclass field types and metadata.
Key GPX specification pattern: - XML attributes are always required → dataclass fields without | None - XML child elements are always optional → dataclass fields with | None
This allows automatic determination of attributes vs elements based on type hints.
- gpx.utils.extract_namespaces_from_string(xml_string)¶
Extract namespace prefix mappings from an XML string.
This function extracts all namespace declarations (xmlns attributes) from the XML string using regex, before ElementTree parsing which loses prefix info.
- gpx.utils.from_isoformat(dt_str)¶
Convert a string in ISO 8601 format to a datetime object.
- gpx.utils.to_isoformat(dt)¶
Convert a datetime object to a string in ISO 8601 format.
- gpx.utils.is_optional(field_type)¶
Check if a type annotation represents an optional field.
- gpx.utils.get_inner_type(field_type)¶
Extract the inner type from an Optional type annotation.
- gpx.utils.is_list_type(field_type)¶
Check if a type annotation represents a list.
- gpx.utils.get_list_item_type(field_type)¶
Extract the item type from a list type annotation.
- gpx.utils.has_from_xml(obj_type)¶
Check if a type has a from_xml classmethod.
- gpx.utils.has_to_xml(obj)¶
Check if an object has a to_xml method.
- gpx.utils.parse_from_xml(cls, element)¶
Parse XML element into dictionary by auto-detecting attributes vs elements.
Uses the GPX specification pattern: - Required fields (no | None) are parsed as XML attributes - Optional fields (with | None) are parsed as XML child elements
Supports: - Simple types (str, int, etc.) - Nested models (types with from_xml() method) - Lists of models (list[Model]) - Extensions (special handling for GPX extensions)
- gpx.utils.build_to_xml(obj, element, nsmap=None)¶
Serialize dataclass to XML by auto-detecting attributes vs elements.
Uses the GPX specification pattern: - Required fields (no | None) are serialized as XML attributes - Optional fields (with | None) are serialized as XML child elements
Supports: - Simple types (str, int, etc.) - Nested models (objects with to_xml() method) - Lists of models (list[Model])
- gpx.utils.has_geo_properties(obj, exclude_fields=None)¶
Check if a dataclass instance has any optional fields set (for GeoJSON properties).
This is used to determine whether a GeoJSON representation should be a pure geometry or a Feature with properties.
- gpx.utils.build_geo_properties(obj, exclude_fields=None)¶
Build a GeoJSON properties dictionary from a dataclass instance.
Converts dataclass fields to JSON-serializable values for GeoJSON properties. Excludes specified fields (typically coordinate fields) and only includes optional fields that are set.
- gpx.utils.build_geo_feature(geometry, obj, exclude_fields=None)¶
Build a GeoJSON Feature or pure geometry based on whether properties exist.
If the object has any optional fields set (excluding coordinate fields), returns a Feature with geometry and properties. Otherwise, returns the pure geometry.