Changelog¶
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and this project adheres to Calendar Versioning.
The first number of the version is the year. The second number is incremented with each release, starting at 1 for each year. The third number is for emergencies when we need to start branches for older releases.
2026.2.0 - 2026-04-27¶
Added¶
GPX Extensions support: Added
Extensionsclass for handling GPX extension elements from any XML namespace (e.g., Garmin’sTrackPointExtension). Extensions are now parsed, preserved, and serialized during round-trip processing, enabling lossless handling of vendor-specific data like heart rate, cadence, temperature, etc.New
extensionsfield on all models that support extensions per the GPX 1.1 spec:GPX,Metadata,Waypoint,Track,TrackSegment, andRoute.
Changed¶
Tracknow inherits fromPointsMixinand reuses its bounds and elevation aggregations (bounds,_points_with_ele,_eles,avg_elevation,min_elevation,max_elevation,diff_elevation,avg_speed,avg_moving_speed), eliminating duplication betweenTrackand the segment/route mixin. Per-segment semantics are preserved for distance, duration, speed extremes, ascent/descent and the elevation profile by overriding only those properties.intandboolfields in__geo_interface__properties (e.g.Waypoint.sat,Track.number,Route.number) now keep their JSON-native types.
Removed¶
Removed obsolete
remove_encoding_from_stringfunction.
Fixed¶
EWKB format parsing now correctly handles Z coordinates by checking the EWKB flag before the ISO WKB flag.
gpx editno longer drops custom XML namespace prefixes (e.g.gpxtpx,gpxx) from the source file. All edit transformations (crop, trim, reverse, precision, strip metadata) now propagatensmapso round-trips preserve the original prefixes.gpx edit --min-lat 0(and the other crop bounds) is no longer silently ignored.Track.elevation_profileno longer skips the first elevation-bearing point of segments after the first, and no longer raisesIndexErrorfor tracks with no segments or no points with elevation.PointsMixin.elevation_profile(used byRouteandTrackSegment) similarly returns[]for empty inputs instead of crashing.Waypoint.speed_tono longer raisesZeroDivisionErrorwhen two waypoints share a timestamp (or either lacks one); it returns0.0instead. This also fixes downstream crashes inPointsMixin._speeds,max_speed,min_speed,moving_duration, andspeed_profilefor tracks containing consecutive points with identical timestamps.Waypoint.slope_tosimilarly returnsDecimal(0)instead of raisingZeroDivisionErrorwhen two waypoints share coordinates.
2026.1.0 - 2026-01-07¶
Added¶
New
climodule with command-line interface (CLI) for common GPX operations:gpx validate: Validate a GPX filegpx info: Show information and statistics about a GPX filegpx edit: Edit a GPX file with various transformations:Crop to a geographic bounding box (
--min-lat,--min-lon,--max-lat,--max-lon)Trim to a date/time range (
--start,--end)Reverse routes and/or tracks (
--reverse,--reverse-routes,--reverse-tracks)Strip metadata fields (
--strip-name,--strip-desc,--strip-author,--strip-copyright,--strip-time,--strip-keywords,--strip-links,--strip-all-metadata)Reduce coordinate precision (
--precision,--elevation-precision)
gpx merge: Merge multiple GPX files into onegpx convert: Convert between GPX, GeoJSON, and KML formats
New CLI reference documentation page with auto-generated help output using
cogNew
iomodule withread_*()functions for reading file formats:read_gpx(): Read GPX filesread_geojson(): Read GeoJSON filesread_kml(): Read KML files
New
convertmodule withfrom_*()functions for converting from data formats:from_string(): Convert from a GPX stringfrom_geo_interface(): Convert from objects that implement the__geo_interface__protocol (e.g., Shapely)from_wkb(): Convert from Well-Known Binary bytesfrom_wkt(): Convert from Well-Known Text strings
New
write_*()methods on theGPXclass for writing to file formats:write_gpx(): Write to GPX file (renamed fromto_file())write_geojson(): Write to GeoJSON filewrite_kml(): Write to KML file (Google Earth format)
New
to_*()methods on theGPXclass for converting to data formats:to_wkt(): Convert to Well-Known Text (OGC standard)to_wkb(): Convert to Well-Known Binary (OGC standard)
Changed¶
Renamed
GPX.to_file()toGPX.write_gpx()for consistency with other write methods.Replaced built-in
tempfilemodule usage with pytest’stmp_pathandtmp_path_factoryfixtures in the test suite for better test isolation and automatic cleanup.
Removed¶
All aliases and proxies.
GPX.from_file()method in favor ofio.read_gpx().GPX.from_string()method in favor ofconvert.from_string().
2025.1.0 - 2025-11-29¶
This is a major release with a lot of breaking changes, primarily due to a complete rewrite of the architecture, and a general modernization of the package. Besides the change in architecture, this release adds comprehensive unit tests, enforces strict linting rules, and drops support folder older versions of Python. Finally, this release implements the __geo_interface__ protocol for all GPX elements that contain geopgraphic information, thus adding support for converting to GeoJSON.
Migration notes for users upgrading from 0.2.x:
Ensure you are using Python 3.11 or higher
Update constructor calls to use keyword arguments for optional parameters
Update field names to use GPX-standard names (e.g.,
trkseginstead oftrksegs)Remove
validate=Truefromfrom_file()andfrom_string()callsUpdate error handling to catch standard Python exceptions instead of
gpx.errors.ParseError
Example:
# Before (0.2.x)
from gpx import GPX, Waypoint
gpx = GPX.from_file("path/to/track.gpx", validate=True)
waypoint = Waypoint()
waypoint.lat = Decimal("52.0")
waypoint.lon = Decimal("4.0")
waypoint.name = "Amsterdam"
gpx.waypoints.append(waypoint)
# After (2025.1.0)
from gpx import GPX, Waypoint
from decimal import Decimal
gpx = GPX.from_file("path/to/track.gpx")
waypoint = Waypoint(Decimal("52.0"), Decimal("4.0"), name="Amsterdam")
gpx.wpt.append(waypoint)
Added¶
CLAUDE.mdfor easier interoperability with Claude Code.Comprehensive unit tests.
Smoke test.
Testing workflow via GitHub Actions.
Support for Python 3.12, 3.13 and 3.14.
More usage examples in
README.md.__geo_interface__protocol for all GPX elements that contain geographic information.
Changed¶
Upgraded the
pre-commithooks.Enabled ALL rules for the
rufflinter by default.Use the
uvbuild backend instead offlit.Updated the installation instructions to make use of
uvinstead ofpip.Switched the versioning scheme from semantic versioning to Calendar Versioning.
Refactored the GPX element classes into
dataclass-based models.Replaced
lxmlwith the built-inElementTreemodule.Optional dependencies to dependency groups.
Renamed
PyGPXtogpx(purely aesthetically, no changes in installation or usage required).
Removed¶
Support for Python 3.7, 3.8, 3.9 and 3.10.
The errors module.
Fixed¶
Erroneous examples in the usage examples in
README.md.
0.2.1 (2023-04-09)¶
Fixed¶
Serialization of route and track numbers. #10
Mutable default values. #11
0.2.0 (2023-04-06)¶
With this release, PyGPX is now fully [1] compatible with the GPX 1.1 specification.
Changes¶
Added the following new modules and classes:
gpx.element.Elementgpx.mixins.AttributesMutableMappingMixingpx.mixins.PointsSequenceMixingpx.mixins.PointsMutableSequenceMixin
All element classes now inherit from the new
gpx.element.Elementbase class.All element classes now make use of the new element / type classes (e.g.
gpx.types.Latitude), according to the GPX 1.1 specification.Added the
gpx.errors.ParseErrorexception for when attempting to parse an XML element that does not exist.All metadata attributes have been moved to the new
gpx.metadata.Metadataclass, but are still accessible via thegpx.gpx.GPXclass via aliases for backwards compatibility and convenience.Changed all
durationattributes todatetime.timedeltaobjects (instead offloats).
0.1.1 (2023-03-31)¶
This release introduces a completely overhauled codebase. For this, I used my cookiecutter-python-package Python package template. As such, this release comes with much higher code quality, documentation and automation.
The API itself has not changed (and as such, there is no minor version bump).
Changes¶
Completely refactored codebase, with:
Moved source code from
./gpxto./src/gpxFully typed and documented
Added documentation via Read the Docs
Updated CI/CD via GitHub Actions
Added pre-commit hooks w/ CI-integration
0.1.0 (2021-06-08)¶
Changes¶
Initial release of PyGPX