This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass
What I Built
Run Club Route Builder
Type what you want ("5K, shaded, fall foliage, starts at Branch Brook Park") and get three loop options on a map, ranked by tree and park cover. Download any route as GPX for your watch or phone.
Built for the Hacktoberfest "Touch Grass" challenge. The screen should be the shortest part of the run.
How it works
Parse the request with a small open-weight model running locally through Ollama (default qwen2.5:3b). If Ollama isn't reachable, a built-in regex parser takes over, and the page tells you which one ran.
Find the start with OpenStreetMap Nominatim, or use your phone's location.
Generate loops: six candidate loops in different directions, routed on real paths and sidewalks by the OSM foot router.
Score them with OpenStreetMap data from Overpass: how much of each route is inside parks, woods, and grass, or within about 20 m of a mapped tree, plus nearness to water.
Check hills with Open-Meteo elevation (Copernicus DEM): up to 100 points per route, total climb with small bumps filtered out, and a mini elevation profile on each card.
Rank by your preferences (shade, foliage, green, water, flat, hilly) minus a penalty for missing your target distance. "Flat" and "hilly" only affect ranking when you ask for them; climb is always shown.
No framework, no build step, no API keys.
Run it
cd run-club-routes
python3 -m http.server 8000
open http://localhost:8000
Local model (optional but the point)
ollama pull qwen2.5:3b
OLLAMA_ORIGINS="*" ollama serve
OLLAMA_ORIGINS lets the browser page call Ollama. Settings on the page let you change the URL and model.
On your phone
Serve the page from your laptop and open http://<laptop-ip>:8000 on the same Wi-Fi.
To use the laptop's model from the phone, start Ollama with OLLAMA_HOST=0.0.0.0 and set the Ollama URL in Settings to http://<laptop-ip>:11434.
Or skip the model: the fallback parser handles typical requests.
The geolocation button needs HTTPS on most phones; localhost is exempt, a LAN IP is not. Typing a start place works everywhere.
Honest limits
"Foliage" is a proxy: tree and park coverage in OpenStreetMap, not actual leaf color. Mapped trees are sparse in some areas, so suburban street shade may be undercounted.
Elevation comes from a coarse (~90 m) terrain grid. Big hills show up; short steep pitches and bridges/underpasses do not, and small bumps under 3 m are ignored on purpose. Treat climb as a rough guide.
Routes depend on public OSM services (rate limited; fine for personal use, not for a deployed public app).
The map tiles, geocoding, tree data and elevation need internet. Routing can be self-hosted (see above). A fully offline version also needs cached tiles and local copies of the other three.
The self-hosting scripts are untested: I could not run Docker where I wrote them.
Privacy, precisely
Your request text is parsed by the local model and never goes to an AI vendor. The start location does go to public services: OpenStreetMap geocoding and Overpass, Open-Meteo for elevation, and the public OSM router.
Self-hosted routing: selfhost/ runs OSRM in Docker on your own machine; put its address in Settings > Routing server and loop generation stays local. See selfhost/README.md. Geocoding, tree data and elevation are still public, so this is a step toward private and offline, not the whole way.
The write-up for the challenge is in POST.md.
Field test checklist (bonus points)
Run or walk one generated route and note how it matched reality (shade? foliage? dead ends? road crossings?).
Note anything the scorer got wrong; that is the most honest part of the write-up.
Photo of the route on the trail.
Demo
Code
https://github.com/mreidy-devai/Hactoberfest2026
How I Built It
Using Claude, Ollama, Openstreetmap, and Docker
Why Does Open Innovation Matter?
The strongest reason is the data, not the model.
The data is the real case. The page works by asking a question about each route: how much of it is inside a park or woods, or within about 20 m of a mapped tree? That needs the underlying map features, not just directions. A closed mapping API gives you directions but generally not raw park and tree geometry to analyze, and its terms often restrict bulk use. OpenStreetMap lets me query all of it. If a footpath or park is missing, anyone can add it, including your run club, and the routes get better for everyone.
Privacy is a real stake for runners. The start point is often your front door. Because the router is open source, I could build the option to run it on your own machine, and the page deliberately won’t fall back to the public one. Part of this is still a promise rather than a fact. Geocoding, tree data and elevation still use public services, so your start point still leaves the device.
Cost and control. No API keys, no per-call fees, and no vendor deciding to change pricing. That matters for something a volunteer-run club might use. You can also swap the model with one text field.
The open model matters less than it sounds. All it does is turn a sentence into a few fields, and the built-in rules handle most requests on their own. So I wouldn’t lead the post with the model. The model-off check in the field test is how you find out for sure. If the results are the same either way, say so. Saying “the open data mattered most, and the model was the least important part” is more credible than claiming the model was essential. -->
Top comments (0)