Similar work
Mike Caddy wrote to me to tell me about a similar project.1 I’ve not looked at the code, but it might be useful.
Introduction
As a keen, but somewhat optimistic, geocacher, I am keen to upload thousands of waypoints to my car’s satnav in the hope that this will make it easier to find caches.
In the past, I used a TomTom GPSr which understood the .ov2 format, but my new car, a 2014 Audi A3, has an inbuilt navigation system. In principle you can upload waypoints to this too: the myAudi website allows you upload GPX, KML, &c. files, then download them as ‘Special destinations’ to a SD-card. You then ask the car to read the SD card.
Here’s a typical file structure for the SD card:
total 8
drwxr-xr-x 4 mjo staff 136 19 Jul 20:45 PersonalPOI
-rw-r--r-- 1 mjo staff 1618 19 Jul 23:07 metainfo2.txt
PersonalPOI:
total 0
drwxr-xr-x 3 mjo staff 102 19 Jul 20:45 InfoFile
drwxr-xr-x 3 mjo staff 102 19 Jul 20:45 Package
PersonalPOI/InfoFile:
total 0
drwxr-xr-x 3 mjo staff 102 19 Jul 20:45 0
PersonalPOI/InfoFile/0:
total 0
drwxr-xr-x 3 mjo staff 102 19 Jul 20:45 default
PersonalPOI/InfoFile/0/default:
total 8
-rw-r--r-- 1 mjo staff 1448 19 Jul 23:07 Update.txt
PersonalPOI/Package:
total 0
drwxr-xr-x 3 mjo staff 102 19 Jul 20:45 0
PersonalPOI/Package/0:
total 0
drwxr-xr-x 12 mjo staff 408 19 Jul 23:07 default
PersonalPOI/Package/0/default:
total 88
-rw-r--r-- 1 mjo staff 28 19 Jul 23:07 PPOIversion.txt
drwxr-xr-x 4 mjo staff 136 19 Jul 21:45 bitmaps
-rw-r--r-- 1 mjo staff 221 19 Jul 23:07 bitmaps.xml
-rw-r--r-- 1 mjo staff 1302 19 Jul 23:07 categories.pc
-rw-r--r-- 1 mjo staff 1247 19 Jul 23:07 hashes.txt
-rw-r--r-- 1 mjo staff 269 19 Jul 23:07 lang_map.xml
-rw-r--r-- 1 mjo staff 11264 19 Jul 23:07 poidata.db
-rw-r--r-- 1 mjo staff 150 19 Jul 23:07 strings_de-DE.xml
-rw-r--r-- 1 mjo staff 150 19 Jul 23:07 strings_en-GB.xml
-rw-r--r-- 1 mjo staff 613 19 Jul 23:07 versions.xml
PersonalPOI/Package/0/default/bitmaps:
total 48
-rw-r--r-- 1 mjo staff 2342 27 Jul 07:12 image_1010.png
-rw-r--r-- 1 mjo staff 1862 27 Jul 07:12 image_1011.png
-rw-r--r-- 1 mjo staff 10161 19 Jul 23:07 stacking_2.png
-rw-r--r-- 1 mjo staff 10979 19 Jul 23:07 stacking_3.png
The reality
However in reality using this is a pain. In principle Audi could teach the car about GPX files avoiding the cloud entirely, or allow you to upload and download multiple types of data at once. In reality, you must:
- upload a separate file for each type of waypoint;
- download a file which turns out to be a small Java program;
- run that ignoring all the warnings about unsigned binaries;
- let this program download yet more data;
- save the data using the awful Java file-chooser.
Having banished Java from my Mac, it was galling to have to reinstall it for this, particularly given all the nonsense Oracle try to foist on you when installing software.
Standing back
Although the implementation seems foolish to me, in essence the task is simple: given some coordinates convert them into a set of files compatible with the Audi’s MMI.
If you look at the files from myAudi, you’ll see that it’s all fairly straightforward. After a bit of digging, it was obvious that:
- All the coordinate data are stored in a SQLite3 database with R*Tree2 and full-text search3 extensions.
- Most of the important files have checksums stored too: the algorithm is SHA1.
- There is no crypto involved, so we don’t have to worry about keys.
SQLite schema
Here is the basic database schema:
CREATE VIRTUAL TABLE poicoord USING rtree(poiid INTEGER,
latmin REAL,
latmax REAL,
lonmin REAL,
lonmax REAL);
CREATE TABLE poidata(poiid INTEGER,
type INTEGER,
namephon TEXT,
ccode INTEGER,
zipcode TEXT,
city TEXT,
street TEXT,
housenr TEXT,
phone TEXT,
ntlimportance INTEGER,
exttype TEXT,
extcont TEXT,
warning TEXT,
warnphon TEXT,
CONSTRAINT PK_poidata PRIMARY KEY (poiid));
CREATE VIRTUAL TABLE poiname USING fts3 (name TEXT);
Astute observers will note the lack of a poiid
column in the poiname
table, which breaks normal form! There appears to be an implicit assumption that the first row inserted into poiname
corresponds to poiid == 1
, and so on.
SHA-1
Most of the files are small, and their checksums are computed using normal SHA-1.4 Larger files are first cut into 512kB chunks, and each chunk processed individually. The chunk size is specified in the files, so perhaps you could change it: I have not explored this.
In one case a file contains its own checksum: what this really means is that the file contains the checksum of the file with that line removed.
File sizes
Reference is also made to the size of files. When referring to the size of the hashes.txt
file (which stores information about other files) the number in question is actually the total size of the files to which reference is made in hashes.txt
.
Icons
Each class of waypoints is associated with an icon. I used 33×33 pixel icons in my tests, and those numbers are implitly embedded into magic constants in the code.
Metadata
I suspect you can have fun messing around with the metadata to promote your waypoints higher up the waypoint hierarchy, and tweaking their display on the map. I have not explored this.
File names and version numbers
I made guesses about the formats these should have, and hoped that here not be magick. Thus far it seems to be OK.
Proof of concept
I wrote a quick proof-of-concept library in Perl. It takes the form of a single file, which you can grab from GitHub.5
The file is quite large, in part because it contains uncompressed versions of some icons which appear to be included in every download.
It is not production quality code, it might not work, and it might break your car. Use it at your own risk.
References
- 1. http://mcaddy.github.io/audipoi/
- 2. http://sqlite.org/rtree.html
- 3. http://sqlite.org/fts3.html
- 4. https://en.wikipedia.org/wiki/SHA-1
- 5. https://github.com/mjoldfield/audi-waypoint-upload