The USR4 file format is a binary file format. The length of each field is given.
The main structure of a USR4 file is
- Header with information on version, creation date etc.
- Number of waypoints
- Waypoint structures
- Number of routes
- Route structures (mainly reference to the already read waypoints)
- Number of tracks
- Track structures
The main structure used is the OrderedDict which is used to map the Waypoint, Route and Track structures from the file to data structures in python.
As a first step I created the OrderedDict for waypoints, routes and tracks:. Each item in the OrderedDict consists of:
- The first field in each of the entries you will find the field name, e.g. UID_unit_number
- The list afterwards comprises of two elements:
- the lenght/type of the field and the
- data of the field itself
wpt = OrderedDict([ ('UID_unit_number' , ['uint32', 0]), ('UID_sequence_number' , ['int64', 0]), ('Waypoint_stream_version_number' , ['uint16', 0]), .........
After reading for example the waypoint count the program initialises a list of waypoints with exactly the structure of the respective OrderedDict using deepcopy (I assume there are more elegant ways to do this?)
Using the for x in y: the program iterates through the waypoints, routes and tracks
wpts =  for i in range(waypointcount): wpts.append(deepcopy(wpt)) for w in wpts: for k, v in w.items(): """ binary read each field and distinguish e.g. for a descrition if k == 'Description': if w['Description_length_in_bytes'] > 0: w['Description'] = binaryReader.readstring..... more elif...statements.... else: v = binaryReader.read(v)
Thus all data is filled into the data structures at the right places and fields like descriptions with variable length are covered through the if statements (a case structure would be more readable here)
Writing the output file
After reading in the USR4 file the GPX output file is written based on the structures created.
The GPX output file has the main structure