The NOD file holds information about roads and how they connect together. First read John Mechalas' document at http://sourceforge.net/projects/garmin-img (henceforth referred to as [JM]) Section NOD 2 ============= Offset | Size | Description -------+--------+-------------------------- 00 | 1 | Road classification 01 | 3 | Pointer into NOD 1 04 | 1 | Number of bits from offset 0x06 05 | 1 | unknown 06 | varies | Little endian bit mask, with the number | | of bits taken from 0x04 Some definitions of the road classification can be found in [JM]. The bit mask at 06 is read from the least significant bit of a byte and the bytes are read in little endian order. Frequently every bit is set to one. Since a road only points to one entry in NOD 2 and yet must connect to more than one node, then this must be telling us which other nodes (in addition to the one pointed at by 0x01) this road connects to. I'm speculating that you read entries in NOD 1 following the one pointed to, and match them against the bit map. Where there is a one in the bit map, you take that node, and where there is a zero you skip it. If this is right then the number of bits set to 1 will be the same as the number of (routing) nodes in the road. Section NOD 1 ============= Consists of two kinds of area. One contains records of variable length, describing nodes in the road network. The other is a set of tables related to the previous area of nodes. NOD 1 is made up of alternating node and table areas. The first byte of each node record provides a pointer to the associated table area. The offset in NOD 1 of each table area is a multiple of 0x40, thus a node area is limited to a size of about 0x4000 bytes. In practice, this first byte doesn't appear to exceed 0x30. (It is possible that 0x40 is not hardcoded, but is instead specified by the "node align" field in the NOD header.) The table area starts with a header which specifies the number of records in the tables, allowing to determine the offset of the next node area, which follows the table area directly. Node area --------- The first area consists of variable sized records. There are pointers from NOD 2 and NOD 3 to these records. There is often more than one pointer to the same record. There also appears to be cases where there are no pointers (or none that have been discovered). Each node record starts with a header. Offset | Size | Description -------+--------+-------------------------- 00 | 1 | Pointer to tables area 01 | 1 | Flags 02 | varies | Coordinate offsets The following flags are known. Flag | Description -------+---------------------------- 0x20 | 2 byte coordinate offsets 0x10 | Restrictions 0x08 | Boundary node If the flag 0x10 is set, there are routing restrictions at this node. The flag signifies the presence of restrictions data at the end of the record. The flag 0x08 is set if the node is a boundary node, that is if it lies on the boundary of the IMG tile. In that case, there will be a pointer from NOD 3 to this record. Furthermore, the flags 0x40 and 0x04 are usually set. Their purpose is yet to be determined. Possibly, these flags signify the presence of link and position data in the record. The coordinate offsets are relative to the base coordinates in the header of the following tables area. If the flag 0x20 is set, each coordinate offset is a two byte value, else both offsets are stored in three bytes (12 bits each). Links ----- Following the coordinate offsets comes a sequence of variable length records which describe links to other nodes. The last of these records is marked by bit 0x80 in the second byte (Flags B below). Links may point to nodes in the same or another node area in NOD 1. We call the latter inter-area links, the former intra-area links. A link may point to a directly adjacent node in the road network (a "direct link"), or to a node that may be reached by following a sequence of direct links (an "indirect link"). For direct links, there is always an opposite direct link from the destination node. This is not the case for indirect links. Indirect links appear to always point to nodes on the same polyline. It is not clear whether inter-area indirect links are allowed. The destination node of an intra-area link is given by a signed 14-bit integer stored in bytes two and three. Byte three is the low byte, the low 6 bits of byte two are the high bits. An inter-area link is signified by the presence of bit 0x40 in the second byte. In that case, the low six bits of byte two are an index into Table B in the following tables area, which holds a pointer to another nodes area of NOD 1. Notation: here | libgarmin --------------+-------------- direct link | arc indirect link | link A link starts as follows. Offset | Size | Decription -------+--------+------------------------------------- 00 | 1 | Flags A 01 | 1 or 2 | Flags B and pointer Flags A: Mask | Description -------+-------------------- 0x80 | New direction 0x40 | Sign 0x07 | Destination class Flags B: Mask | Description -------+-------------------- 0x80 | Last link 0x40 | Inter-area link The links from a node appear to be grouped according to the direction in which they leave the node. The first link within such a group is a direct link, while following links will be indirect (leading to nodes further along the road than the one pointed at by the previous direct link). The bit 0x80 in the first byte signifies that a new group starts. It is not set at the start of the first group. Thus, a link is direct if it is the first link in a node record, or if bit 0x80 is set in its first byte. Other links are indirect. Each link has an orientation which is stored in bit 0x40 of Flags A. This orientation is consistent within a polyline. Direct links: After the pointer, a direct link has a one byte index into the following Table A, which gives some parameters for the segment and a pointer to the road in NET. This is followed by a byte which usually (but not always) agrees with the reverse link, and which may be related to the segment length. Following this is a variable amount of data is a sequence of bytes of unknown length, between one and three bytes long. The first byte may represent the direction in which the segment heads out of the node, with North=0x00, East=0x40. In the absence of bits 0x10 and 0x08 in Flags A, there appears to be more than one byte if and only if 0x20 is set in Flags A. This may be related to the segment being curved. In some cases, bit 0x08 in Flags correlates with long segments, whose length would not fit into the length byte. Indirect links: These have no segment index and no byte agreeing with the opposite link, if present. There are one or two bytes of unidentified data. Restrictions: If node flag 0x10 was set, the links are followed by a variable length sequence of offsets into Table C. The corresponding record in Table C describes a restriction at the node. Depending on the size of the largest Table C in NOD 1, these may be bytes or little-endian shorts (or larger?). It is unknown whether their size may be determined without reading the header of each tables area. The last offset has its highest bit set. Tables area ----------- The second kind of subsection in NOD 1 occurs once after each node area. It always starts on a 0x40 boundary in the section and zero padding bytes are used achieve this alignment. There appear to be at least 0x40 of these zero padding bytes always, such that an offset of 0x40 less would also appear to have sufficed. The table area starts with a 9 byte header, and is followed by up to three tables we call Table A, B and C. There is a header area of 9 bytes. It is unclear whether the first byte may contain other data in the higher bits. Only values up to 2 have been observed. Offset | Size | Description -------+--------+------------------------------ 00 | 1 | size of Table C size field 01 | 3 | base longitude 04 | 3 | base latitude 07 | 1 | number of records in Table A 08 | 1 | number of records in Table B Table A contains fixed length records (always size 5?) that represent road segments (parts of roads between adjacent nodes) that meet nodes in the preceding nodes area. These contain pointers into NET and routing data (speed, oneway, road class, toll, what vehicle types are allowed). Table B contains offsets into NOD 1. These are the destinations of inter-area links from the preceding nodes area. Table B is followed by one or more bytes giving the size of Table C. If the first byte of the header before was zero, there is one zero byte. If it was non-zero, there are that many bytes giving the byte size of Table C as a little-endian integer. Table C contains data that is related to restrictions. In the common case, it contains records of size 11 that are of the following form. Offset | Size | Description -------+--------+--------------------------- 00 | 3 | Header (05 40 00) 03 | 2 | Source node 05 | 2 | Restriction node 07 | 2 | Destination node 09 | 1 | Source segment 10 | 1 | Destination segment Such a record describes a restriction at "Restriction node" coming from "Source node" via "Source segment" headed for "Destination node" along "Destination segment". The segments are given by indices into the preceding Table B. The nodes are given by little-endian unsigned shorts which are negative offsets from the start of the tables area. It is unclear what inter-section restrictions or restrictions at boundry nodes look like, if they are possible. Section NOD 3 ============= These are boundary nodes that are on the edge of the map, and connect to other maps in the set. They are described in [JM].