Display GPX data
GPX (GPS Exchange Format) is an XML schema for exchanging waypoints, routes, and tracks recorded by GPS devices and applications. The HERE Maps API for JavaScript supports GPX 1.0 and 1.1 documents through the data module (mapsjs-data.js).
The H.data.gpx.Reader class fetches and parses GPX content, converts it into map objects, and exposes a layer that you can add directly to the map. Every parsed map object receives regular map events and carries the original GPX attributes on its data property, so values such as elevation, time, speed, course, or symbol remain accessible at runtime.
Note
You can load a GPX file from a different domain provided that the domain supports Cross-Origin Resource Sharing (CORS).
Quick start
// Create a GPX reader bound to a URL:
const reader = new H.data.gpx.Reader('path/to/file.gpx');
// Start asynchronous parsing of the document:
reader.parse();
// Add the layer that holds the parsed GPX content to the map:
map.addLayer(reader.getLayer());Remember to import the data module in the <head> of your HTML file before using the reader:
<script type="text/javascript" src="https://js.api.here.com/v3/3.2/mapsjs-data.js"></script>Supported GPX elements
Waypoint (<wpt>)
<wpt>)A <wpt> element represents a named geographic point and is rendered as an H.map.Marker.
The marker's data exposes the parsed attributes. featureType property in data is waypoint.
Route (<rte>)
<rte>)A <rte> element represents an ordered list of <rtept> route points and is rendered as a single H.map.Polyline.
Route metadata (name, desc, etc.) is attached to the polyline's data, and the parsed route point list is exposed as pointsMetaInfo — an array of objects with the same fields as waypoints. featureType property in data is route.
Track (<trk> and <trkseg>)
<trk> and <trkseg>)A <trk> element represents a recorded path that can contain one or more <trkseg> segments. Tracks are always rendered as a H.map.Group.
Track-level metadata (name, desc, etc.) is attached to the group's data. The featureType property in data is track.
All <trkseg> segments are rendered as one or more H.map.Polyline objects depending on how the reader is configured:
| Option | Geometry | Polyline data |
|---|---|---|
enableIndividualTrackSegmentStyling: false (default) | One H.map.Polyline per track, using a MultiLineString that combines every <trkseg>. | { featureType: 'track_segment', pointsMetaInfo: [...] }, where pointsMetaInfo is an array of per-segment point arrays (one inner array per <trkseg>). |
enableIndividualTrackSegmentStyling: true | One H.map.Polyline per <trkseg>, using a LineString. | { featureType: 'track_segment', pointsMetaInfo: [...] }, where pointsMetaInfo is a flat array of parsed <trkpt> objects. |
Use the default mode when you want to style the entire track uniformly with the smallest number of map objects. Switch to individual-segment mode when you want to configure a different style per segment.
For each polyline, featureType property in data is track_segment.
Metadata (<metadata>)
<metadata>)Metadata from the GPX document is exposed on the root group's data. Call reader.getParsedObjects()[0].getData() to access fields such as name, desc, time, keywords, author, copyright, links, and bounds ({ minlat, minlon, maxlat, maxlon }), along with the version and creator attributes of the <gpx> root element. Both GPX 1.1 documents (which nest these inside <metadata>) and GPX 1.0 documents (which expose them as direct children of <gpx>, including url and urlname) are supported.
Note
The
latandlonfields of the metadata in<wpt>,<rtept>and<trkpt>are not part of the map objectdata. You can access this information from respective map object geometry.Any
<extension>fields are not parsed and are not present as part of the object metadata.
Output hierarchy
The reader produces a single H.map.Group tree that mirrors the structure of the GPX document. getParsedObjects() returns this root group as the only entry in the array, and the layer returned by getLayer() displays it. The root group is always created, even when the GPX document contains no waypoints, routes, or tracks, effectively representing an empty GPX document.
Root GPX (H.map.Group)
├── Waypoints (H.map.Group)
│ └── Waypoint (H.map.Marker)
│ └── Waypoint (H.map.Marker)
├── Routes (H.map.Group)
│ └── Route (H.map.Polyline)
│ └── Route (H.map.Polyline)
└── Tracks (H.map.Group)
└── Track (H.map.Group)
└── Track Segment (H.map.Polyline)
└── Track Segment (H.map.Polyline)
└── Track (H.map.Group)
└── Track Segment (H.map.Polyline)A waypoints, routes, or tracks subgroup is only added when the document contains at least one element of that kind. Use getData() on any object in the tree to access its parsed attributes. Properties whose corresponding GPX element or attribute is absent from the source document are omitted from the returned data object, so consumers can use a truthiness or hasOwnProperty check to detect missing fields. The reader does not retain references to the original DOM nodes.
| Node | Map Object | Map Object Data |
|---|---|---|
| GPX Root | H.map.Group | { featureType: 'gpx', ...parsed <gpx> data } |
| Waypoints | H.map.Group | { featureType: 'waypoints' } |
| Waypoint | H.map.Marker | { featureType: 'waypoint', ...parsed <wpt> data } |
| Routes | H.map.Group | { featureType: 'routes' } |
| Route | H.map.Polyline | { featureType: 'route', pointsMetaInfo: [...], ...parsed <rte> data } |
| Tracks | H.map.Group | { featureType: 'tracks' } |
| Track | H.map.Group | { featureType: 'track', ...parsed <trk> data } |
| Track segment | H.map.Polyline | { featureType: 'track_segment', pointsMetaInfo: [...] } — see Track (<trk> and <trkseg>) for how pointsMetaInfo is shaped in each mode. |
Example: Render GPX content in HERE map
The following example loads a GPX file and displays its waypoints, routes, and tracks. It builds on the base map described in Get started with HERE Maps API for JavaScript.
-
In the
<head>element of your HTML file, import the data module:<script type="text/javascript" src="https://js.api.here.com/v3/3.2/mapsjs-data.js"></script> -
Create a reader, parse the document, and add the resulting layer to the map. Listen to
statechangeto react when parsing completes or fails:const reader = new H.data.gpx.Reader('path/to/file.gpx'); reader.addEventListener('statechange', function (evt) { if (evt.state === H.data.AbstractReader.State.READY) { // Auto-fit the view to the parsed content. map.getViewModel().setLookAtData({ bounds: reader.getLayer().getProvider().getRootGroup().getBoundingBox() }); } else if (evt.state === H.data.AbstractReader.State.ERROR) { console.error('Failed to parse GPX document:', evt.message); } }); reader.parse(); map.addLayer(reader.getLayer()); -
To inspect the GPX attributes that accompany each rendered object, attach a
taplistener to the layer's provider and read thedataproperty:reader.getLayer().getProvider().addEventListener('tap', function (evt) { console.log(evt.target.getData()); // parsed GPX attributes for the tapped object });
Customize the rendering style
The Reader constructor accepts an options object with a style callback. The callback is invoked once per rendered map object — the markers and polylines, not the intermediate groups — and receives that object as its only argument. Determine the feature type by reading mapObject.getData().featureType; the value is one of 'waypoint', 'route', or 'track_segment', and can be used to apply different defaults per feature type.
const reader = new H.data.gpx.Reader('path/to/file.gpx', {
style: function (mapObject) {
const featureType = mapObject.getData().featureType;
if (featureType === 'waypoint') {
mapObject.setIcon(new H.map.Icon('icons/pin.svg'));
} else if (featureType === 'route') {
mapObject.setStyle({ strokeColor: '#1f78b4', lineWidth: 4 });
} else if (featureType === 'track_segment') {
mapObject.setStyle({ strokeColor: '#e31a1c', lineWidth: 5 });
}
}
});
reader.parse();Parse GPX content from a string
When the GPX payload is already in memory, use parseData() instead of parse(). This avoids an additional HTTP request and is convenient for content that is generated by your application or fetched through a custom transport.
const gpxString = `<?xml version="1.0"?>
<gpx version="1.1" xmlns="http://www.topografix.com/GPX/1/1">
<wpt lat="52.5189" lon="13.4158"><name>Berlin</name></wpt>
</gpx>`;
const reader = new H.data.gpx.Reader();
reader.parseData(gpxString);
map.addLayer(reader.getLayer());Access parsed objects programmatically
In addition to the style callback based workflow, the reader exposes its parsed map objects directly. This is useful when you need to inspect, transform, or post-process GPX rendered objects.
reader.addEventListener('statechange', function (evt) {
if (evt.state === H.data.AbstractReader.State.READY) {
const rootGroup = reader.getParsedObjects()[0];
// print data of top-level GPX feature
console.log(rootGroup.getData());
const waypointsGroup = rootGroup.getObjects().find(g => g.getData().featureType === 'waypoints');
// print data of each waypoint
waypointsGroup.getObjects().forEach(w => console.log(w.getData()));
}
});Handle parsing errors
The reader transitions to the ERROR state when the input cannot be processed — for example when the response body is empty, the XML is malformed, or the root element is not <gpx>. The statechange event exposes a human-readable explanation in evt.message:
reader.addEventListener('statechange', function (evt) {
if (evt.state === H.data.AbstractReader.State.ERROR) {
console.error('GPX parsing failed:', evt.message);
}
});Next steps
- See the
H.data.gpx.Readerentry in the API reference for the full method and option listing.
Updated 10 days ago