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:

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:

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.