Skip to content

feat(search): local POI lane (PR 3 of 5) - #5

Merged
taddyb merged 2 commits into
mainfrom
feat/richer-geocoding-pr3
May 20, 2026
Merged

feat(search): local POI lane (PR 3 of 5)#5
taddyb merged 2 commits into
mainfrom
feat/richer-geocoding-pr3

Conversation

@taddyb

@taddyb taddyb commented May 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Third PR in the rollout. Wires the 79k-POI binary shipped by PR 2 into the search bar as a synchronous-ish "local" lane that returns results before any network round-trip.

What lights up

  • Typing "Battery Park" with no bias now resolves to the actual park (local exact-name hit, score 100 + park category boost 8), not whatever Photon happened to rank first
  • Typing "Joe's Pizza" returns local Joe's first across the merged dropdown — local exact-name beats Photon's noisy ranking
  • Address queries (e.g. 140 W 25th St) still route to Census + Photon as in PR 1 — the local lane returns empty for non-POI queries and the dropdown falls back to the network lanes

How it works

`js/poi-index.js` loads `tiles/pois.bin` (or assembles from chunks) on the first keystroke, decodes the POI1 binary, and builds two in-memory indexes:

Index Shape Purpose
Postings `Map<token, Uint32Array>` Token search — query tokens intersected with prefix-expanded last token
ByCategory `Map<category, Uint32Array>` Future use by PR 5's discovery lane

`scoreLocal` ranks each candidate:

  • 100 if normalized name === query exactly
  • 80 if every query token is in the name
  • 60 if just the last token is a prefix of any name token
    • 15/8/5 for transit/park/attraction categories
  • − `log2(name_token_count)` length penalty

`searchMerge` adds the local lane and gains an `overrides` parameter (`{local, photon, census}`) so tests can inject stubs without touching globals.

Test plan

  • `node --test tests/unit/**/*.test.mjs` → 30/30 pass
  • Manually: "Battery Park" returns the park as the top dropdown item, no network needed
  • Manually: "Joe's Pizza" returns Manhattan / Brooklyn Joe's above Photon noise
  • Manually: "140 W 25th St" still resolves via Census (PR 1 path not regressed)
  • Manually: with browser DevTools, observe that the network panel shows zero requests when typing a landmark name (local lane fires first)

Subsequent PRs

  • PR 4: WASM `reachable_nodes` method
  • PR 5: search-driven category discovery + map pins

🤖 Generated with Claude Code

@taddyb
taddyb merged commit d7a919b into main May 20, 2026
2 checks passed
@taddyb
taddyb deleted the feat/richer-geocoding-pr3 branch May 20, 2026 23:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant