Convert TCX to KML

Converting TCX to KML keeps the shape of a session and discards the rest of it. Heart rate, cadence, power, laps, calories and even the timestamps have no place in a Google Earth LineString, so what you get is a line over terrain with the sport as its label. That is enough for looking at a route and not enough for anything else.

  • Where it runs In your browser. The file is never uploaded.
  • Rebuilt KML works differently from a TCX, so this is not the gradual degradation a lossy codec applies. What KML can express is reproduced faithfully; what it has no equivalent for does not survive at all.
  • File size limit Up to 100 MB per file, free, without an account.
  • Worth knowing Positions, elevation and timestamps are carried across. Sensor streams, styling and embedded imagery are not.

Up to 100 files at once. Mixed formats are fine.

This is a conversion into a picture, and it should be treated as one

A TCX is dense. Every second of a session it records a position, an altitude, a running distance, a heart rate, often a cadence and a power figure, grouped into laps that each declare their own duration, distance, calorie total and heart-rate averages. It is the most information-rich file most athletes ever own.

A KML LineString is a list of coordinates. That is the entire destination, and the conversion is therefore not a translation but a reduction: one stream out of eight or nine survives, and the structure around it does not. Done for the right reason — you want to see the valley the climb went up, or put a route in front of somebody who has never been there — that is exactly the right amount of data. Done in the belief that a Google Earth file is a portable copy of a workout, it throws away the workout.

The streams that end at the conversion

Per trackpoint: `<HeartRateBpm>`, `<Cadence>`, `<DistanceMeters>` and the `<Extensions>` block that carries watts and running cadence. Per lap: the total time, the distance, the maximum speed, the calories, the average and maximum heart rate, the intensity and the trigger method. Per activity: the lap divisions themselves and any block naming the device that recorded it.

What crosses over is the position of each point and its `<AltitudeMeters>`, which becomes the third value of the coordinate. The reason is structural rather than a limitation of effort: KML models a drawing, and a drawing has geometry and appearance and no concept of a measurement taken at a moment. There is no element that could hold a heart rate, so there is no version of this conversion that keeps one.

Even the clock is left behind

The timestamps go too, which surprises people more than the sensor data does. A LineString stores coordinates and nothing else, so the `<Time>` on every TCX trackpoint is dropped and the KML records where the line went without recording when any part of it was reached.

The visible consequence in Google Earth is that the time slider — the control that lets you scrub through a track and watch it draw itself — does not appear for the file. That animation is driven by a `gx:Track` element with parallel `<when>` values, and this conversion writes a plain LineString. If replaying the session is what you were after, the conversion that keeps time is TCX to GPX, and Google Earth will open a GPX directly.

Seeing the terrain, which is the honest reason to do this

What Google Earth gives you that a two-dimensional map does not is relief. Tilt the view and the climb you remember as long becomes a shape with a gradient, the descent has a wall on one side, and a course you have never ridden stops being an abstraction. For a race report, a recce, or explaining to somebody why a segment hurt, that is genuinely useful and nothing in the discarded data would have helped.

The line is written with a tessellation flag set, which tells the renderer to subdivide each segment and follow the ground between vertices. Without it, a straight segment across a valley passes underneath the surface and the track vanishes into the hillside — the failure looks like a broken file and is a rendering artefact. With it on, the route stays visible along its whole length, which is the only way the terrain view is worth having.

Altitude is written into the file and drawn on the ground

Each coordinate is a triple, and the third value carries the altitude from `<AltitudeMeters>` in metres. The elevation profile of the session is therefore present in the KML, and software reading it as data will find it.

Google Earth will not draw it, because no `<altitudeMode>` is declared and the default is to clamp the line to the terrain. For a GPS track that default is right: barometric and satellite altitude both wander by tens of metres, and a line floating raggedly above a ridge looks like an error rather than a measurement. Adding `<altitudeMode>absolute</altitudeMode>` to the LineString by hand will lift it into the air if you want to see how badly the receiver was drifting, which is occasionally instructive and never flattering.

The straight jumps where the receiver lost the sky

A trackpoint with no `<Position>` cannot become a coordinate and is dropped. Watches keep sampling heart rate through tunnels, underpasses and multi-storey car parks, so those stretches exist in the TCX as valid points with a time and no location — and in the KML they exist as nothing at all.

On the globe that appears as a straight line between the last fix before the obstruction and the first one after it, cutting across whatever lies between. It is not corruption and there is nothing to repair; the file never held the intervening positions. An indoor session, where no point has a fix, produces no geometry whatsoever and the conversion reports that no track or waypoints were found, which is the correct description of a workout that did not go anywhere.

The sport is the only label available

Each activity becomes one Placemark, and its name comes from the `Sport` attribute — restricted by the TCX schema to a short list, so in practice `Running`, `Biking` or `Other`. That is what appears in the Google Earth sidebar.

The title you gave the session in Garmin Connect or Strava belongs to that platform's database and is not part of the export, so it cannot be carried across. When several sessions end up in the same Earth project the sidebar becomes a column of identical words, and renaming the `<name>` element in the KML afterwards is the fix — a one-line edit per placemark, and the file is plain text specifically so that such edits are trivial.

Laps disappear, and with them the shape of the session

Lap boundaries are flattened into one continuous line. A KML placemark has no notion of a division within a line, so twelve intervals and one steady effort produce visually identical geometry, and nothing on the map marks where a repetition started or ended.

If the point of showing the route is to explain the structure of the workout, that has to be done another way — separate placemarks drawn by hand in Google Earth, or annotations added afterwards. Splitting the TCX into one activity per interval before converting will produce separate lines, but the effort involved is usually larger than simply saying which part of the map was the hard bit.

The same applies to anything else the file knew and the map does not. Where the wind turned, where the group split, where the mechanical happened: none of it is encoded in a line, and Google Earth offers no way to derive it. A placemark dropped at the spot with a two-line description does more for a reader than any amount of geometry, and it takes a few seconds once the file is already open.

A much smaller file, for a clear reason

Measured on a 7,200-point track carrying time and altitude, a TCX in this shape came to about 2.2 MB and the equivalent KML to about 258 KB — roughly 315 bytes a trackpoint against 36 for a coordinate. A real Garmin export with heart rate and cadence on every point is larger still, so the shrink in practice is usually more than a factor of eight.

None of that saving is compression, and reading it as efficiency would be the wrong conclusion. It is a fairly direct measurement of what the file no longer contains: the tag names, the timestamps and the sensor values. If the smaller file is what you wanted, that is fine — just keep the TCX, because the KML cannot be converted back into it.

A session map made without handing over the session

The TCX is parsed and the KML written in this browser tab. No request carries the file anywhere, which the network panel confirms while a conversion runs, and the page works with the connection off once loaded.

The file being converted is health data and location data in one document — heart rate against time, position against time, usually starting at the athlete's front door. The output is less exposing, since the sensor streams and the clock are gone, but the route still traces a life. Producing the map locally means the richer original never leaves the machine on the way to becoming the poorer picture.

How to convert TCX to KML

  1. Drop your TCX file onto this page, or click to choose one.
  2. The positioned trackpoints are drawn into a KML line in your browser.
  3. Download the KML and open it in Google Earth to tilt the view.

A TCX training record reduced to a KML line

TCX compared with KML
TCXKML
Full nameTraining Center XMLKeyhole Markup Language
File extension.tcx.kml
Media typeapplication/vnd.garmin.tcx+xmlapplication/vnd.google-earth.kml+xml
First published2007
Published byGarminKeyhole
SpecificationTraining Center XMLOGC KML 2.3
LicensingPublished, not standardisedOpen standard
Standing todayCurrentCurrent
Opens in a browserNo browserNo browser
Considered insteadGPX, FITKMZ, GPX

Opening the result

The usual programs do not overlap: TCX opens in Garmin Connect, Strava and TrainingPeaks, KML in Google Earth, QGIS and ArcGIS — so whoever receives the result needs something from the second list.

What each format is for

The two are aimed at different work: TCX at fitness tracking, KML at mapping. That is worth weighing before converting, because the reason one exists is usually the reason the other is awkward.

TCX is Garmin's format, published in 2007. The specification is Training Center XML, and it is worth reading if the file has to outlive the tool that wrote it.

KML comes from Keyhole, specified as OGC KML 2.3. Google Earth, QGIS and ArcGIS all read it.

TCX to KML: what Google Earth shows of a workout

Are my TCX files uploaded anywhere?

No. This conversion runs entirely inside your browser, so the file never leaves your device. You can confirm it yourself: open the network tab of your browser's developer tools and convert something. You will see the page load, plus the analytics and advertising the site is paid for with — and nothing carrying your file.

What survives from the TCX?

The positions and their altitudes, plus the sport as a label. Heart rate, cadence, power, per-point distance, calories, laps and timestamps are all left behind.

Will Google Earth replay the ride over time?

No. The track is written as a LineString, which has no time information, so the time slider does not appear. Only a gx:Track would give you that, and this conversion does not write one.

Why does the route sit on the ground rather than in the air?

Because no altitudeMode is declared, so Google Earth applies its default and clamps the line to the terrain. The altitude values are in the file; the display ignores them.

Why are there gaps in the line?

Trackpoints without a position are dropped, and a watch records them whenever the GPS has no fix. A tunnel or an underpass becomes a straight jump across the map.

What will the placemark be called?

The activity's sport — `Running`, `Biking` or `Other`. A TCX activity has no name, so there is nothing more descriptive to carry.

How much smaller is the KML?

Roughly eight to nine times on a densely recorded session. TCX spends around 315 bytes on a trackpoint; a KML coordinate is about 36.

More about these formats