RDBK.app

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 Structure meta track notes symbols road types junctions result QR conformance full example

Why .rdbk

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

FieldTypeMeaning
titlestringHuman-readable roadbook title.
km_totalnumberTotal route length in km (derived from track).
note_countintegerNumber of notes.
logo_pathstringOptional; 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.

FieldTypeMeaning
numinteger1-based note number (display order).
idxintegerIndex into track where this note sits.
lat, lonnumberNote position (decimal degrees).
kmnumberCumulative distance from the start (km).
km_partialnumberDistance from the previous note (km).
textstringThe instruction / comment.
capnumber | null"CAP" heading to the next note in degrees, when shown.
cap_kmnumber | nullStraight-line distance for that heading (km).
bearing_innumberTrack bearing arriving at the note (degrees).
bearing_outnumberTrack bearing leaving the note (degrees).
road_type_in0–4Surface arriving — see road types.
road_type_out0–4Surface leaving.
iconsarrayPositioned symbols — see symbols.
junctionsarray | nullJunction 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.

FieldTypeMeaning
namestringSymbol key; looked up in icons.
pos[x, y]Centre position in reference units, from box centre, +y up.
sizenumberBox size in reference units (square).
anglenumberRotation, degrees clockwise.
flip_xbooleanHorizontal 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

idTypeRendering
0Defaultneutral
1Motorway / paved fastsolid
2Asphaltsolid
3Track / pistesolid (default off-road)
4Off-pistedashed

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 }
]
FieldTypeMeaning
pivot[x, y]Vector start (reference units, +y up).
tip[x, y]Vector tip / arrow head.
widthnumberStroke thickness.
road_type0–4Road 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:

FieldWidthMeaning
team3Vehicle number.
date6Date DDMMYY.
start6Start time HHMMSS.
end6End time HHMMSS.
accuracy4Accuracy penalty.
skip4Skipped-note penalty.
extra4Overshoot penalty.
cap4Heading penalty.
speed4Speed penalty.
km5Distance, deci-km.
avg3Average 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

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…" }
}

Open a .rdbk in the Reader