OSM Map On Garmin/NOD Subfile Format
A reverse-engineering of Garmin's NOD Subfile format
Header
NOD Header
Common Header
The structure of the common header is the same in all subfiles.
Byte Offset | Length (bytes) | Description |
---|---|---|
0x000 | 2 | Header length. So far '0x3f' and '0x7f' have been seen. |
0x002 | 10 | Type GARMIN NOD |
0x00C | 1 | 0x01 ? |
0x00D | 1 | 0x00 |
0x00E | 2 | Creation year |
0x010 | 1 | Creation month |
0x011 | 1 | Creation day |
0x012 | 1 | Creation hour |
0x013 | 1 | Creation minute |
0x014 | 1 | Creation second |
Specific NOD Header
Byte Offset | Length (bytes) | Description |
---|---|---|
0x015 | 4 | NOD1 section offset |
0x019 | 4 | NOD1 section length |
0x01D | 1 | Unknown. Lower bit always set. 0x01 and 0x27 spotted |
0x01E | 1 | Flag: 0x01: left-hand drive. others unknown (0x02 spotted) |
0x01F | 2 | Unknown. 0x0000 |
0x021 | 2 | Unknown. 0x06 |
0x023 | 2 | Unknown. 0x05 |
0x025 | 4 | NOD2 section offset |
0x029 | 4 | NOD2 section length |
0x02D | 4 | Unknown 0x0000 |
0x031 | 4 | NOD3 section offset |
0x035 | 4 | NOD3 section length |
0x039 | 1 | NOD3 section record length. 0x09 |
0x03a | 4 | Unknown 0x00 and 0x0200 spotted |
0x03e | 1 | Unknown 0x00 |
0x03f | 4 | NOD4 section offset |
0x043 | 4 | NOD4 section length |
0x047 | 32 | Unknown all bytes 0x00 |
0x067 | 4 | NOD5 section offset |
0x06b | 4 | NOD5 section length |
0x06f | 2 | Unknown 0x02 spotted |
0x071 | 4 | NOD6 section offset |
0x075 | 4 | NOD6 section length |
0x079 | 2 | NOD6 record size |
0x07b | 4 | Unknown 0x02 spotted |
NOD1 section
This consists of alternating nodes and tables areas.
The nodes area consists of variable sized records. Each record is as follows:
Node header
Node record begins with a header:
Byte Offset | Length (bytes) | Description |
---|---|---|
0x00 | 1 | Pointer to table area. Associated table area is at pointer * 0x40 |
0x01 | 1 | Flags: 0x04: unknown, usually set; 0x08: boundary node; 0x10:restrictions; 0x20: 2 byte coordinate offsets; 0x40: has arcs |
0x02 | varies | Coordinate offsets. If flag 0x20 is unset this is 3 bytes (12 bits for each offset) else this is 4 bytes (16 bits for each offset) |
Links
Directly following node header is a sequence of links:
Byte Offset | Length (bytes) | Description |
---|---|---|
0x00 | 1 | Flags A: bits 0-2: destination class; 3-5: curve length; 6: sign; 7: new direction |
0x01 | 1 or 2 | Flags B: 0x40: inter-area link; 0x80: last node / pointer index B (see [1]) |
variable | 1 | pointer index A |
variable | 1 to 3 | first is direction? |
The tablesarea consists of a header and three tables:
Tables header
Byte Offset | Length (bytes) | Description |
---|---|---|
0x00 | 1 | 0-1: size of Table C size field; 2-7: unknown (???? this is not correct see Explore IMG) |
0x01 | 3 | base longitude |
0x04 | 3 | base latitude |
0x07 | 1 | number of records in table A |
0x08 | 1 | number of records in table B |
Table A
Table A contains fixed length records of 5 bytes representing road segments.
Byte Offset | Length (bytes) | Description |
---|---|---|
0x00 | 3 | 0-29: Pointer to NET; 30: no delivery; 31: no emergency |
0x03 | 1 | class flag: 0-3: road speed; 4: oneway; 5-6: road class; 8: toll |
0x04 | 1 | access flag: 0: no car; 1: no bus; 2: no taxi; 3: no through routing; 4: no foot; 5: no bike; 6: no truck; 7: carpool only (<-- ??? ) - looks like Road ID! |
Table B
Table B contains fixed length records of 3 bytes representing destinations of inter area links.
Table C
If size of Table C size field was zero, table B is followed by 2 optional bytes indicating respectively the number of unpaved arcs and ferry arcs in table A, then 0x00.
Else there is size of Table C size field bytes indicating the length of table C. Following this are restriction records:
Byte Offset | Length (bytes) | Description |
---|---|---|
0x00 | 1 | unknown; 0x05 spotted |
0x01 | 1 | Flag: 0: unknown; 1: pedestrian exception; 2: emergency exception; 3: additional vehicle exceptions; 4: unknown; 5-7: number of ways |
0x02 | 1 | unknown; 0x00 spotted |
0x03 | 1 | Optional (present if vehicle additional exceptions is active in header flag). Vehicle exceptions flag: 0x01: car; 0x02: bus; 0x04: taxi; 0x10: delivery; 0x20: bicycle; 0x40: truck |
variable, repeated nb_ways+1 times | 2 | node |
variable, repeated nb_ways times | 1 | segment |
Finally the table is finished by 2 optional bytes indicating respectively the number of unpaved arcs and ferry arcs in table A.