{"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":"python","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,"search_vec":"'1.0':38 '1.1':40 '1.6.2':47 'activ':50 'base':22 'common':25 'contribut':56 'creat':11 'current':44 'exchang':14 'file':16,23 'format':15,24 'geospati':65 'gis':64 'gps':13,28,58 'gpx':12,17,37,57 'gpxpi':1,2 'librari':6,34 'maintain':51 'manipul':9 'pars':8 'parser':60 'python':5 'regular':53 'releas':54 'rout':30,63 'support':35 'track':29,61 'use':26 'version':41,46 'waypoint':32,62 'xml':21,59 'xml-base':20","created_at":"2026-04-15T18:37:22.382565+00:00","updated_at":"2026-04-16T15:26:35.523787+00:00","problems":[{"fix":"pip install gpxpy","cause":"The gpxpy library has not been installed in your current Python environment.","error":"ModuleNotFoundError: No module named 'gpxpy'"},{"fix":"Ensure the GPX file is a valid XML file. You might need to open it in a text editor to check for issues like an invalid root tag, unclosed tags, or extraneous characters, especially at the beginning of the file. If you are reading from a file path, ensure you pass a file object, not just the path string, to `gpxpy.parse()` if that's the expected input.","cause":"The GPX file you are trying to parse is malformed, corrupted, or not a valid XML document according to GPX standards. This can also happen if the file is empty or contains unexpected characters at the beginning.","error":"gpxpy.gpx.GPXException: Error parsing XML: not well-formed (invalid token): line X, column Y"},{"fix":"Double-check the file name, its extension, and ensure it is in the correct directory. Provide an absolute path to the file or ensure your script's current working directory is where the file is located.","cause":"The specified GPX file does not exist at the given path, or the path is incorrect.","error":"FileNotFoundError: [Errno 2] No such file or directory: 'your_file.gpx'"},{"fix":"Before accessing attributes like 'offset' on a point's time, check if `point.time` is not `None`. For timezone-aware operations, consider converting `gpxpy`'s `datetime` objects to a standard timezone-aware format (e.g., using `pytz` or Python's `zoneinfo` module for Python 3.9+) before performing calculations or plotting. For example, `if point.time: # process point.time`.","cause":"This error typically occurs when trying to access the 'offset' attribute on a GPX point's time object, but the time object itself is None or has a timezone object that does not support 'offset', often due to naive (timezone-unaware) datetime objects or issues with specific timezone implementations within gpxpy's internal `SimpleTZ` class when interacting with other libraries like matplotlib.","error":"AttributeError: 'NoneType' object has no attribute 'offset'"},{"fix":"Check the GPX version of your file. If it's 1.1, the `speed` attribute is not directly available on `GPXTrackPoint` objects. You can calculate speed manually from consecutive points' time and position data using utility methods like `gpx.get_moving_data()` which calculates speed based on timestamps, or ensure you are working with GPX 1.0 if `speed` is critical.","cause":"The `speed` attribute was part of GPX 1.0 but was removed in GPX 1.1. If you are parsing a GPX 1.1 file, the `point.speed` attribute will be `None`.","error":"point.speed returns None or AttributeError when accessing speed"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.6.2","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/tkrajina/gpxpy","docs":null,"changelog":null,"pypi":"https://pypi.org/project/gpxpy/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["serialization","data"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-06-28","next_check":"2026-07-28","install_tag":null}}