rdbk · v1.0application/x-roadbook.rdbk
The .rdbk standard
An open, single-file format for digital roadbooks. One self-contained UTF-8 JSON document carries the whole route — track, notes, headings, junction diagrams and its own symbols — so a roadbook is just a file you can read, follow, share and archive, with nothing else attached.
Why .rdbk
- Self-contained. A
.rdbkembeds the symbols it uses (as data URIs), so it renders identically anywhere — offline, years later — with no external icon packs to lose. - One file, plain JSON. Open it in any text editor, parse it with one line in any language, diff it in git.
- Map-ready. The full GPS track travels with the notes, so any reader can draw the route and place you on it.
- Symbols are first-class. Each note can carry positioned, rotated, scalable pictograms and colored junction vectors — not just a line of text.
Document structure
A .rdbk file is a single JSON object with four top-level keys:
{
"meta": { … }, // document metadata
"track": [ … ], // the GPS polyline (ordered points)
"notes": [ … ], // navigation notes, ordered along the track
"icons": { … } // embedded symbol library (name → data URI)
}
Coordinates are WGS-84 decimal degrees. Distances are kilometres. Headings are degrees clockwise from true north (0–360). Symbol angles are degrees clockwise.
meta
| Field | Type | Meaning |
|---|---|---|
title | string | Human-readable roadbook title. |
km_total | number | Total route length in km (derived from track). |
note_count | integer | Number of notes. |
logo_path | string | Optional; empty when none. |
track
An ordered array of points describing the route polyline. Notes reference into it by index.
"track": [
{ "lat": 45.82712, "lon": 9.41164 },
{ "lat": 45.82740, "lon": 9.41180 }
]
notes
The heart of a roadbook: an ordered list of waypoints, each with an instruction, heading and symbols. A reader highlights the active note and validates progress against the GPS track.
| Field | Type | Meaning |
|---|---|---|
num | integer | 1-based note number (display order). |
idx | integer | Index into track where this note sits. |
lat, lon | number | Note position (decimal degrees). |
km | number | Cumulative distance from the start (km). |
km_partial | number | Distance from the previous note (km). |
text | string | The instruction / comment. |
cap | number | null | "CAP" heading to the next note in degrees, when shown. |
cap_km | number | null | Straight-line distance for that heading (km). |
bearing_in | number | Track bearing arriving at the note (degrees). |
bearing_out | number | Track bearing leaving the note (degrees). |
road_type_in | 0–4 | Surface arriving — see road types. |
road_type_out | 0–4 | Surface leaving. |
icons | array | Positioned symbols — see symbols. |
junctions | array | null | Junction vectors — see junctions. |
{
"num": 12, "idx": 184,
"lat": 45.8321, "lon": 9.4002,
"km": 8.42, "km_partial": 0.63,
"text": "Bear right onto the gravel track",
"cap": 247, "cap_km": 0.30,
"bearing_in": 92, "bearing_out": 247,
"road_type_in": 2, "road_type_out": 3,
"icons": [
{ "name": "s03_30km.png", "pos": [40, 22], "angle": 0, "size": 32, "flip_x": false }
],
"junctions": [
{ "pivot": [0, 0], "tip": [45, 25], "width": 3, "road_type": 3 }
]
}
Symbols (icons + icons)
A note's icons array places pictograms on a fixed 230 × 162 reference box. The origin is the box centre; +y points up. This makes a note render the same at any display size.
| Field | Type | Meaning |
|---|---|---|
name | string | Symbol key; looked up in icons. |
pos | [x, y] | Centre position in reference units, from box centre, +y up. |
size | number | Box size in reference units (square). |
angle | number | Rotation, degrees clockwise. |
flip_x | boolean | Horizontal mirror. |
The symbols themselves live inside the file in icons, a map from symbol name to a data URI. This is what makes a .rdbk portable: every symbol it draws is embedded.
"icons": {
"s03_30km.png": "data:image/png;base64,iVBORw0KGgoAAAANS…",
"p07_ponte.png": "data:image/png;base64,iVBORw0KGgoAAAANS…"
}
Resolution order for a symbol: an inline data: URI on the icon → the file's icons (case-insensitive) → a host symbol set. A note may also carry a speed limit encoded in a symbol name (e.g. s03_30km ⇒ 30 km/h; s99_end clears it).
Road types
| id | Type | Rendering |
|---|---|---|
0 | Default | neutral |
1 | Motorway / paved fast | solid |
2 | Asphalt | solid |
3 | Track / piste | solid (default off-road) |
4 | Off-piste | dashed |
Junction vectors (junctions)
Beyond text, a note can draw the junction itself: one or more vectors on the same 230 × 162 box. Each goes from a pivot to a tip (arrow head), colored by road type and drawn with a stroke width.
"junctions": [
{ "pivot": [0, 0], "tip": [45, 25], "width": 3, "road_type": 3 },
{ "pivot": [0, 0], "tip": [-30, 40], "width": 2, "road_type": 4 }
]
| Field | Type | Meaning |
|---|---|---|
pivot | [x, y] | Vector start (reference units, +y up). |
tip | [x, y] | Vector tip / arrow head. |
width | number | Stroke thickness. |
road_type | 0–4 | Road type → vector color. |
Result token (optional, for events)
When a roadbook is followed competitively, a reader can emit a compact, fixed-width 49-character result token (suitable for a QR code). It is a sequence of zero-padded numeric fields and carries no personal data:
| Field | Width | Meaning |
|---|---|---|
team | 3 | Vehicle number. |
date | 6 | Date DDMMYY. |
start | 6 | Start time HHMMSS. |
end | 6 | End time HHMMSS. |
accuracy | 4 | Accuracy penalty. |
skip | 4 | Skipped-note penalty. |
extra | 4 | Overshoot penalty. |
cap | 4 | Heading penalty. |
speed | 4 | Speed penalty. |
km | 5 | Distance, deci-km. |
avg | 3 | Average speed, deci-km/h. |
The token may be appended with -<sig>, a truncated HMAC over the token, for tamper-evidence between the reader and the scorer.
Conformance
- Files are UTF-8 JSON, extension
.rdbk, media typeapplication/x-roadbook. - A conforming reader MUST render
trackandnotesin order and resolve symbols fromiconsfirst. - A conforming writer MUST embed every symbol referenced by any note into
icons, so the file is self-contained. - Unknown fields MUST be preserved on round-trip and ignored if not understood (forward-compatibility).
Full minimal example
{
"meta": { "title": "Demo loop", "km_total": 1.21, "note_count": 2, "logo_path": "" },
"track": [
{ "lat": 45.8271, "lon": 9.4116 },
{ "lat": 45.8290, "lon": 9.4135 },
{ "lat": 45.8305, "lon": 9.4150 }
],
"notes": [
{
"num": 1, "idx": 0, "lat": 45.8271, "lon": 9.4116,
"km": 0, "km_partial": 0, "text": "Start",
"cap": null, "cap_km": null, "bearing_in": 0, "bearing_out": 45,
"road_type_in": 3, "road_type_out": 3, "icons": [], "junctions": null
},
{
"num": 2, "idx": 2, "lat": 45.8305, "lon": 9.4150,
"km": 1.21, "km_partial": 1.21, "text": "Finish",
"cap": null, "cap_km": null, "bearing_in": 45, "bearing_out": 0,
"road_type_in": 3, "road_type_out": 3,
"icons": [ { "name": "i01_arrivo.png", "pos": [0, 0], "angle": 0, "size": 40, "flip_x": false } ],
"junctions": null
}
],
"icons": { "i01_arrivo.png": "data:image/png;base64,iVBORw0KGgoAAAANS…" }
}
RDBK.app