Second day of “quick” weekend project.
Frankly, I’ve run out of interesting things to map around my immediate surroundings. During the holiday season I travelled around the countryside and noticed long stretches of cycleways running alongside highways, occasionally featuring benches, bins, and similar roadside infrastructure. On one trip I tried mapping a rural street using EveryDoor, but the result was similar to summer cycling: frequent stopping dropped my average speed by 10–15 km/h.
I needed a solution where I could mass-save coordinates while moving, and deal with proper mapping later. Vespucci’s copy-paste workflow is probably the closest thing in the OSM ecosystem, but it still requires first tagging a node, then tapping the correct spot on the map. If the map is accidentally dragged, follow-position mode is disabled, and changing the type of copied element requires tagging a new node.
After concluding development I was suggested OsmAnd may support something similar.
I’m android user, so the problem was phrased as “Is there some Android app with a super fast UI for saving coordinates?”
A quick search showed that virtually no existing apps allow bulk bookmarking of unnamed unorganised coordinates My intention was save location something i could later properly map from aerial images. Most apps seemed to require at least 2-3 taps to save position, often with typing bookmark name.
Functional requirements
For time estimates and comparison I used my typical summertime EveryDoor mapping experience. Potential mapping-assisting app should consider these points:
- The app must pick location directly from phone GPS. Dragging the map to the exact location is slow.
- Dragging is also data-intensive. Inaccurate GPS forces switching to aerial imagery and zooming in to place nodes correctly. Using osm-carto consumes less data, but nodes often end up 20–40 m off.
- Since nodes are placed at phone GPS position, they will usually land on the road; definitely not where roadside infrastructure actually is.
- Therefore app must not upload data directly to OSM, but to own backend instead.
- No searching for presets. Typing while moving is error-prone, and preset search could easily fail due to typos.
- Loading presets and tagging would take an extra 15-45 seconds, or 500-1000 m at highway speeds.
- No detailed tagging in-app.
- The in-app don’t need valid OSM tags; simple predefined labels are sufficient.
- No manual uploads. Button presses should be sent to the server automatically.
- Data should be sent in small batches to save data overhead
- 10 sec batch window turned out to be too short
- In the countryside, network connection could be unreliable
- GPS position must update as frequently as possible
- The app should always capture two positions per note, allowing speed and azimuth calculation if the browser doesn’t provide them.
- The time between two positions should be as long as possible to reduce noise
- Assume the phone is safely mounted near the dashboard or window pillar, close to the steering wheel
- Therefore time spent on hand movement is minimal
- Battery usage isn’t a concern due to car charging; keeping the screen active is a bigger issue.
- The app should support a small set of predefined node types, not just one. For example bench, bin and traffic calming.
- Since I’m mostly a web developer, the app ought to run in mobile browser.
- Ideally this would work like a dashcam “record” button, but:
- My dashcam has no GPS.
- A browser app can’t realistically control a third-party dashcam.
- Pulling images from the camera on button press is even harder.
- Dashcam Wi-Fi would disable mobile data.
- The dashcam is mounted near the rear-view mirror, making it harder to reach than the phone.
Implementation
Looking at message timestamps, it took roughly 40 minutes from the initial question to a basic MVP, and another 40 minutes to deploy, test on a phone, and fix obvious bugs. Unfortunately, I tested the app while stationary and didn’t notice that AI had implemented GPS caching twice leading to refresh 15 second refresh rate. Luckily i had phone during trip in split-screen mode shared with navigator, therefore i didn’t experience GPS refreshing errors like later.
After initial testing, I spent around 6 hours trying to bypass browser and OS restrictions to force faster GPS updates. Locking the screen dropped GPS entirely, although it could sometimes be recovered. I still don’t fully understand why, but the only way to get a reliable stream of coordinates was to keep a native GPS-using app (e.g. GMaps or a low-level GPS debugger) running alongside the browser in Android’s multitasking view. I even tried dual tracking with one thread polling precise and other WiFi positioning.
Aftermatch
Due to GPS caching, saving two points 2–10 seconds apart often resulted in identical coordinates. That made it very difficult to establish where the second object should be. Even worse, I often couldn’t remember what I had intended to mark despite having rough location and travelling direction.
In one location I had marked 1 bench and 1 bin, 8 seconds apart, at the same coordinates. Eight seconds corresponds to roughly a 150–200 m search radius. Within that area I found 4 bins and 3 benches from rather blurry imagery, 5 of them already mapped.
Secondary coordinate pairs for speed and direction rarely worked because cached positions were reused. Luckily many points had azimuth information, but speed was usually missing.
I didn’t actually encounter any traffic tables, that label was repurposed as bicycle parking. A grey, unsortable HTML table of decimal coordinates wasn’t very helpful either, so today I added a basic Leaflet map view to render the notes spatially.
Now that I’ve started mapping some of these notes, I also need a way to delete or mark resolved entries. Potential workaround is downloading the SQLite database, editing it locally, and uploading it back to the server.
Technical
Setup is simple:
- 1x Sqlite database (single table)
- 2x PHP backend endpoints (read & insert)
- 3x UI views (data entry, table view, map view)
Ideally the database should be more normalized, but this was a 30-minute prototype and there was no time to improve schema. If this hadn’t worked at all, I would have just stored raw JSON requests as text files.
There’s currently no real authentication beyond an optional username field. Currently it could be treated as extra additional information field.
Source code at github. Code is currently written by approx. 50% GPT, 40% Claude, 10% me.
Few screenshots. Data entry view:

And map view

While the prototype works technically, using the collected data turned out to be harder than expected. The experiment was still useful as i now have 100+ potential features to map. About 1/4 of them was added in changeset/177738315.
PS. Do not try this at home, nor away. Only as passenger.