DMD HUB GPX Extension
Pre-rendered route data for instant GPX loading across all platforms
https://dmdnavigation.com/ns/gpx/1
Overview
The DMD HUB GPX Extension (dmd: namespace) embeds pre-computed route data directly inside standard GPX 1.1 files. This eliminates the need for routing API calls, on-device surface extraction, and elevation computation when loading a file — routes display instantly.
The extension is placed inside the <extensions> block of <rte> or <trk> elements and is fully compliant with the GPX 1.1 specification. Applications that don't understand the dmd: namespace will simply ignore it.
Benefits
Instant Route Loading
No routing API calls needed. The full routed geometry is embedded in the file, ready to render immediately.
Turn-by-Turn Instructions
Navigation instructions are pre-computed and stored with road names, eliminating on-device processing.
Surface Classification
Paved/unpaved segments with OSM surface and highway tags — no map tile extraction required.
Integrity Verification
SHA-256 hash ensures data validity. If the file is edited externally, apps know to re-compute.
Schema Structure
Add the namespace declaration to your <gpx> root element:
<gpx version="1.1" creator="YourApp"
xmlns="http://www.topografix.com/GPX/1/1"
xmlns:dmd="https://dmdnavigation.com/ns/gpx/1">
The extension is placed inside <rte><extensions> or <trk><extensions>:
<rte>
<name>My Route</name>
<extensions>
<dmd:PreRendered version="1" hash="sha256:abc123..." profile="road-fast-all">
<dmd:CalculatedRoute>...</dmd:CalculatedRoute>
<dmd:Instructions>...</dmd:Instructions>
<dmd:Surface>...</dmd:Surface>
<dmd:Warnings>...</dmd:Warnings>
<dmd:Stats .../>
</dmd:PreRendered>
</extensions>
<rtept lat="..." lon="..."></rtept>
</rte>
Element Reference
<dmd:PreRendered>
Root container for all pre-rendered data.
| Attribute | Type | Description |
|---|---|---|
version | Integer | Schema version (currently 1). If a reader encounters a higher version, it should fall back to normal routing. |
hash | String | Integrity hash. Format: sha256:<16 hex chars> |
profile | String | The routing profile used to generate this data (e.g., road-fast-all, offroad-medium) |
<dmd:CalculatedRoute>
Routes only (tracks already have <trkpt> geometry). Contains the full routed geometry as a semicolon-separated text node:
<dmd:CalculatedRoute>48.123456,16.456789,312.5;48.123470,16.456900,313.1;...</dmd:CalculatedRoute>
Each point is lat,lon,ele with 6 decimal places for coordinates and 1 for elevation (meters). Whitespace between points is allowed and should be stripped before parsing.
<dmd:Instructions>
Turn-by-turn navigation instructions:
<dmd:Instructions>
<dmd:I lat="48.123" lon="16.456" type="LEFT" dist="1250" road="Hauptstrasse" ref="B17"/>
<dmd:I lat="48.200" lon="16.500" type="ROUNDABOUT" dist="3400"/>
<dmd:I lat="48.300" lon="16.600" type="DESTINATION" dist="5200"/>
</dmd:Instructions>
| Attribute | Description |
|---|---|
lat, lon | Instruction point coordinates |
type | Instruction type enum (see below) |
dist | Cumulative distance from route start (meters) |
road | Road name (optional) |
ref | Road reference number (optional) |
dest | Destination sign text (optional) |
jref | Junction reference (optional) |
Instruction Types:
LEFTRIGHTSLIGHT_LEFTSLIGHT_RIGHTSHARP_LEFTSHARP_RIGHTKEEP_LEFTKEEP_RIGHTU_TURNROUNDABOUTSTRAIGHTEXIT_RIGHTEXIT_LEFTDESTINATION<dmd:Surface>
Paved/unpaved classification segments:
<dmd:Surface>
<dmd:S s="0" e="142" sf="asphalt" hw="secondary" p="1"/>
<dmd:S s="143" e="380" sf="gravel" hw="track" p="0"/>
</dmd:Surface>
| Attribute | Description |
|---|---|
s | Start point index (into CalculatedRoute or trkpt sequence) |
e | End point index (inclusive) |
sf | OSM surface tag value (e.g., asphalt, gravel, dirt) |
hw | OSM highway tag value (e.g., secondary, track, path) |
p | Paved flag: 1 = paved, 0 = unpaved |
<dmd:Warnings>
Pre-computed hazard warnings along the route:
<dmd:Warnings>
<dmd:W type="SLOPE" lat="48.5" lon="16.8" dist="12500" val="18.5"/>
<dmd:W type="UNPAVED" lat="48.6" lon="16.9" dist="15000" len="3200"/>
</dmd:Warnings>
| Attribute | Description |
|---|---|
type | SLOPE (gradient ≥ 15%) or UNPAVED (unpaved run ≥ 250m) |
lat, lon | Warning location |
dist | Cumulative distance from route start (meters) |
val | Slope percentage (SLOPE type only) |
len | Unpaved section length in meters (UNPAVED type only) |
<dmd:Stats>
Aggregate statistics (self-closing element with attributes):
<dmd:Stats dist="185420" gain="2340" loss="2180" eleMin="120" eleMax="1845"
time="14400" paved="72" maxSlope="22.5" minSlope="-18.3"/>
| Attribute | Unit | Description |
|---|---|---|
dist | meters | Total route distance |
gain | meters | Total elevation gain |
loss | meters | Total elevation loss |
eleMin | meters | Minimum elevation |
eleMax | meters | Maximum elevation |
time | seconds | Estimated travel time |
paved | % | Percentage of route that is paved (0–100) |
maxSlope | % | Maximum uphill slope |
minSlope | % | Maximum downhill slope (negative value) |
Integrity Hash
The hash ensures that pre-rendered data matches the current route waypoints. If a file is edited in another application (waypoints moved/added/removed), the hash will not match and readers should discard the pre-rendered data and re-route.
Algorithm
- Build a canonical string from the source waypoints:
lat1,lon1;lat2,lon2;...;latN,lonN;profile=road-fast-all- For
<rte>: use all<rtept>coordinates - For
<trk>: use all<trkpt>coordinates - Coordinates truncated to 6 decimal places
- Append
;profile=followed by the routing profile string
- For
- Compute SHA-256 of the canonical string (UTF-8 encoded)
- Take the first 16 hex characters of the hash
- Store as:
sha256:<16 hex chars>
Reader Behavior
| Scenario | Action |
|---|---|
| Hash matches | Use pre-rendered data directly. No routing needed. |
| Hash mismatch | Discard pre-rendered data. Route via normal method (DMD Router, etc.) |
| No hash present | Treat as no pre-rendered data. |
| Unknown version | Fall back to normal routing. |
Implementation Guide
For Readers (GPX Viewers)
- Parse the GPX file normally (tracks, routes, waypoints)
- For each
<rte>or<trk>, check for<dmd:PreRendered>in<extensions> - If found, compute the expected hash from the source coordinates + profile
- If hash matches: use
<dmd:CalculatedRoute>for display geometry,<dmd:Stats>for metadata, etc. - If hash doesn't match: ignore the extension and route normally
For Writers (Route Planners / Navigation Apps)
- After computing a route (via DMD Router or your routing engine), collect:
- Full routed geometry (the dense point array)
- Surface/highway classification per segment
- Turn instructions (if your router provides them)
- Elevation statistics
- Compute the hash from the source waypoints + routing profile
- Write the
<dmd:PreRendered>block inside<extensions> - Continue writing normal
<rtept>/<trkpt>elements as usual
<rtept>, <trkpt>) alongside the extension. The extension is supplementary — the file must remain valid and usable without it.Full Example
<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="DMD HUB GPX Planner"
xmlns="http://www.topografix.com/GPX/1/1"
xmlns:dmd="https://dmdnavigation.com/ns/gpx/1">
<metadata>
<name>Mountain Loop</name>
</metadata>
<rte>
<name>Route 1</name>
<extensions>
<dmd:PreRendered version="1" hash="sha256:f28a213d70082096" profile="offroad-medium">
<dmd:CalculatedRoute>41.651310,-8.249183,114.5;41.651327,-8.249231,114.3;41.650449,-8.249211,110.8;41.649858,-8.247084,127.0;41.648490,-8.245994,134.5</dmd:CalculatedRoute>
<dmd:Instructions>
<dmd:I lat="41.651296" lon="-8.250214" type="SHARP_LEFT" dist="91"/>
<dmd:I lat="41.648015" lon="-8.245977" type="SLIGHT_RIGHT" dist="658"/>
<dmd:I lat="41.632462" lon="-8.244647" type="DESTINATION" dist="3980"/>
</dmd:Instructions>
<dmd:Surface>
<dmd:S s="0" e="2" sf="asphalt" hw="tertiary" p="1"/>
<dmd:S s="3" e="4" sf="" hw="track" p="0"/>
</dmd:Surface>
<dmd:Warnings>
<dmd:W type="SLOPE" lat="41.651274" lon="-8.250075" dist="79" val="15.4"/>
<dmd:W type="UNPAVED" lat="41.648490" lon="-8.245994" dist="658" len="2364"/>
</dmd:Warnings>
<dmd:Stats dist="3980" gain="396" loss="48" eleMin="105.0" eleMax="465.0"
time="358" paved="51" maxSlope="33.8" minSlope="-24.9"/>
</dmd:PreRendered>
</extensions>
<rtept lat="41.65131" lon="-8.249183"></rtept>
<rtept lat="41.632462" lon="-8.244647"></rtept>
</rte>
</gpx>
Compatibility
The extension is currently supported by:
- DMD HUB GPX Planner (web) — writer + reader
- DMD HUB GPX Browser (web) — reader
- DMD HUB iOS App — reader
- DMD2 Android App — writer + reader
Any GPX application can add support by following the implementation guide above. The extension does not interfere with standard GPX processing — non-supporting apps will simply ignore the dmd: namespace elements.