GPX to GeoJSON converter

Turn a GPX file from a GPS watch, Strava or Garmin Connect into a GeoJSON FeatureCollection for Leaflet, MapLibre or your own code. Point times and heart rate come along. Free, and no account needed.

Drop a GPX file here

Download the sample

Your file stays on your computer: nothing is uploaded.

In short

Convert GPX to GeoJSON online, in your browser

The Spatibase GPX to GeoJSON converter reads a GPX file and writes an RFC 7946 FeatureCollection in your web browser. How the GPX maps to GeoJSON:

  • Tracks become lines. A LineString, or a MultiLineString with one part per trkseg, with the elevation as the third coordinate.
  • Per-point data stays. Times, heart rate, cadence, temperature and power sit in properties.coordinateProperties, one array entry per point.
  • Waypoints become Points. With name, description, sym, type and vendor fields such as OsmAnd’s osmand_icon.
  • Nothing is uploaded. Files up to 50 MB, free, no account.
How to

How to convert GPX to GeoJSON

  1. Find a GPX: an activity exported from Strava or Garmin Connect, a route planned on gpx.studio or Komoot, or a log straight off a GPS unit.
  2. Drop it on the box above, or press Choose a file. The sample holds a walk through Barcelona, three areas saved as closed tracks and five waypoints.
  3. Check the preview: every track, route and waypoint is one feature in the list.
  4. Press Download GeoJSON, or Copy GeoJSON to paste it into geojson.io or your code.
  5. Load it in Leaflet with L.geoJSON(data) or in MapLibre as a geojson source, or import it into a Spatibase project.
What’s kept

How GPX elements land in the GeoJSON

WhatWhat happens
Track (trk)A LineString feature, or a MultiLineString when the track has more than one segment (trkseg). Its _gpxType is "trk".
Route (rte)A LineString through the route points, with _gpxType: "rte". The names of single route points (rtept) are not kept.
Waypoint (wpt)A Point feature with name, description (from desc), cmt, sym, type and time.
Elevation (ele)The third number of a position: [2.17, 41.38, 12.4]. A point without <ele> keeps two numbers, so one line can mix both.
Point timescoordinateProperties.times: one array per track, or one per segment for a MultiLineString. The track’s own time is its first point’s time.
Heart rate, cadence, temperature, powercoordinateProperties.heart, cads, atemps and powers, aligned with the coordinates, with null where a point has no value.
Vendor fields in their own namespaceKept with the prefix: OsmAnd’s <osmand:icon> becomes osmand_icon.
Feature orderTracks first, then routes, then waypoints, whatever the order in the file.
Not keptThe file’s metadata (author, bounds), route-point names and times, and any segment or route with a single point.
Formats

Reading a GPS track in GeoJSON

GeoJSON has no time. RFC 7946 stores shapes and properties, nothing per vertex. coordinateProperties is a convention of togeojson, the open-source library this converter uses: arrays that run parallel to the coordinates. GDAL and GPSBabel don’t write it, and Leaflet and MapLibre ignore it when they draw.

Three details to handle when you read the file in code:

  • Times can be shorter than the line. Only points with a <time> are listed. If a few points have none, times[i] no longer belongs to coordinates[i], so compare the lengths before pairing them.
  • Segments mark gaps. A MultiLineString part ends where recording stopped. Flattening the parts into one line connects the gap with a straight stroke.
  • Sensor arrays hold nulls. A point without a heart-rate reading is null in heart, so filter before you average.

Need one feature per point? For charts and tables, the GPX to CSV converter writes a row per track point with time, elevation and heart rate.

Do it in code

Convert GPX to GeoJSON in JavaScript

togeojson (@tmcw/togeojson) reads GPX in a browser or in Node.js. In Node it needs a DOM parser such as @xmldom/xmldom:

import { readFile, writeFile } from 'node:fs/promises'
import { DOMParser } from '@xmldom/xmldom' // browsers have DOMParser built in
import { gpx } from '@tmcw/togeojson'

const xml = new DOMParser().parseFromString(await readFile('ride.gpx', 'utf8'), 'text/xml')
const geojson = gpx(xml) // tracks, then routes, then waypoints
await writeFile('ride.geojson', JSON.stringify(geojson))

Two fixes this page adds. Plain togeojson copies the last point’s sensor values onto the whole track (gpxtpx_hr: "151" on a Strava run), and it misses the heart rate in Garmin Connect files, which write ns3: instead of gpxtpx:. The converter renames the prefix and drops those keys.

On the command line, ogr2ogr -f GeoJSON tracks.geojson ride.gpx tracks writes each track as a 2D MultiLineString without times, and its track_points layer gives one Point per track point with ele and time. GPSBabel’s -o geojson joins a track’s segments into one line and drops the times.

FAQ

Questions about converting GPX to GeoJSON

Where do the GPX timestamps go in the GeoJSON?

Into properties.coordinateProperties.times, one ISO 8601 time per track point, in the same order as the coordinates. A track with several segments gets one array per segment. The geometry itself has no place for time in GeoJSON.

Is elevation kept when converting GPX to GeoJSON?

Yes, as the third value of each position, in metres: [2.17, 41.38, 12.4]. RFC 7946 allows a third value, and web maps draw the line flat and ignore it.

Why is my track a MultiLineString?

Your GPX track has more than one segment (trkseg): recording stopped and started again. Each segment becomes one part, so no line is drawn across the gap. A track with a single segment comes out as a plain LineString.

How do I show a Strava or Garmin activity on a Leaflet map?

Export the activity as GPX, convert it here and load the file with L.geoJSON(data).addTo(map). Leaflet draws the track and the waypoints; the times and heart rate stay in the properties for your own popups or charts.

What is the _gpxType property?

togeojson marks every line with where it came from: "trk" for a recorded track and "rte" for a planned route. Waypoints have none. Filter on it when you only want the tracks.

Moving the places into Spatibase? Read how to import your data. Need another pair of formats? The GIS file converter converts between all of them.

Talk to us

Not sure it’s a fit? Let’s find out

Tell us about your use case and what you need, from data model to security and deployment. In 30 minutes we’ll look at it together and tell you honestly if we can help.

Or write to hello@spatibase.com.