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.
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.
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.
how it works
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.
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.
out of the box
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.
avoidance strength
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.
the measurement study
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) →
screenshots
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.
the honest part
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.
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.
get it
Sideload in four steps.
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.