Prologue: Three Things I Could Not Stand
If you drive, this has probably happened to you: your dashcam proudly advertises “built-in speed camera alerts”, the feature is switched on, and one day a ticket still shows up in your mailbox. The newly installed camera simply was not in the database.
After digging into this product category, I found three fundamental problems:
First, dashcam map data never updates itself. The built-in camera database is a snapshot from the day the device left the factory. Updating it means hunting down a file on the vendor’s website, pulling out the SD card, and flashing it through some buried menu. Most people never do it even once, so the data stays frozen in whatever year they bought the device.
Second, nobody on the market supports Android Auto properly. My daily routine is plugging my phone into the head unit and navigating with Google Maps. The speed camera apps out there either do not support Android Auto at all, or they support it by fighting with your navigation and covering the map every time an alert fires. That defeats the whole purpose.
Third, the interfaces are just ugly. Design taste in this category is stuck in the early smartphone era: skeuomorphic buttons, neon numerals, a rainbow of icons crammed into every corner. This is something I look at every single day in the car. I refuse to settle.
After enough complaining, only one option was left: build it myself.
What Is Speed Camera OUT!

Speed Camera OUT! is a speed camera alert app built for drivers in Taiwan. The core idea fits in one sentence: stay quietly in the background, and only speak up when it matters.
- Pure background operation: alerts play on Android’s dedicated alarm stream (
STREAM_ALARM) together with heads-up notifications. You keep navigating with Google Maps as usual; the alert cuts through the voice guidance but never interrupts the map on screen. - Native Android Auto support: the head unit gets its own digital speed panel, and you can toggle between elevated and surface road modes with one tap right on the car screen.
- Plug and play: protection starts automatically the moment your phone connects to the car over USB, and shuts down when you unplug or kill the engine. Get in and drive, zero taps required.
The interface itself was rethought from scratch in Jetpack Compose: a dark dashboard base, a large speed readout you can parse at a glance, and a single orange accent color. One quick look while driving gives you everything, with no visual noise to dig through.
A Map That Grows on Its Own: the Fully Automated Rectification Pipeline
This is the problem I most wanted to solve: the freshness and precision of map data.
Camera data comes from Taiwan’s open government dataset, and the pipeline syncs the list daily. But the open data has a nasty trap: the direction field only contains rough text like “southbound”, “northbound”, “both directions”, or “towards the HSR station”. On curved segments (the coastal Highway 61, the mountain stretches of National Freeway 3), naively converting text into one of eight compass bearings produces errors of 30 to 60 degrees, which wrecks alert accuracy. Landmark-style descriptions like “towards the HSR station” cannot be converted at all.
So I built a fully automated azimuth rectification pipeline that runs on a weekly schedule, end to end:
graph LR
A["Government open data<br>daily list sync"] --> B["Macro heuristics<br>freeway mileage segmentation"]
B --> C["OSM geometry refinement<br>Overpass API"]
C --> D["AI hybrid engine<br>Gemini + Nominatim"]
D --> E["Weekly scheduled release<br>auto-updated map data"]
- Macro heuristics: long freeways have predictable large-scale geometry, so mileage-based segmentation gets the general bearing right first.
- OSM geometry refinement: the Overpass API pulls the road geometry within 50 meters of each camera, computes the tangent angle of the actual road segment, then a four-way trigonometric disambiguation picks the shooting direction.
- AI hybrid engine: landmark-style descriptions like “towards the HSR station” or “downhill”, which pure geometry cannot handle, go to Gemini AI combined with Nominatim geocoding.
The result is a map that grows and corrects itself every week, currently maintaining over nine hundred precise bearings automatically. A dashcam can never do this, because its map died the day it shipped.
Radar Algorithms: More Than Drawing Circles
Most speed camera apps detect with “draw a circle around the camera, beep when you enter it”. In urban areas and around elevated roads this produces endless false alarms: cameras one street over fire, cameras on the parallel road under the viaduct fire, and eventually the user just mutes the whole thing.
This app is more deliberate in a few places:
- Vector corridor projection: the detection zone is not a circle but a corridor along your direction of travel, using cross-track error to filter out cameras on parallel roads. A camera one street over is not your problem, no matter how close it is.
- Geohash spatial index: nearby camera lookup runs in constant time via Geohash, keeping CPU load and battery drain to a minimum.
- Direct vehicle hardware data: GPS drifts in tunnels and under viaducts. Through
CarHardwareManagerthe app reads wheel speed and compass bearing straight from the car’s CAN bus, switching over seamlessly the moment GPS drops, so your speed readout never jumps around. - Section speed state machine: when you enter an average speed enforcement zone, a dedicated state machine tracks your average across the whole section, showing live average speed, the limit, remaining distance, and a progress bar that changes color when you are over.
Making It Not Boring: Five Gamification Mechanics
Utility apps share a curse: no matter how well they work, the user never feels it. The alert fired, you slowed down, no ticket came. And then? Nothing remains.
So I added a set of gamification mechanics that turn every safe pass into something you can see accumulate:
- Accumulated stats: every camera pass gets settled. Pass safely and the app estimates, based on Taiwan’s traffic fine schedule, how much money that pass just saved you; speed through it and it honestly logs a violation. The stats page does not show cold counters, it shows “how much money this app has protected so far”.
- Achievement system: milestones like safe passes and accumulated distance unlock badges and titles, and earn achievement points along the way.
- Reward shop: achievement points are not decoration. They buy real rewards such as subscription extensions, voice packs, and map themes.
- Trip history: every trip’s track is kept, and you can replay it on a map afterwards. The tracks live only in your own private Google Drive space (appDataFolder); my backend never touches your location data at any point.
- Personal map: spotted a camera with a wrong bearing? Log into the web member area and fix its azimuth and dual-direction attributes right on the map, synced instantly to your personal cloud profile. Your map keeps molding itself to the roads you actually drive.
These five mechanics chain into a flywheel:
graph TB
DRIVE["Drive"] --> DATA["Accumulated stats<br>see the fines you avoided"]
DATA --> ACH["Unlock achievements<br>earn points"]
ACH --> SHOP["Reward shop<br>real rewards"]
SHOP --> BETTER["The app keeps getting better"]
DRIVE --> MAP["Personal map<br>ever more accurate"]
MAP --> BETTER
BETTER --> DRIVE
The longer you drive, the more accurate it gets, the more you save, and the harder it becomes to switch away. That is exactly the effect I wanted.
Tech Stack at a Glance
| Layer | Tech |
|---|---|
| Android App | Kotlin, Jetpack Compose, Room, FusedLocationProvider with Vincenty high-precision inverse formula |
| Android Auto | androidx.car.app (POI category, full driving safety restrictions) |
| Backend | Cloudflare Workers, D1, R2, fully serverless |
| Map pipeline | Node.js, Overpass API (OSM), Google Gemini AI, scheduled via GitHub Actions |
The backend runs entirely on Cloudflare’s serverless stack, and the map pipeline runs itself on GitHub Actions schedules. The system needs no babysitting from me; it raises its own map.
Closing
This project started as three personal grievances: stale map data, nobody doing Android Auto right, and ugly interfaces. Along the way it grew into a system that updates its own map and carries a gamification flywheel.
If you drive Android in Taiwan, give it a spin:
- Google Play: Speed Camera OUT!
- Web member area: speed-camera-out.taislife.work
If you try it and have thoughts, leaving a Play Store review is the fastest way to reach me.