Guides & How-tos

What a Workout File Holds: TCX, GPS Tracks and the Data Past the Coordinates

A training file records far more than a route: laps, heart rate, cadence and power all sit alongside the positions. Here is which of it reaches a map format and which of it quietly does not.

Guides & How-tosUpdated Version 2026.086 min readNovus Convert Team
A Garmin TCX activity with laps, heart rate and cadence converting into a GeoJSON LineString that keeps the route and drops the lap summaries.

Exporting a run from a watch gives you a file that is mostly not about geography. The coordinates are there, but so is the structure of the effort: where the laps fell, what your heart was doing at each sample, how fast your legs were turning over. Converting it into something a map can draw is easy. Knowing what the map format cannot hold is the part worth a few minutes.

TCX is a fitness format first#

Garmin introduced Training Center XML in the mid-2000s for a simple reason: GPX knew about position and time and nothing else. Laps, heart rate and intensity had to be bolted on as extensions, so Garmin wrote a schema where they are defined elements instead. The hierarchy is stricter than GPX's:

  • Activity carries an Id and a Sport attribute, one of Running, Biking or Other, which shapes how a platform interprets everything inside it.
  • Lap has a StartTime and a set of aggregates: TotalTimeSeconds, DistanceMeters, Calories, and average and maximum heart rate.
  • Track groups the samples, and one lap can hold more than one track where recording was paused and resumed.
  • Trackpoint is the sample itself: a Time, a Position, an AltitudeMeters, a cumulative DistanceMeters, a HeartRateBpm and a Cadence. Power and newer metrics arrive through a namespaced extension.

GeoJSON is a mapping format, and only that#

RFC 7946 defines a small vocabulary: geometries, features that pair a geometry with a free-form properties object, and collections of features. It mandates WGS 84 and removed the coordinate-reference-system member earlier drafts allowed, so two GeoJSON files can never disagree about what their numbers mean. There is no time dimension in the specification, no sensor reading, and no notion of a lap.

What crosses, and what does not#

Each TCX track becomes one GeoJSON feature: a LineString, or a Point where the track holds a single sample. The route, the altitudes and the identifying fields come with it, and the per-sample series travel in the properties object as arrays lined up one-to-one with the coordinates. That arrangement is a convention rather than something the specification blesses, so plenty of mapping tools draw the line and ignore the arrays entirely.

  • Survives: the coordinates, the altitude where present, the activity identifier, the sport, each lap's start time, and the per-point time, distance, heart-rate and cadence series.
  • Does not survive: the lap aggregates. TotalTimeSeconds, Calories and the per-lap average and maximum heart rate are not carried across.
  • Does not survive: vendor extension fields, where power, running cadence and most newer metrics live.
  • Does not survive a GPX or KML target: the distance, heart-rate and cadence series are dropped. GPX keeps the trackpoint timestamps; KML keeps geometry and simple scalar properties only.

So the target is a real decision. Convert TCX to GeoJSON when the destination is a web map or analysis code, and convert TCX to GPX when it is another device or a route planner. Keep the original .tcx either way: it is the only file that still has the laps in it.

The samples with no position#

A watch keeps recording while it looks for satellites, so the start of a workout is often a run of trackpoints with a time and a heart rate and no Position element. There is nothing a geometry can do with those, so they are skipped, and a conversion should say how many it dropped rather than silently shortening the track. A treadmill session can be almost entirely made of them, which is why an indoor run sometimes converts to a file with no geometry at all.

Checking the result#

  1. Open the output on a map first. A transposed or zeroed coordinate is obvious visually and invisible in the text.
  2. Compare the point count against the original. A large drop means trackpoints without a fix were skipped.
  3. Check the bounding box. The route should sit where you ran, and an output whose extent has changed has lost or gained geometry.
  4. Do not expect calories or lap averages anywhere. Read them from the original file or the platform that produced it.

The output here is reopened and re-parsed after it is written, and the coordinate count, geometry counts and bounding box are compared against the source, so a conversion that lost geometry fails rather than downloads. The wider habit is in verifying conversion results, and our guide to GeoJSON, KML and GPX covers how the three formats relate. Tracks already in GPX take the shorter road through GPX to GeoJSON.

Troubleshooting

The track appears off the coast of Africa

A coordinate pair has become zeroes, or latitude and longitude have been swapped. GeoJSON writes longitude first, unlike most fitness tools, so check the axis order in whatever produced or consumed the file.

The converted file has far fewer points than the workout

Trackpoints without a Position element are skipped, because a geometry cannot use them. This is normal at the start of a session while the watch acquires satellites, and near-total on an indoor activity.

Calories and lap averages are missing

Lap aggregates are TCX concepts with no equivalent in GeoJSON, GPX or KML, so they are not carried across. Read them from the original .tcx, which is the reason to keep it.

Heart rate and cadence vanished in the GPX output

The per-sample sensor series are written to GeoJSON properties only. GPX output keeps trackpoint timestamps and drops the rest, and KML keeps geometry with simple scalar properties. Convert to GeoJSON when the sensor data matters.

A mapping tool draws the route but shows none of the extra data

The per-point series ride in the feature's properties as arrays aligned to the coordinates. That is a convention, not part of RFC 7946, so many readers display the geometry and ignore them.

Frequently asked questions

Why use TCX instead of GPX in the first place?

GPX describes position and time, and everything else is an extension. TCX has laps, heart rate, cadence and calories as defined schema elements, so training data survives a round trip between devices and platforms intact.

Does converting to GeoJSON keep my heart rate?

The per-sample series are written into the feature properties as arrays lined up with the coordinates, so the values are there. Whether a given map tool shows them is another matter, since the specification has no place for time-series data.

What happens to the laps?

Each lap's tracks become separate features carrying the lap start time, so the boundaries are visible. The lap summaries, meaning total time, distance, calories and average and maximum heart rate, are not converted.

Why is latitude and longitude order such a problem?

GeoJSON writes [longitude, latitude] while most fitness and mapping formats put latitude first. Swapped axes produce a file that is structurally perfect and geographically nonsense, and the only reliable check is looking at a map.

Is my activity data uploaded?

No. The file is parsed and rewritten in your browser. That matters here more than for most formats, because a workout file is a dated record of where a specific person was, usually starting and ending at home.

Related workflows and tools

Sources and further reading