{"id":6658,"library":"gpxpy","title":"gpxpy","description":"gpxpy is a Python library for parsing, manipulating, and creating GPX (GPS eXchange Format) files. GPX is an XML-based file format commonly used for GPS tracks, routes, and waypoints. The library supports both GPX 1.0 and 1.1 versions. It is currently at version 1.6.2 and is actively maintained, with regular releases and contributions.","status":"active","version":"1.6.2","language":"en","source_language":"en","source_url":"https://github.com/tkrajina/gpxpy","tags":["gpx","gps","xml","parser","track","waypoint","route","gis","geospatial"],"install":[{"cmd":"pip install gpxpy","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Optional dependency for faster XML parsing; if not present, minidom is used.","package":"lxml","optional":true}],"imports":[{"symbol":"gpxpy","correct":"import gpxpy"},{"note":"While individual classes can be imported, `import gpxpy.gpx` is often used when creating new GPX objects for clarity.","wrong":"from gpxpy import GPX, GPXTrack, GPXTrackSegment, GPXTrackPoint","symbol":"gpxpy.gpx","correct":"import gpxpy.gpx"}],"quickstart":{"code":"import gpxpy\nimport gpxpy.gpx\nimport os\n\n# Create a dummy GPX file for demonstration\ndummy_gpx_content = \"\"\"\n<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" creator=\"gpxpy\" version=\"1.1\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">\n  <trk>\n    <name>Example Track</name>\n    <trkseg>\n      <trkpt lat=\"48.123\" lon=\"11.456\">\n        <ele>500.0</ele>\n        <time>2023-01-01T10:00:00Z</time>\n      </trkpt>\n      <trkpt lat=\"48.124\" lon=\"11.457\">\n        <ele>505.0</ele>\n        <time>2023-01-01T10:01:00Z</time>\n      </trkpt>\n    </trkseg>\n  </trk>\n  <wpt lat=\"48.125\" lon=\"11.458\">\n    <name>Example Waypoint</name>\n  </wpt>\n</gpx>\n\"\"\"\n\ndummy_gpx_filename = \"example.gpx\"\nwith open(dummy_gpx_filename, \"w\") as f:\n    f.write(dummy_gpx_content)\n\ntry:\n    # Parsing an existing GPX file\n    with open(dummy_gpx_filename, 'r') as gpx_file:\n        gpx = gpxpy.parse(gpx_file)\n\n    print(f\"GPX parsed successfully. Version: {gpx.version}\")\n\n    for track_idx, track in enumerate(gpx.tracks):\n        print(f\"  Track {track_idx + 1}: {track.name or 'Unnamed Track'}\")\n        for segment_idx, segment in enumerate(track.segments):\n            print(f\"    Segment {segment_idx + 1}: {len(segment.points)} points\")\n            for point_idx, point in enumerate(segment.points):\n                print(f\"      Point {point_idx + 1}: Lat={point.latitude}, Lon={point.longitude}, Ele={point.elevation}, Time={point.time}\")\n\n    for wpt_idx, waypoint in enumerate(gpx.waypoints):\n        print(f\"  Waypoint {wpt_idx + 1}: {waypoint.name or 'Unnamed Waypoint'} at Lat={waypoint.latitude}, Lon={waypoint.longitude}\")\n\n    # Getting some statistics\n    if gpx.has_points():\n        moving_data = gpx.get_moving_data()\n        print(f\"Total distance: {gpx.length_3d()/1000:.2f} km\")\n        print(f\"Max speed: {moving_data.max_speed * 3.6:.2f} km/h (filtered)\")\n        print(f\"Total uphill: {gpx.get_uphill_downhill().uphill:.2f} m\")\n        print(f\"Total downhill: {gpx.get_uphill_downhill().downhill:.2f} m\")\n\n    # Creating a new GPX file programmatically\n    new_gpx = gpxpy.gpx.GPX()\n    new_track = gpxpy.gpx.GPXTrack()\n    new_gpx.tracks.append(new_track)\n    new_segment = gpxpy.gpx.GPXTrackSegment()\n    new_track.segments.append(new_segment)\n    new_segment.points.append(gpxpy.gpx.GPXTrackPoint(48.2, 11.5, elevation=550, time='2023-01-01T11:00:00Z'))\n    new_segment.points.append(gpxpy.gpx.GPXTrackPoint(48.21, 11.51, elevation=560, time='2023-01-01T11:05:00Z'))\n\n    print(\"\\nGenerated new GPX content:\")\n    print(new_gpx.to_xml())\n\nfinally:\n    # Clean up the dummy file\n    if os.path.exists(dummy_gpx_filename):\n        os.remove(dummy_gpx_filename)\n","lang":"python","description":"This quickstart demonstrates how to parse an existing GPX file, iterate through its tracks, segments, and points, extract basic statistics, and programmatically create a new GPX structure with tracks and points. It also includes cleanup for the created dummy file."},"warnings":[{"fix":"Always open the GPX file first and pass the file object: `with open('your_file.gpx', 'r') as f: gpx = gpxpy.parse(f)`.","message":"The `gpxpy.parse()` function expects a file-like object, not a file path string. Passing a path directly can lead to `xml.etree.ElementTree.ParseError: not well-formed (invalid token)` errors.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Be aware of the GPX version when parsing and serializing. Use `gpx.to_xml(version='1.0')` or `gpx.to_xml(version='1.1')` to explicitly control the output version. For custom data, utilize GPX extensions.","message":"The `gpxpy` object model is not 100% equivalent to the GPX XML schema, particularly between GPX 1.0 and 1.1. Attributes like 'speed' (present in GPX 1.0 but removed in 1.1) might be lost or handled inconsistently if you parse one version and serialize to another without explicit management (e.g., using extensions or forcing version).","severity":"gotcha","affected_versions":"All versions"},{"fix":"If you need raw, unfiltered data for speed calculations, use `gpx.get_moving_data(raw=True)`. Understand that other statistical methods might also apply internal filtering.","message":"When calculating statistics like `max_speed` or `uphill/downhill`, `gpxpy` applies heuristics to filter out common GPS errors (e.g., removing top 5% of speeds or points with non-standard distances). The raw data might differ.","severity":"gotcha","affected_versions":"All versions"},{"fix":"When working with extensions, inspect the `gpx.extensions`, `point.extensions`, etc., to ensure data is retained as expected, especially after modification or serialization across different GPX versions. Test round-tripping for critical extension data.","message":"GPX extensions (custom XML elements within the GPX structure) are preserved as `ElementTree` DOM objects. However, they might be ignored when serializing a GPX 1.1 object to a GPX 1.0 file, and there have been reports of extension data being lost or not properly outputted during read/write operations if not handled carefully.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure that string inputs for GPX fields adhere to the GPX specification's format requirements if strict schema validation is required for target applications. Most applications are tolerant, but validation errors can occur.","message":"Generated GPX XML, while always a valid XML document, may not always be a strictly valid GPX document if certain string fields (e.g., `gpx.email`) do not conform to the expected regex patterns defined by the GPX schema.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z","problems":[]}