Z-Maps Car
Features
What appears on the driving screen, and what you can change in Settings.
The driving screen
What is on screen while you drive
The whole driving loop lives in a foreground service rather than in the Activity — on a head unit the Activity is stopped at any moment: select reverse and the camera takes the whole screen, take a call and the phone app jumps in front. The trip and the alerts have to survive that.
The speed changes colour by severity
White inside the limit, amber inside the safety margin, orange over it, red well over. Readable at a glance, without reading words.
A speed sign that looks like a speed sign
White disc, red ring, exactly like the R.127 sign on the road. A value the app inferred carries a '~ estimated' line under it.
GPS status is always visible
Waiting for GPS, GPS good, or speed being computed from fixes rather than taken from the driver — you always know what the number rests on.
Road matching against the rendered frame
RoadMatcher queries the road features currently being drawn to work out which segment you are on, its name and its class.
Correct a limit from the car
Where the app has guessed wrong, open the limit editor, pick the right figure, and it is remembered for the area around that position. 'Use the default again' undoes it.
The trip is measured, then kept
Distance, moving time, average and maximum speed and overspeed events accumulate through the journey and are written to the history when it ends.
Settings
Tuned to your car and your driving
Safety margin
Only alert once you exceed the limit plus this much. It defaults to +5 km/h because GPS is a few km/h out; zero would make it cry wolf.
Voice or beep
If the device has no Vietnamese voice, the app falls back to a beep — a lot of head units ship without a vi-VN TTS engine at all.
Turn the estimated limits off
With it off, roads that have no limit data raise no alert at all, rather than alerting against an inferred number.
Map style
Liberty for full detail, Dark for night driving, Positron for a quieter, paler screen.
Keep the screen on
Some head units blank the screen mid-journey. This keeps it lit for the whole trip.
Clear the map cache
The app caches up to 512 MB of the roads you drive. If storage is getting tight, clear it from Settings.
Trip history
Opened from Settings: total trips, total distance and total time, plus each journey with its average speed, maximum and overspeed count. Delete one trip or all of them.
Clear your limit corrections
Drops every figure you have overridden, so the app goes back to map data and its estimates.
Two things are the app's inference, not the law
Stated plainly here because both directly affect the number you see on the sign.
- Built-up areasInferred from the map's landuse layer, because OSM does not mark the R.420 / R.421 signs. That is an inference, not a sign being read.
- The road-class ceilingThe law allows 80 km/h on any two-way road outside an urban area, including a 3 m concrete village lane. The app caps by road class instead, so its figure can be lower than the law permits — deliberately, because warning early is safer than warning late.
Three real problems
The hard parts, and how they were handled
The head unit reports zero speed while the car is moving
Many GPS modules parse only $GPGGA and never $GPRMC, so Location.hasSpeed() returns true while the value stays at zero. Trusting it leaves the speedometer frozen forever.
SpeedEstimator runs two sources side by side — what the driver reports, and speed derived from consecutive fixes. After roughly eight 'moving' samples with the driver still reporting zero, it concludes the driver is broken and switches over permanently. There is a unit test for exactly this case.
location/SpeedEstimator.ktPublic tiles do not carry the maxspeed tag
The OpenMapTiles schema has no maxspeed field, even for roads that are tagged in raw OSM. With free tiles, close to 100% of speed limits have to be inferred.
VietnamSpeedRules implements Circular 31/2019/TT-BGTVT for cars and trucks up to 3.5 t: 50–60 km/h in built-up areas, 80–90 km/h outside them, depending on whether the road is divided. Every inferred value is displayed with the '~ estimated' marker.
speedlimit/VietnamSpeedRules.ktAn annoying alert gets the app switched off within ten minutes
An alert that flickers with GPS noise, or repeats the same sentence, is the fastest way to have a speed-warning app turned off and never turned back on.
OverspeedEngine has a 3 km/h hysteresis band, cooldowns of 30/20/12 seconds by severity, and a default +5 km/h safety margin — but escalating to a worse level speaks immediately. VoiceAlerts requests transient ducking audio focus, so music is lowered and then restored.
alert/OverspeedEngine.ktTry it in your own car
The APK is split by CPU architecture; the smallest build is 10 MB.
