48 Commits

Author SHA1 Message Date
38160e9d3d Trigger CI after runner re-registration
All checks were successful
CI / test-and-build (push) Successful in 40s
2026-08-30 20:59:29 +00:00
966e4312cc Trigger CI after runner URL fix
Some checks failed
CI / test-and-build (push) Failing after 37s
2026-08-30 20:51:59 +00:00
9125341a8c Drop npm cache in CI (Docker-mode runner cache server causes failures)
Some checks failed
CI / test-and-build (push) Failing after 42s
2026-08-30 20:43:13 +00:00
ab991e212c Switch CI runner to Ubuntu (containerized act_runner)
Some checks failed
CI / test-and-build (push) Failing after 43s
2026-08-30 20:33:40 +00:00
1d4ae6c76d Humanize turn-by-turn distances; drop arrival step distance
All checks were successful
CI / test-and-build (push) Successful in 1m2s
2026-08-16 19:43:31 +00:00
fb6ad3eb0c Fix: resolve data paths against app base for subdirectory deploys
All checks were successful
CI / test-and-build (push) Successful in 48s
The static app is served at /maps/ but the data manifest and graph/poi/layer
fetches used absolute /data/... paths, which resolved to the server root and
failed. Add src/lib/base.ts exporting upath() that prefixes a path with the
runtime-detected base (mirroring SvelteKit's 'base: new URL(".", location)'),
and apply it to the manifest, layer, graph and POI fetches. Works at both
root and any sub-path.
2026-08-16 14:39:58 +00:00
8941d837b5 Directions: merge consecutive turn-by-turn steps on the same street
All checks were successful
CI / test-and-build (push) Successful in 58s
buildTurnInstructions grouped steps purely by heading change, so a street
that bends (same name, >30° heading shift) produced redundant
'Continue/Turn onto Pine St' entries. Now consecutive legs sharing the same
street name are collapsed into a single step with summed distance.

- routing.ts: track each leg's street name and absorb subsequent same-street
  steps' distance into the first; the arrival step uses the final bearing
- scripts/test.mjs: assert a bent single-named road yields 1 step, and that
  two distinct streets are not merged
2026-08-12 18:05:41 +00:00
f054164e84 fix(ui): offset context dialog for 16x16 arrow (8px left, 16px down) so it points at the click
All checks were successful
CI / test-and-build (push) Successful in 44s
2026-08-10 21:46:07 +00:00
80e002ff3d fix(ui): position context dialog in viewport coords (was offset from the click by the header)
All checks were successful
CI / test-and-build (push) Successful in 46s
2026-08-10 21:35:48 +00:00
c2051a665b feat(ui): add explicit X close buttons to context dialog, Preferences dialog, and Directions panel
All checks were successful
CI / test-and-build (push) Successful in 45s
2026-08-10 21:21:12 +00:00
fbf939d236 feat(routing): street-aware turn-by-turn (road names) + one-way/roundabout support; widen graph to named local streets
All checks were successful
CI / test-and-build (push) Successful in 47s
- osm-dump.mjs: capture way name/ref as edgeNames; honor oneway & roundabout as directed edges; graphHighways widened to include named local roads
- routing.ts: buildTurnInstructions emits 'Head north on Pine St' / 'Turn right onto 21st St'; merges short legs to avoid phantom turns; nameResolverFor() maps node path to street names
- Rebuilt tulsa-dump-graph.json: 225,956 nodes / 227,468 edges (was 55k); ~27MB (was 4.7MB)
- tests, README updated
2026-08-10 21:11:20 +00:00
397979ac78 style(directions): let the dialog size to its content (no fixed width)
All checks were successful
CI / test-and-build (push) Successful in 42s
2026-08-10 20:53:48 +00:00
2ce71b8955 fix(directions): drawResult no longer clears the result state, so turn-by-turn/distance remain visible after calculating
All checks were successful
CI / test-and-build (push) Successful in 41s
2026-08-10 20:48:41 +00:00
000b892202 fix(directions): selecting a saved point as destination no longer re-sets the origin (remove leftover onPickSavedPoint callback)
All checks were successful
CI / test-and-build (push) Successful in 42s
2026-08-10 20:37:09 +00:00
c3e3617794 fix(routes): store routing graph/pois as plain vars (not $state proxies) so they structured-clone into the Web Worker
All checks were successful
CI / test-and-build (push) Successful in 42s
2026-08-10 20:33:36 +00:00
4de3e31708 feat(directions): include Saved Points in destination search results (filtered by query)
All checks were successful
CI / test-and-build (push) Successful in 43s
2026-08-10 20:29:10 +00:00
a7955c0636 fix(ui): consolidate POI info into single context dialog (remove duplicate native Leaflet popup)
All checks were successful
CI / test-and-build (push) Successful in 43s
2026-08-10 20:11:52 +00:00
b0147940af fix(ui): restore map height after removing the top bar (was collapsing to 0 via grid auto row)
All checks were successful
CI / test-and-build (push) Successful in 42s
2026-08-10 16:14:02 +00:00
6abcf0483c docs: add CONTRIBUTING.md with setup, automated checks, and local QA checklist
All checks were successful
CI / test-and-build (push) Successful in 43s
2026-08-10 16:10:21 +00:00
b442e1ef44 docs: document context-dialog interaction; correct Saved Points flow
All checks were successful
CI / test-and-build (push) Successful in 42s
2026-08-10 15:54:46 +00:00
80d049eebf feat(ui): context dialog on map click (no auto-save); save-point form; 'Directions from/to here'; remove Directions button + Data sources bar 2026-08-10 15:52:34 +00:00
2e0269b865 test+docs: add routing & savedPoints regressions; document new Directions flow, Saved Points, worker
All checks were successful
CI / test-and-build (push) Successful in 41s
2026-08-10 15:31:39 +00:00
9ef58e62c8 feat(directions): on-demand road-data layer loading with loading-state CTA 2026-08-10 15:29:38 +00:00
5c29320e6b feat(prefs): export/import Saved Points (merge + dedupe by id) in Preferences dialog 2026-08-10 15:28:35 +00:00
fe072c8d85 feat(directions): browser-local Saved Points layer (click empty space), toggleable, selectable as origin/destination 2026-08-10 15:26:30 +00:00
591fafc5de feat(directions): run route computation in a Web Worker with live progress (off UI thread) 2026-08-10 15:22:01 +00:00
62ddbf160c feat(directions): rework panel to destination-picker + collapsed route options; graph loaded on demand with sync fallback 2026-08-10 15:20:17 +00:00
5e85c15798 feat(directions): origin selection via search or map click; Directions button gated on origin 2026-08-10 15:16:38 +00:00
4e0d82f416 refactor(directions): unit system now controlled solely via Preferences dialog (pull from prefs store)
All checks were successful
CI / test-and-build (push) Successful in 41s
2026-08-10 14:37:21 +00:00
f46d604546 feat(prefs): drop redundant unit-override; distances auto m/ft under a km/mi, else km/mi
All checks were successful
CI / test-and-build (push) Successful in 41s
2026-08-10 14:22:31 +00:00
149d7942dd docs: document preferences dialog, default-unchecked layers, robust routing + turn-by-turn
All checks were successful
CI / test-and-build (push) Successful in 42s
2026-08-10 13:12:55 +00:00
d786ee3151 feat: preferences dialog, default-unchecked layers, robust routing + turn-by-turn
Some checks failed
CI / test-and-build (push) Has been cancelled
2026-08-10 13:12:20 +00:00
71db0da5aa docs: correct repo URL to exlim/navigator (post-org-move)
All checks were successful
CI / test-and-build (push) Successful in 39s
2026-08-09 22:16:42 +00:00
81a3da388e Fix layer toggles: malformed GeoJSON geometry + fragile layer loading
All checks were successful
CI / test-and-build (push) Successful in 47s
Root cause: osm-data.mjs emitted ways with 'out center' (no geometry) as a
flat [lon,lat] labeled 'LineString'. Leaflet reads those as two invalid
points and threw 'Invalid LatLng', which aborted the entire layer load loop
in onMount -- so no layers rendered and the checkboxes all showed unchecked.
Toggling then appeared to do nothing.

Fixes:
- osm-data.mjs: coordsFor/geometryFor now emit a proper Point for any flat
  [lon,lat] (from nodes / 'out center' ways) instead of a malformed LineString
- MapView.svelte: isolate each layer's load + each feature's searchable build
  in try/catch so one bad feature/layer can't break all layers; skip invalid
  bounds in fitBounds
- osm-data.mjs: preserve manifest entries it doesn't generate (e.g. dump
  layers from osm-dump.mjs) so data/osm-dump scripts don't clobber each other
- scripts/test.mjs: add geometry-integrity checks (no malformed coords)

Verified in a real browser: all 6 layers render, each toggles off/on
independently (33361->0 overlays), and the Directions panel loads.
2026-08-09 21:35:47 +00:00
edd6ba9ae2 Fix viewport overflow so the Directions panel stays on-screen
All checks were successful
CI / test-and-build (push) Successful in 41s
The page had two stacked 100vh containers (.app and .wrap) which made the
page taller than the viewport and forced scrolling. Fixes:
- .wrap now fills its grid cell (height:100%, min-height:0, overflow:hidden)
  instead of a second 100vh
- .app uses 100dvh + overflow:hidden; html/body/#svelte get height:100%,
  body overflow:hidden
- Directions panel is now viewport-anchored (top:64px/bottom:14px) with a
  max-height and internal overflow-y so it can't exceed the screen
- DirectionsPanel itself scrolls internally when content is tall
2026-08-09 21:14:01 +00:00
54345a21bd chore: confirm CI runs from exlim org home
All checks were successful
CI / test-and-build (push) Successful in 42s
2026-08-09 20:38:56 +00:00
8c2e7eb6ab Directions: add Imperial unit system (feet/miles) alongside metric
All checks were successful
CI / test-and-build (push) Successful in 39s
- Add a System selector (Metric/Imperial) to the Directions panel; Units
  dropdown adapts (m/km vs ft/mi) with a smart Auto for each system
- Auto: short routes show the small unit (m or ft), long routes the large
  one (km or mi); shows the alternate unit as a sub-line
- README: document the unit system + units options
2026-08-09 16:01:47 +00:00
4b00704735 Directions: smart distance units (m/km auto + toggle) and travel-time estimate
All checks were successful
CI / test-and-build (push) Successful in 39s
- DirectionsPanel: unit selector (Auto = m under 1km else km, or force m/km)
  and a Drive/Walk mode that estimates travel time from distance + avg speed
- Distance shows meters for short routes and km for longer ones; est. time in
  seconds/minutes/hours as appropriate
- README: document the new units and travel-time options
2026-08-09 15:31:59 +00:00
db292409f1 Add OSM data-dump ingestion + in-browser routing with POI avoidance
All checks were successful
CI / test-and-build (push) Successful in 1m3s
- scripts/osm-dump.mjs: download & stream-parse regional .osm.pbf extracts
  (Geofabrik/BBBike etc). Clips to bbox, extracts POI features (poiTags),
  and builds a routable road graph (coords + weighted adj) from road ways.
  Caches the downloaded .pbf under scripts/.cache/ (git-ignored). Default:
  Geofabrik Oklahoma extract -> tulsa-dump layer (12.8k POIs, 55k-node graph).
- src/lib/routing.ts: client-side A* routing over the graph. Snaps A/B to
  nearest nodes, supports avoid-rules (category + radius, block or penalty)
  built from nearby POIs; returns waypoints + distance.
- src/lib/components/DirectionsPanel.svelte: Directions UI — pick A/B by
  clicking the map, choose POI categories to avoid, compute & draw the route.
- MapView: adds a Directions toggle when a dump layer with a graph is present.
- package.json: add 'build:dump'; build now runs data + dump + static.
- scripts/test.mjs: validate dump manifest entries + routing graph structure.
- README: document dump ingestion and the routing/avoid feature.
2026-08-09 15:19:35 +00:00
0753527d69 Add OSM road data + directional bearing arrows on POI points
All checks were successful
CI / test-and-build (push) Successful in 35s
- osm-data.mjs: add 'roads' Overpass query to tulsa area — major road
  classes (motorway/trunk/primary/secondary/tertiary) as LineString geometry
- MapView.svelte: render POIs that have a bearing as a rotated arrow
  divIcon marker pointing in the compass heading; other POIs stay as
  circleMarkers. Adds .dir-arrow CSS.
- scripts/test.mjs: adapt street-name search assertions (roads now match
  address queries legitimately) and add an expectAll helper
- static/data: tulsa.geojson now includes ~20k road features (11MB)
2026-08-08 19:10:15 +00:00
220e6c9e48 ci: route tests through tsx so CI can run search regressions
All checks were successful
CI / test-and-build (push) Successful in 34s
scripts/test.mjs imports src/lib/search.ts (TypeScript), which plain node
cannot execute. Add tsx as a devDependency and point npm test at it.
2026-08-08 18:39:41 +00:00
c010e8f931 ci: trigger re-run to debug runner
Some checks failed
CI / test-and-build (push) Failing after 18s
2026-08-08 18:38:27 +00:00
f43530bed0 Add Gitea Actions CI: run tests on every push
Some checks failed
CI / test-and-build (push) Failing after 1m18s
- .gitea/workflows/ci.yml: on push/PR, runs npm ci, svelte-check, offline
  regression tests, and a static (no-Overpass) build, then verifies output
- scripts/test.mjs: offline test suite — validates manifest + GeoJSON
  structure and asserts fuzzy-search regressions against committed data
- package.json: add 'test' and 'build:static' scripts
- osm-data.mjs: tag OSM layers layerType='mixed' in the manifest
2026-08-08 18:32:48 +00:00
4e3fef6559 Add path/route layer type + online geocoding + Rogers County example data
- custom-layers.mjs: new 'path' layerType (LineStrings like GPX tracks/trails)
  with a 'line' feature format, an example trails layer, and a seeded
  Rogers County POI layer with real geocoded coordinates (museums, courthouse,
  university, towns)
- osm-data.mjs: converts path features to GeoJSON LineStrings and tags
  layerType='path' in the manifest; fixes kind detection for all three types
- MapView.svelte: styles path layers as dashed polylines, computes bounds for
  LineStrings, supports 'path' in search results, and adds a Nominatim
  'Places (online)' geocoding fallback section to the search box (debounced,
  fit-to-bounds on select)
- geocode.ts: dependency-free Nominatim client
- README: documents path layers and online location search
2026-08-08 18:26:48 +00:00
63f1b75456 Add fuzzy search + richer POI data (address, bearing, fov)
- src/lib/search.ts: dependency-free fuzzy search engine that matches POIs
  and zones by name/address with text normalization (st->street, compass
  words), substring + Levenshtein fuzzy matching, and field-aware ranking
- MapView.svelte: builds a searchable index from loaded layers, adds a
  search box that shows ranked results, pans/zooms + opens popup on select,
  and renders dedicated popup rows for address, Facing (compass), and
  Field of view
- custom-layers.mjs: documents optional address / bearing / fov POI fields
  with examples; osm-data.mjs normalizes bearing (compass point or degrees)
  into degrees and carries the new properties through to GeoJSON
- README: documents POI data fields and the search feature
2026-08-08 17:01:10 +00:00
347e9b2a0a Add custom zones & POI layers with user-editable config and example data
- scripts/custom-layers.mjs: hand-authored, self-documenting config for
  custom zones (polygons) and points of interest, shipped with example
  Tulsa POIs and district zones plus a copy-paste template
- osm-data.mjs: merges custom layers into static/data/custom/<id>.geojson
  and includes them in the _index.json manifest with category, layerType,
  and color metadata
- MapView.svelte: renders each manifest entry as an independent toggleable
  Leaflet layer with per-layer styling and an on-map legend panel
- +page.svelte: loads all data sources (OSM + custom) from the manifest
2026-08-08 16:09:39 +00:00
3413b7053f Initial Navigator app: SvelteKit static build + OSM Overpass data pipeline
- SvelteKit project with @sveltejs/adapter-static (runs fully static)
- scripts/osm-data.mjs: pulls OSM data from Overpass API and converts to
  static GeoJSON under static/data/ with per-area manifest
- Leaflet map frontend that loads the static data and renders features
  with popups and area selection dropdown
- npm run build fetches data then produces a self-contained static site
2026-08-08 15:29:51 +00:00
492916e0c5 Initial commit 2026-08-08 10:13:40 -05:00