Skip to content
Ribhav Hora

Projects

Park Tracker

Building
Role
Solo: product & engineering
When
2026
Stack
SwiftUI, Core Location, MapKit, SwiftData, OpenStreetMap

Source

I walk in Central Park most days and kept ending up on the same loop. The question that started this was small and specific: how much of the park have I actually seen? Not “how many miles did I run”; every fitness app answers that. How much of the park.

Nothing answered it, so I built it.

Loading the park…

0.0% of the park0.0 miles

Drag the blue dot along the paths to walk, or simulate a walk. Reset sends it back to the start.

An interactive recreation of the coverage map, drawn from the app's real OpenStreetMap path data. The app itself is native iOS.

The product decision that shaped everything

The obvious implementation is an area grid: tile the park, light up a tile when you enter it. It’s easy to build and it feels good for about a week. Then you notice it’s lying to you: standing in one spot near a wide meadow fills in tiles you never walked, and a long thin path through dense woods barely registers.

Central Park isn’t an area you cover. It’s a network of paths you traverse. So coverage is defined against the path network itself: every walkway, bridle path, and stair in the park, and the percentage is walked meters over total meters. It is a harder thing to build and a much more honest number. 61.4 miles, and getting to 100% means genuinely walking all of them.

How it works

Path geometry comes from OpenStreetMap via the Overpass API, pulled by a script in the repo and bundled with the app so it works with no network. At launch the raw ways are split into ~20 metre segments, about 14,900 of them, each with a stable {wayId}_{index} ID so progress survives a data refresh. Twenty metres is the resolution that turns out to matter: coarser and you get credit for paths you only crossed, finer and GPS noise starts marking parallel paths you never took.

A walk is a session, not always-on background tracking. You tap start, the map follows you, and it shows elapsed time and session miles. Location updates get matched against nearby segments with the tolerance tuned so that walking one side of a divided path doesn’t spill over onto the other.

Park Tracker mid-walk: a live stats bar reading 19:42, 1.30 miles now, 50.6% complete, the user's blue location dot on a map where the walked paths are drawn in green, and a red Stop walk button.
The real app mid-walk: elapsed time, miles added, and paths lighting up green as you cover them.

The part I’m happiest with is the ending: the app knows the park’s boundary polygon, so when you leave and don’t come back within a two-minute grace period, the session stops itself. You never have to remember. You just get a notification (“you grew from 34% to 37%”) and a summary map with the new paths lit up.

State lives in SwiftData, so everything persists across launches, and there’s a backup and reset path for when the model changes.

Where it’s going

It’s on TestFlight-adjacent status: building, not shipped. The next questions are the interesting ones: does this generalize to any park with OSM path data? Prospect Park, the Presidio, Golden Gate Park all have the same geometry available. And what does the social version look like? Is the compelling artifact the percentage, or the map?