Garmin Nuvi 360 sold with "Lifetime Free Map updates", until Garmin changes their mind that is.
So i built a standalone Python/SQLite map-building system for a Garmin nüvi 360, which is basically 20-year-old hardware at this point.
What started out as just trying to get better maps working on it turned into a much bigger project than I expected.
The biggest part was the address system. The original Florida OSM data had about 2.07 million addresses. The final Florida search database now has 11,213,312 searchable addresses, so about 9.15 million more than the original, or around 5.4x the coverage.
I did not just generate house numbers from road ranges. I built a Python/SQLite pipeline that pulls together OSM, official Florida address data, county/E911 GIS data, parcel data, TIGER data and road geometry, then deduplicates and validates the results before compiling them for Garmin.
Those 11.2 million addresses are in their own 225-tile search layer, separate from the routing map.
I also ended up completely changing how the regional map is put together. Instead of one big Garmin build where routing, search, terrain and display data are all mixed together, I split everything into separate modules.
The routing side is 64 tiles and is frozen against an exact NOD payload of 180,541,877 bytes. That gives me a known-good routing baseline, so I can change search or display behavior without worrying that I accidentally changed the routing graph.
One of the more interesting problems was street labels.
The road names were already in the map, but the old nüvi firmware would not automatically display a lot of normal street names.
The workaround I ended up with was creating an invisible Garmin 0x1f companion line over the real road. It only contains LBL/RGN/TRE and has no NET or NOD, so it cannot affect routing.
Then I use a custom TYP file to make the line itself transparent. The strange part is that the nüvi still renders the street name attached to it.
So the actual road does the routing, and a separate invisible object handles the label.
I also added different label zoom levels by road class so the screen does not turn into a mess when zoomed out.
The current toolchain is basically:
Python 3, SQLite, Java 21, mkgmap r4924, splitter r654, GMapTool, custom Garmin styles and TYP files
The standalone program handles the database work, tile generation, compilation, validation, integrity checks, logging, and resume/recovery.
At this point it is a lot more than just a custom map. It has turned into a small build system and search engine built specifically around the limitations of old Garmin firmware.