ggps - tcx and gpx file parsing for garmin connect and garmin devices
Project description
ggps
ggps - gps file parsing utilities for garmin connect and garmin devices
Urls
Features
- Parse gpx and tcx files downloaded from Garmin Connect (https://connect.garmin.com)
- Use class TcxHandler to parse TCX files
- contains the Trackpoint data with additional/augmented values, such as:
- "elapsedtime", "elapsedseconds", "altitudefeet", "distancemiles", "distancekilometers", and "cadencex2"
- also includes an event "stats" summary with heartbeat_data and cadence_data sections
- the stats contains value histograms and computed values such as averages
- cadence_data includes run/walk/idle time percentages
- contains the Trackpoint data with additional/augmented values, such as:
- Use class GpxHandler to parse GPX files
- contains the Trackpoint data with additional/augmented values, such as:
- "seq", "elapsedtime", "elapsedseconds"
- contains the Trackpoint data with additional/augmented values, such as:
- Discover the structure of the TCX/GPX/XML files with class PathHandler
Quick start
Installation
$ pip install ggps
Use
Sample Program
See the following sample-program.py in the GitHub repo.
See the data/ directory in the GitHub repo for the sample gpx and tcx files processed by this sample program.
import json
import ggps
def parse_file(infile, handler_type):
print("parsing file: {} type: {}".format(infile, handler_type))
handler = None
opts = dict()
opts["run_walk_separator_cadence"] = 150 # 150 is the default
# opts["no-stats"] = "any value"
if handler_type == "tcx":
handler = ggps.TcxHandler(opts)
elif handler_type == "gpx":
handler = ggps.GpxHandler(opts)
else:
handler = ggps.PathHandler(opts)
handler.parse(infile)
# print(str(handler))
write_json_file(handler)
def write_json_file(handler, pretty=True, verbose=True) -> None:
"""Write the parsed handler data to a file in the same directory, with a .json filetype."""
outfile = "{}.{}.json".format(handler.filename.strip(), handler.handler_type)
jstr = None
if pretty is True:
jstr = json.dumps(handler.get_data(), sort_keys=False, indent=2)
else:
jstr = json.dumps(handler.get_data())
with open(file=outfile, encoding="utf-8", mode="w") as file:
file.write(jstr)
if verbose is True:
print(f"file written: {outfile}")
if __name__ == "__main__":
print("ggps version {}".format(ggps.VERSION))
# Latest files produced in 2024 with Forerunner 265S
parse_file("data/activity_17075053124_lorimer_avinger.tcx", "tcx")
parse_file("data/activity_17075053124_lorimer_avinger.tcx", "path")
parse_file("data/activity_17075053124_lorimer_avinger.gpx", "gpx")
parse_file("data/activity_17075053124_lorimer_avinger.gpx", "path")
# Twin Cities Marathon files
parse_file("data/twin_cities_marathon.tcx", "tcx")
parse_file("data/twin_cities_marathon.tcx", "path")
parse_file("data/twin_cities_marathon.gpx", "gpx")
parse_file("data/twin_cities_marathon.gpx", "path")
# New River 50K files
parse_file("data/new_river_50k.tcx", "tcx")
parse_file("data/new_river_50k.tcx", "path")
parse_file("data/new_river_50k.gpx", "gpx")
parse_file("data/new_river_50k.gpx", "path")
# Davidson Track 5K files
parse_file("data/dav_track_5k.tcx", "tcx")
parse_file("data/dav_track_5k.tcx", "path")
parse_file("data/dav_track_5k.gpx", "gpx")
parse_file("data/dav_track_5k.gpx", "path")
# activity_4564516081 files
parse_file("data/activity_4564516081.tcx", "tcx")
parse_file("data/activity_4564516081.tcx", "path")
parse_file("data/activity_4564516081.gpx", "gpx")
parse_file("data/activity_4564516081.gpx", "path")
# activity_4564516081 files
parse_file("data/activity_607442311.tcx", "tcx")
parse_file("data/activity_607442311.tcx", "path")
parse_file("data/activity_607442311.gpx", "gpx")
parse_file("data/activity_607442311.gpx", "path")
Executing the Sample Program
$ python sample-program.py
Sample Program Output
ggps version 0.5.0
parsing file: data/activity_17075053124_lorimer_avinger.tcx type: tcx
file written: data/activity_17075053124_lorimer_avinger.tcx.tcx.json
parsing file: data/activity_17075053124_lorimer_avinger.tcx type: path
file written: data/activity_17075053124_lorimer_avinger.tcx.path.json
parsing file: data/activity_17075053124_lorimer_avinger.gpx type: gpx
file written: data/activity_17075053124_lorimer_avinger.gpx.gpx.json
parsing file: data/activity_17075053124_lorimer_avinger.gpx type: path
file written: data/activity_17075053124_lorimer_avinger.gpx.path.json
parsing file: data/twin_cities_marathon.tcx type: tcx
file written: data/twin_cities_marathon.tcx.tcx.json
parsing file: data/twin_cities_marathon.tcx type: path
file written: data/twin_cities_marathon.tcx.path.json
parsing file: data/twin_cities_marathon.gpx type: gpx
file written: data/twin_cities_marathon.gpx.gpx.json
parsing file: data/twin_cities_marathon.gpx type: path
file written: data/twin_cities_marathon.gpx.path.json
parsing file: data/new_river_50k.tcx type: tcx
file written: data/new_river_50k.tcx.tcx.json
parsing file: data/new_river_50k.tcx type: path
file written: data/new_river_50k.tcx.path.json
parsing file: data/new_river_50k.gpx type: gpx
file written: data/new_river_50k.gpx.gpx.json
parsing file: data/new_river_50k.gpx type: path
file written: data/new_river_50k.gpx.path.json
parsing file: data/dav_track_5k.tcx type: tcx
file written: data/dav_track_5k.tcx.tcx.json
parsing file: data/dav_track_5k.tcx type: path
file written: data/dav_track_5k.tcx.path.json
parsing file: data/dav_track_5k.gpx type: gpx
file written: data/dav_track_5k.gpx.gpx.json
parsing file: data/dav_track_5k.gpx type: path
file written: data/dav_track_5k.gpx.path.json
parsing file: data/activity_4564516081.tcx type: tcx
file written: data/activity_4564516081.tcx.tcx.json
parsing file: data/activity_4564516081.tcx type: path
file written: data/activity_4564516081.tcx.path.json
parsing file: data/activity_4564516081.gpx type: gpx
file written: data/activity_4564516081.gpx.gpx.json
parsing file: data/activity_4564516081.gpx type: path
file written: data/activity_4564516081.gpx.path.json
parsing file: data/activity_607442311.tcx type: tcx
file written: data/activity_607442311.tcx.tcx.json
parsing file: data/activity_607442311.tcx type: path
file written: data/activity_607442311.tcx.path.json
parsing file: data/activity_607442311.gpx type: gpx
file written: data/activity_607442311.gpx.gpx.json
parsing file: data/activity_607442311.gpx type: path
file written: data/activity_607442311.gpx.path.json
Sample Output File - TcxParser
{
"filename": "data/twin_cities_marathon.tcx",
"ggps_version": "0.5.0",
"ggps_parsed_at": "2024-09-30 09:44:13.594348",
"device_name": "Garmin Forerunner 620",
"device_id": "3875991210",
"trackpoint_count": 2256,
"trackpoints": [
{
"type": "Trackpoint",
"time": "2014-10-05T13:07:53.000Z",
"latitudedegrees": 44.97431952506304,
"longitudedegrees": -93.26310088858008,
"altitudemeters": 259.20001220703125,
"distancemeters": 0.0,
"heartratebpm": 85,
"speed": 0.0,
"cadence": 89,
"altitudefeet": 850.3937408367167,
"distancemiles": 0.0,
"distancekilometers": 0.0,
"cadencex2": 178,
"elapsedtime": "00:00:00",
"seq": 1,
"elapsedseconds": 0.0
},
...
{
"type": "Trackpoint",
"time": "2014-10-05T17:22:17.000Z",
"latitudedegrees": 44.95180849917233,
"longitudedegrees": -93.10493202880025,
"altitudemeters": 263.6000061035156,
"distancemeters": 42635.44921875,
"heartratebpm": 161,
"speed": 3.5460000038146977,
"cadence": 77,
"altitudefeet": 864.8294163501167,
"distancemiles": 26.492439912628992,
"distancekilometers": 42.63544921875,
"cadencex2": 154,
"elapsedtime": "04:14:24",
"seq": 2256,
"elapsedseconds": 15264.0
}
],
"stats": {
"heartbeat_data": {
"histogram": {
"85": 2,
"89": 2,
"90": 2,
"91": 3,
"93": 1,
"96": 2,
"98": 1,
"100": 1,
"104": 1,
"106": 1,
"107": 1,
"108": 3,
"109": 2,
"111": 1,
"112": 1,
"114": 4,
"115": 2,
"116": 1,
"117": 7,
"118": 2,
"119": 3,
"120": 3,
"121": 5,
"122": 3,
"123": 4,
"124": 8,
"125": 15,
"126": 5,
"127": 17,
"128": 22,
"129": 12,
"130": 17,
"131": 23,
"132": 37,
"133": 39,
"134": 34,
"135": 49,
"136": 70,
"137": 82,
"138": 113,
"139": 223,
"140": 221,
"141": 195,
"142": 192,
"143": 124,
"144": 81,
"145": 72,
"146": 75,
"147": 61,
"148": 77,
"149": 55,
"150": 47,
"151": 39,
"152": 32,
"153": 29,
"154": 21,
"155": 12,
"156": 16,
"157": 17,
"158": 8,
"159": 5,
"160": 12,
"161": 8,
"162": 5,
"163": 7,
"164": 3,
"165": 3,
"166": 1,
"167": 4,
"168": 3,
"170": 7
},
"total_readings": 2256,
"highest_bpm": 170,
"average_bpm": 141.18262411347519,
"most_frequent_bpm": 139
},
"cadence_data": {
"histogram": {
"88": 2,
"92": 1,
"94": 4,
"100": 3,
"102": 2,
"104": 3,
"106": 1,
"108": 5,
"110": 7,
"112": 13,
"114": 11,
"116": 19,
"118": 57,
"120": 51,
"122": 30,
"124": 22,
"126": 13,
"128": 8,
"130": 6,
"132": 2,
"134": 2,
"136": 1,
"138": 3,
"140": 2,
"142": 3,
"144": 2,
"146": 3,
"148": 2,
"152": 1,
"154": 1,
"156": 1,
"158": 2,
"160": 2,
"162": 5,
"164": 7,
"166": 62,
"168": 496,
"170": 826,
"172": 380,
"174": 90,
"176": 53,
"178": 24,
"180": 10,
"182": 3,
"184": 7,
"186": 2,
"188": 1,
"234": 1
},
"running_avg_cadence": 170.28571428571428,
"walking_avg_cadence": 119.6978417266187,
"run_walk_separator_cadence": 150,
"total_readings": 2252,
"running_count": 1974,
"walking_count": 278,
"idle_count": 0,
"running_pct": 87.65541740674956,
"walking_pct": 12.344582593250445,
"idle_pct": 0.0
}
}
}
Sample Output File - PathParser
{
"filename": "data/twin_cities_marathon.tcx",
"ggps_version": "0.5.0",
"ggps_parsed_at": "2024-09-30 09:44:14.336540",
"path_counter": {
"TrainingCenterDatabase": 1,
"TrainingCenterDatabase@xsi:schemaLocation": 1,
"TrainingCenterDatabase@xmlns:ns5": 1,
"TrainingCenterDatabase@xmlns:ns3": 1,
"TrainingCenterDatabase@xmlns:ns2": 1,
"TrainingCenterDatabase@xmlns": 1,
"TrainingCenterDatabase@xmlns:xsi": 1,
"TrainingCenterDatabase@xmlns:ns4": 1,
"TrainingCenterDatabase|Activities": 1,
"TrainingCenterDatabase|Activities|Activity": 1,
"TrainingCenterDatabase|Activities|Activity@Sport": 1,
"TrainingCenterDatabase|Activities|Activity|Id": 1,
"TrainingCenterDatabase|Activities|Activity|Lap": 27,
"TrainingCenterDatabase|Activities|Activity|Lap@StartTime": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|TotalTimeSeconds": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|DistanceMeters": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|MaximumSpeed": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|Calories": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|AverageHeartRateBpm": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|AverageHeartRateBpm|Value": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|MaximumHeartRateBpm": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|MaximumHeartRateBpm|Value": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|Intensity": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|TriggerMethod": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|Track": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|Time": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|Position": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|Position|LatitudeDegrees": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|Position|LongitudeDegrees": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|AltitudeMeters": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|DistanceMeters": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|HeartRateBpm": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|HeartRateBpm|Value": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|Extensions": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|Extensions|TPX": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|Extensions|TPX@xmlns": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|Extensions|TPX|Speed": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Track|Trackpoint|Extensions|TPX|RunCadence": 2256,
"TrainingCenterDatabase|Activities|Activity|Lap|Extensions": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|Extensions|LX": 108,
"TrainingCenterDatabase|Activities|Activity|Lap|Extensions|LX@xmlns": 108,
"TrainingCenterDatabase|Activities|Activity|Lap|Extensions|LX|MaxRunCadence": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|Extensions|LX|AvgRunCadence": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|Extensions|LX|AvgSpeed": 27,
"TrainingCenterDatabase|Activities|Activity|Lap|Extensions|LX|Steps": 27,
"TrainingCenterDatabase|Activities|Activity|Creator": 1,
"TrainingCenterDatabase|Activities|Activity|Creator@xsi:type": 1,
"TrainingCenterDatabase|Activities|Activity|Creator|Name": 1,
"TrainingCenterDatabase|Activities|Activity|Creator|UnitId": 1,
"TrainingCenterDatabase|Activities|Activity|Creator|ProductID": 1,
"TrainingCenterDatabase|Activities|Activity|Creator|Version": 1,
"TrainingCenterDatabase|Activities|Activity|Creator|Version|VersionMajor": 1,
"TrainingCenterDatabase|Activities|Activity|Creator|Version|VersionMinor": 1,
"TrainingCenterDatabase|Activities|Activity|Creator|Version|BuildMajor": 1,
"TrainingCenterDatabase|Activities|Activity|Creator|Version|BuildMinor": 1,
"TrainingCenterDatabase|Author": 1,
"TrainingCenterDatabase|Author@xsi:type": 1,
"TrainingCenterDatabase|Author|Name": 1,
"TrainingCenterDatabase|Author|Build": 1,
"TrainingCenterDatabase|Author|Build|Version": 1,
"TrainingCenterDatabase|Author|Build|Version|VersionMajor": 1,
"TrainingCenterDatabase|Author|Build|Version|VersionMinor": 1,
"TrainingCenterDatabase|Author|Build|Version|BuildMajor": 1,
"TrainingCenterDatabase|Author|Build|Version|BuildMinor": 1,
"TrainingCenterDatabase|Author|LangID": 1,
"TrainingCenterDatabase|Author|PartNumber": 1
}
}
Changelog
Current version: 0.5.1
- 2024/10/15, version 0.5.1 Enabled support for python 3.11
- 2024/09/30, version 0.5.0 Output as JSON files with numeric attributes
stats added to TCX output by default with heartbeat_data and cadence_data sections
configurable run_walk_separator_cadence
new sample program
- 2024/09/23, version 0.4.1, Fix pyproject.toml project description
- 2024/09/23, version 0.4.0, Upgraded to python 3.12, pyproject.toml build mechanism, latest m26 >=0.3.1
- 2020/02/22, version 0.3.0, Parsing improvements, normalize 'cadence' and 'heartratebpm' attribute names
- 2020/02/19, version 0.2.1, Upgraded the m26 and Jinga2 libraries
- 2017/09/27, version 0.2.0, Converted to the pytest testing framework
- 2017/09/26, version 0.1.13, packagin.
- 2016/11/07, version 0.1.12, updated packaging
- 2016/11/07, version 0.1.11, updated packaging
- 2016/11/07, version 0.1.10, updated packaging
- 2016/11/07, version 0.1.9, updated packaging
- 2016/11/07, version 0.1.8, updated packaging
- 2016/11/06, version 0.1.7, updated description
- 2016/11/06, version 0.1.6, republished
- 2016/11/06, version 0.1.5, refactored ggps/ dir
- 2016/11/06, version 0.1.4, refactored ggps/ dir. nose2 for tests
- 2015/11/07, version 0.1.3, Added README.rst
- 2015/11/07, version 0.1.1 Initial release
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
ggps-0.5.1.tar.gz
(13.6 kB
view details)
Built Distribution
ggps-0.5.1-py3-none-any.whl
(12.8 kB
view details)
File details
Details for the file ggps-0.5.1.tar.gz
.
File metadata
- Download URL: ggps-0.5.1.tar.gz
- Upload date:
- Size: 13.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5488d05da82a10c5312363a7c0b805e18bd324ded881e66f3ed7575e846fac00 |
|
MD5 | f598ca3e6c380861f380b95226b103b5 |
|
BLAKE2b-256 | 251aa2933214d683ae89a53c5eb0aa1104614fd51717f85e4df424a9495440e9 |
File details
Details for the file ggps-0.5.1-py3-none-any.whl
.
File metadata
- Download URL: ggps-0.5.1-py3-none-any.whl
- Upload date:
- Size: 12.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3d6b6c6986027e65a4b8a46e4a36a944a21535c4db7c7ffc4419339d6814c591 |
|
MD5 | 314ab4defef41d1d19898d5c602d3e36 |
|
BLAKE2b-256 | 9555e2b1dea5b4bbc05fe4f76f8eddf709258ee2c42fcc272340ce4d06ff0b88 |