OSM hiking & cycling trail routing for Land mode#41
Open
radumarias wants to merge 5 commits into
Open
Conversation
Re-implements #33 from scratch on current main (the original PR had heavy merge conflicts from the wind/compass/GPS work). The trail routing logic (`osm-land.ts`) is identical to the original. When Land mode is active, each route leg now snaps to OpenStreetMap hiking/cycling trails (path, footway, track, bridleway, cycleway, pedestrian, steps, foot/bicycle=designated) instead of drawing a straight line. Pipeline: * `osm-land.ts` — queries Overpass for trail ways within a graduated bbox, builds a geojson-path-finder graph, snaps endpoints to the nearest vertex (≤5 km), and returns the routed polyline + length + hike/bike way counts. * `/api/route?land=1` — calls computeLandTrailRoute first, falls back to straight-line on failure. * `/api/multi-route?land=1` — each leg attempts trail routing; trailLegs count in the response. * RouteView shows "🥾 Trail route via OpenStreetMap: X km (Y hike · Z bike ways)". Straight-line fallback shows the trail failure reason. * WaypointsView shows "🥾 N trail" in the track summary. Constraints: MAX_SPAN_DEG=1.5 (~165 km), MAX_SNAP_KM=5, 24h Overpass cache. Trails are dense — tight bbox keeps payloads bounded. i18n: route.trailPrefix/trailWaysSuffix/trailLabel, waypoints.trailLegs in en/th/ro. 91/91 tests pass, 0 type errors, build succeeds. https://claude.ai/code/session_01B9DMrLPT7hYfdCTsJgFF9q
6 tasks
Open-Meteo's geocoding API only indexes cities and populated places — searching for "Lumpini Park", "Hyde Park London", or any trail/POI returned empty results. Now if Open-Meteo returns no results, the geocoder falls back to Nominatim (OpenStreetMap's geocoder), which knows parks, mountains, beaches, trails, buildings — everything tagged in OSM. The flow: Open-Meteo first (fast, good for cities) → Nominatim fallback (slower, but finds POIs). Both are free and unkeyed. https://claude.ai/code/session_01B9DMrLPT7hYfdCTsJgFF9q
The controls card (waypoint chips + Done button, route meta-line, search fields) was hidden in fullscreen via display:none. This broke waypoint editing — you couldn't see/tap chips or press Done. Now the controls card stays visible but compact in fullscreen: reduced padding, no rounded corners, horizontally scrollable if needed. The map fills the remaining space below. https://claude.ai/code/session_01B9DMrLPT7hYfdCTsJgFF9q
maxZoom: 11 forced the map to zoom out far even when all waypoints were within a few blocks. Now caps at 16 so nearby points stay zoomed in with just enough padding (60px) to see all markers. https://claude.ai/code/session_01B9DMrLPT7hYfdCTsJgFF9q
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Re-implements #33 from scratch on current main. The original PR had heavy merge conflicts from the wind/compass/GPS work that landed since. The trail routing logic (
osm-land.ts) is identical to the original — this is a clean application onto the current codebase.Closes #33.
What it does
When Land mode is active, each route leg now snaps to OpenStreetMap hiking/cycling trails instead of drawing a straight line. Supported way types:
highway=path | footway | track | bridleway | cycleway | pedestrian | stepsfoot=designatedorbicycle=designatedPipeline
src/lib/server/osm-land.tsgeojson-path-findergraph, snaps endpoints (≤5 km), returns routed polyline + length + hike/bike way counts/api/route?land=1computeLandTrailRoutefirst, falls back to straight-line/api/multi-route?land=1trailLegscount in responseRouteView🥾 Trail route via OpenStreetMap: X km (Y hike · Z bike ways)WaypointsView🥾 N trailin the track summaryConstraints
MAX_SPAN_DEG = 1.5(~165 km) — wider trips bail earlyMAX_SNAP_KM = 5— endpoints must be within 5 km of a trailcached()helperVerified
pnpm check— 0 errorspnpm test— 91/91 passpnpm build— succeeds/api/route?from=13.7308,100.5418&to=13.7253,100.5435&land=1(Lumpini Park, Bangkok) →kind: 'trail', 0.91 km, 3755 hike + 79 bike waysPreview
https://weather-voodoo-2vuhhzarh-xorio-s-projects.vercel.app
i18n
New keys
route.{trailPrefix, trailWaysSuffix, trailLabel},waypoints.trailLegsin en / th / ro.Test plan
🥾 Trail route via OpenStreetMapwith hike/bike counts🥾 N traillegshttps://claude.ai/code/session_01B9DMrLPT7hYfdCTsJgFF9q
Generated by Claude Code