v1.2.3 · Android · offline by default

TRAMES

Navigation that routes around automated licence-plate readers — entirely on your phone. An ordinary route request — an address, a destination — with one extra constraint: prefer roads that no ALPR camera can actually see. Routing runs offline by default, so where you are and where you're going never leave the device.

TRAMES navigating from Idylwood to Fairlington: a blue route curves away from a dense cluster of red camera markers, and a toast reads "1 licence-plate reader(s) can see this route."
0avoidance levels
120,838cameras mapped
0states, offline
v1.2.3latest APK

Trames (Latin): byways, side roads. · Debug-signed APK — sideload; no Play Store. Read the README.

Built on
  • OsmAnd (GPLv3)
  • GraphHopper 11
  • OpenStreetMap · Overpass
  • DeFlock ALPR map
🗺

The one that acts — sibling to OVERWATCH & VIGIL

OVERWATCH shows you the surveillance watching a place right now. VIGIL shows you what has been following you over time. TRAMES is the one that does something about it — it takes the same map of cameras and drives you around them.

A camera watches one way. So we model it that way.

A reader pointed at northbound traffic says nothing about the southbound carriageway. Treat it as a circle and the router detours around roads nobody is being read on. TRAMES models every camera as a cone pointing where it actually looks, and asks for the fastest path that crosses none of them.

TRAMES map over Reston, Virginia: red ALPR camera markers, each drawn with a translucent wedge showing the direction it watches, some clustered into groups.
1
Directional cones, not dots

Each camera becomes a wedge aimed the way it faces. A route that passes a reader on the far carriageway isn't penalised — it was never seen.

2
Baked into the graph

120,838 camera cones are compiled into GraphHopper's spatial index at import as one area, alpr. A request just references it — {"if": "in_alpr", "multiply_by": 0.05} — no geometry attached, so the payload stays tiny.

3
Strength is a live knob

Because the penalty rides on each request, avoidance strength stays a per-route slider instead of being frozen into the graph. No forked routing engine required.

4
See what you're avoiding

The map draws the same cameras the router steers around — from the server's own snapshot, so the picture matches the route. Overpass is a fallback, not the only source.

Install, type a destination, it already avoids.

Avoidance is the whole point of the app, so it is no longer opt-in homework. A fresh install sets itself up on first launch — no engine to create, no URL to paste, no setting to find.

On by default, offline by default

First launch sets the driving profile to the offline engine at Strong avoidance. Download your state, enter where you're going, and the route already bends around camera fields of view — computed on the phone, with nothing sent anywhere. The only thing you touch is the destination.

🎚

Your call, and it sticks

Turn avoidance down, off, or up — the app seeds itself exactly once, so your choice is never overwritten on the next launch.

🚲

Driving, cycling, walking

A camera is a camera whether you drive, ride or walk past it. All three profiles get the same five levels, and a level means the same thing in each.

🧩

Installs alongside OsmAnd

Package org.soulstone.trames — a distinct app, not a replacement. Keep your OsmAnd exactly as it is.

🛰

Self-host friendly

Point the engine at your own GraphHopper if you'd rather. Upgraders who configured one by hand keep it, custom strength and all.

🧭

A real navigator underneath

TRAMES is a fork of OsmAnd, so turn-by-turn voice guidance, offline maps, lane hints and the rest are all there — the avoidance is one honest constraint layered onto a mature navigation app, not a demo.

Five levels, from fastest to leave-no-plate-unturned.

The levels aren't evenly spaced, and that's deliberate: measured on the continental graph, everything from off down to about a third leaves most routes unchanged — a penalty can't outweigh a highway. So the useful range is packed where it actually bites, and the effective strength shifts with how dense the cameras are around you.

OFF

Fastest route. No avoidance — TRAMES navigates like any other app.

LIGHT

Avoid readers only where the detour is nearly free.

MODERATE

A balanced trade — dodge most cameras for a modest cost.

STRONGdefault

Avoid readers wherever a reasonable alternative exists. Where TRAMES ships.

MAXIMUM

Avoid every camera it can find a way around, whatever the extra time.

Does avoidance actually cost anything? We measured it.

We routed 17,580 real home–work commutes — drawn from Census LEHD LODES in proportion to how many workers actually make each trip, across 15 states — twice each: once normally, once avoiding the fields of view of 120,838 mapped ALPR installations.

17,580commutes routed, twice each
74.8%pass at least one reader
84.6%can route to zero exposure
+1.5 minmedian cost to do it (5.96%)
📈

Avoidance is cheapest where cameras are densest

A metropolitan grid always offers a parallel street a block over; a rural route often has one road and no alternative. So the burden of refusal falls hardest on the drivers with the fewest cameras to refuse. The full method, limitations, and the equity findings are in the paper. Read the paper (PDF) →

The route, the cameras, the drive.

Real routes over real ALPR data — the avoided cluster, the directional markers, and turn-by-turn guidance that already went the quiet way.

A planned route from Idylwood to Fairlington curving away from a dense red cluster of camera markers, with a readout of 9.26 mi, 18 min, and a toast: 1 licence-plate reader can see this route.
Routed around the clusterThe blue line bends away from a wall of readers on the right — and the app tells you exactly how many can still see the route.
Map of Reston, Virginia with red ALPR camera markers, each drawn with a translucent wedge indicating the direction it faces.
Directional camera layerEvery reader drawn as a wedge pointing where it looks — the same cones the router avoids, so the map matches the route.
Turn-by-turn navigation following King Street, with ALPR camera markers visible along the route.
Turn-by-turn, the quiet wayFull OsmAnd navigation — voice, lanes, offline maps — on a route that already chose to avoid what it could.

Routing happens on your phone. Nothing about you leaves it.

Earlier versions routed through a server, which meant handing over every start and destination — the exact movement record this app exists to avoid. As of v1.2.0 that's inverted: the private path is the default and the network is opt-in. Here's the whole posture.

📴

The default sends nothing

Routes are computed on the device against maps you've downloaded, so your start, destination and timing never travel. Airplane mode changes nothing — avoidance keeps working. Avoiding cameras while streaming your itinerary to a host isn't privacy, so we stopped doing it.

🛑

The map doesn't phone home either

Camera positions come from a 1.1 MB pack on the device. A camera query would carry a box around your current view — your location — so those requests are denied by default and only permitted if you deliberately switch a profile to online routing.

🌐

Online is still there, opt-in

Prefer fresher camera data, or need an area you have no map for? Pick the online engine in navigation settings and it works as before — open, no account, no API key. Or point it at your own GraphHopper.

🧾

Open source, open data

The client, the server, and the study are all public. Camera data is © OpenStreetMap contributors under ODbL, largely mapped by the DeFlock community.

🔑

Read this before you trust the build

The APK is signed with the public Android debug key. Anyone can build one that looks identical, so the signature proves nothing about who built it. Verify the SHA-256 on the release, or build from source.

Sideload in four steps.

TRAMES turn-by-turn navigation following King Street with camera markers along the road.
1 · download
  • Grab the latest debug-signed APK from Releases (currently v1.2.3, arm64-v8a, Android 7.0+).
2 · install
  • Sideload it — allow "install unknown apps" for your browser or files app, then open the APK. It installs alongside OsmAnd.
3 · get your maps
  • Open TRAMES offline maps in the drawer and download your state — the camera data (1.1 MB) comes with it. Routing is offline by default, so this step is what makes it work.
4 · just drive
  • Grant location, type a destination — avoidance is already on. Tune the strength in the driving, cycling or walking profile if you like.

Build from source, read the paper, or file issues: github.com/KaraZajac/TRAMES · the paper