Skip to main content

gpx is a zero-dependency, pure Python package for reading, manipulating, writing and converting GPX files.

Project description

gpx

PyPI Supported Python Versions CI Test Documentation Status OpenSSF Best Practices

gpx is a zero-dependency, pure Python package for reading, manipulating, writing and converting GPX (GPS Exchange Format) files.

Installation

gpx is available on PyPI. Install with uv or your package manager of choice:

uv add gpx

Documentation

Check out the gpx documentation for the User's Guide, API Reference and CLI Reference.

Usage

Reading a GPX file

from gpx import read_gpx


# Read GPX data from file
gpx = read_gpx("path/to/file.gpx")

# Access basic properties
print(f"Creator: {gpx.creator}")
print(f"Number of waypoints: {len(gpx.wpt)}")
print(f"Number of tracks: {len(gpx.trk)}")
print(f"Number of routes: {len(gpx.rte)}")

Working with waypoints

from decimal import Decimal

from gpx import Latitude, Longitude, Waypoint, read_gpx


# Read GPX data from file
gpx = read_gpx("path/to/file.gpx")

# Create a new waypoint
waypoint = Waypoint(
    lat=Latitude("52.3676"),
    lon=Longitude("4.9041"),
    name="Amsterdam",
    desc="Capital of the Netherlands",
    ele=Decimal("2.0"),
)

# Add waypoint to GPX data
gpx.wpt.append(waypoint)

# Iterate over waypoints
for idx, wpt in enumerate(gpx.wpt):
    print(f"{idx}: ({wpt.lat}, {wpt.lon})")

Working with tracks and statistics

from gpx import read_gpx


# Read GPX data from file
gpx = read_gpx("path/to/file.gpx")

# Access track data
for track in gpx.trk:
    print(f"Track: {track.name}")

    # Get statistics from the track
    print(f"  Total distance: {track.total_distance:.2f} meters")
    print(f"  Total duration: {track.total_duration}")
    print(f"  Average speed: {track.avg_speed:.2f} m/s")
    print(f"  Max elevation: {track.max_elevation} meters")
    print(f"  Total ascent: {track.total_ascent} meters")

    # Iterate over track segments and points
    for track_segment in track.trkseg:
        print(f"  Segment with {len(track_segment.trkpt)} points")
        for track_point in track_segment.trkpt:
            print(
                f"    Point: ({track_point.lat}, {track_point.lon}) at {track_point.time}"
            )

Creating a GPX from scratch

import datetime as dt
from decimal import Decimal

from gpx import (
    GPX,
    Latitude,
    Longitude,
    Metadata,
    Track,
    TrackSegment,
    Waypoint,
)


# Create track points
track_points = []
for i in range(5):
    point = Waypoint(
        lat=Latitude(Decimal("52.0") + i * Decimal("0.01")),
        lon=Longitude(Decimal("4.0") + i * Decimal("0.01")),
        ele=Decimal("10.0") + Decimal(i) * Decimal("2.0"),
        time=dt.datetime.now(dt.UTC),
    )
    track_points.append(point)

# Create a track with segments
track_segment = TrackSegment(trkpt=track_points)
track = Track(name="Morning Run", trkseg=[track_segment])

# Create metadata
metadata = Metadata(
    name="My GPS Track",
    desc="A sample track",
    time=dt.datetime.now(dt.UTC),
)

# Create GPX object (creator defaults to "*gpx*")
gpx = GPX(
    creator="My Application",
    metadata=metadata,
    trk=[track],
)

Writing GPX files

from gpx import from_string


# Write GPX data to file
gpx.write_gpx("output.gpx")

# Convert to string
gpx_string = gpx.to_string()
print(gpx_string)

# Parse from string
gpx = from_string(gpx_string)

Working with routes

from gpx import Latitude, Longitude, Route, Waypoint


# Create route points (waypoints)
route_point_1 = Waypoint(
    lat=Latitude("52.3676"),
    lon=Longitude("4.9041"),
    name="Start: Amsterdam Centraal",
)

route_point_2 = Waypoint(
    lat=Latitude("52.3731"),
    lon=Longitude("4.8922"),
    name="Dam Square",
)

# Create a route
route = Route(name="City Tour", rtept=[route_point_1, route_point_2])
gpx.rte.append(route)

# Access route statistics
print(f"Route distance: {route.total_distance:.2f} meters")

Working with GPX Extensions

gpx supports reading and writing GPX extensions from any namespace, enabling lossless round-trip handling of vendor-specific data like Garmin's TrackPointExtension:

from gpx import read_gpx


# Define extension namespace
GARMIN_TPX = "http://www.garmin.com/xmlschemas/TrackPointExtension/v2"

# Read GPX file with extensions
gpx = read_gpx("activity.gpx")

# Access extension data from track points
for track in gpx.trk:
    for track_segment in track.trkseg:
        for track_point in track_segment.trkpt:
            if track_point.extensions:
                if (
                    hr := track_point.extensions.get_int("hr", namespace=GARMIN_TPX)
                ) is not None:
                    print(f"Heart rate: {hr} bpm")

Creating GPX files with extensions:

import xml.etree.ElementTree as ET
from decimal import Decimal

from gpx import (
    Extensions,
    GPX,
    Latitude,
    Longitude,
    Track,
    TrackSegment,
    Waypoint,
)


# Register namespace prefix for cleaner XML output
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 = "145"

# Create waypoint with extensions
point = Waypoint(
    lat=Latitude("52.0"),
    lon=Longitude("4.0"),
    extensions=Extensions(elements=[tpx]),
)

# Build GPX with the point
gpx = GPX(trk=[Track(trkseg=[TrackSegment(trkpt=[point])])])
gpx.write_gpx("with_extensions.gpx")

Converting to other formats

gpx supports converting GPX data to various formats:

from gpx import GPX, read_gpx


gpx = read_gpx("path/to/file.gpx")

# Write to file formats
gpx.write_gpx("output.gpx")  # GPX file
gpx.write_geojson("output.geojson")  # GeoJSON file
gpx.write_kml("output.kml")  # KML file (Google Earth)

# Convert to data formats (strings/bytes)
wkt_string = gpx.to_wkt()  # Well-Known Text
wkb_bytes = gpx.to_wkb()  # Well-Known Binary

# Access GeoJSON-compatible data via the __geo_interface__ property
geojson_dict = gpx.__geo_interface__

Reading from other file formats

gpx can read data from various file formats:

from gpx import read_gpx, read_geojson, read_kml


# Read from files
gpx = read_gpx("path/to/file.gpx")
gpx = read_geojson("path/to/file.geojson")
gpx = read_kml("path/to/file.kml")

Converting from data formats

gpx can convert from data formats (strings, bytes, objects):

from gpx import from_geo_interface, from_wkt, from_wkb


# Convert from WKT (Well-Known Text)
gpx = from_wkt("POINT (4.9041 52.3676)")
gpx = from_wkt("LINESTRING (4.9 52.3, 4.91 52.31, 4.92 52.32)")

# Convert from WKB (Well-Known Binary)
gpx = from_wkb(wkb_bytes)

# Convert from any object that implements the __geo_interface__ protocol (e.g., Shapely)
from shapely.geometry import Point, LineString

point = Point(4.9041, 52.3676)
gpx = from_geo_interface(point)

line = LineString([(4.9, 52.3), (4.91, 52.31), (4.92, 52.32)])
gpx = from_geo_interface(line)

# Or convert from a GeoJSON dict directly
geojson = {"type": "Point", "coordinates": [4.9041, 52.3676]}
gpx = from_geo_interface(geojson)

Command-Line Interface

gpx provides a command-line interface (CLI) for common GPX operations:

# Validate a GPX file
gpx validate path/to/file.gpx

# Show information and statistics about a GPX file
gpx info path/to/file.gpx
gpx info --json path/to/file.gpx  # Output as JSON

# Edit a GPX file
gpx edit input.gpx -o output.gpx --reverse-tracks
gpx edit input.gpx -o output.gpx --min-lat 52.0 --max-lat 53.0
gpx edit input.gpx -o output.gpx --start 2024-01-01T10:00:00 --end 2024-01-01T12:00:00
gpx edit input.gpx -o output.gpx --precision 5 --elevation-precision 1
gpx edit input.gpx -o output.gpx --strip-all-metadata

# Merge multiple GPX files
gpx merge file1.gpx file2.gpx file3.gpx -o merged.gpx

# Convert between formats
gpx convert input.gpx -o output.geojson
gpx convert input.gpx -o output.kml
gpx convert input.geojson -o output.gpx

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gpx-2026.2.0.tar.gz (64.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gpx-2026.2.0-py3-none-any.whl (59.2 kB view details)

Uploaded Python 3

File details

Details for the file gpx-2026.2.0.tar.gz.

File metadata

  • Download URL: gpx-2026.2.0.tar.gz
  • Upload date:
  • Size: 64.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for gpx-2026.2.0.tar.gz
Algorithm Hash digest
SHA256 2062ffaf355aaf4ec68a8696e8849b7e2d687da7662a61b7cda300fddcd5088a
MD5 fcc4b2454cb121012c6a21c8a08075f8
BLAKE2b-256 a19307a8d947a7d565966668f4fd0a96d30948cd4df48d971ecdf314f8d5cc85

See more details on using hashes here.

File details

Details for the file gpx-2026.2.0-py3-none-any.whl.

File metadata

  • Download URL: gpx-2026.2.0-py3-none-any.whl
  • Upload date:
  • Size: 59.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for gpx-2026.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8192773bfaf7524c99dd6dd2d2074f4cff46112706069fb71f14ea8b9bff0fbb
MD5 0b696f14dca26fb6900ad962ac0b171a
BLAKE2b-256 ee7c448e976bbcec495a903fde81186d1adb7304e1ea032969bcb9d125fe0607

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page