mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
feat(search): finish the keyless fallback at every geocode call site
The keyless fallback landed on the LOCATION search box only. Two other places forward-geocode a name and neither had it: the annotation resolver returned null, so an annotation silently failed to anchor, and the Radio layer THREW, which surfaced as a failed voice turn rather than as a station it could not place. src/keylessGeocoder.test.mjs now COUNTS the call sites instead of checking them file by file, so a second seam added to a file that already has a fallback fails the suite too. The annotation path carries the feature's own name out of Photon. Footprint scoring matches OSM on that canonical name rather than on the user's words, so incidental locality tokens cannot win: "the monument near the Texas Capitol, Austin" scored on the raw utterance picks a downtown building that shares only "Texas", "Capitol" and "Austin". Photon's country is deliberately NOT re-exported. It comes back in the feature's own language — "Việt Nam", "日本", "Россия" — and normalizeRadioCountryInput fails CLOSED on a name it cannot map, so forwarding it would filter the station list to nothing for exactly the places the lookup had just resolved. The composed label still names the country. A keyless lookup must not apply a filter the keyed one never applies. A not-found is now remembered only when every source consulted returned a verdict. Photon not replying is a network blip, not "no such place": memoizing it kept the query answering not-found for the rest of the session on a network that had since recovered — the same conflation the Overpass disk cache had to be repaired for. geocodeMissIsDefinitive states the rule once and both entry points use it, and the adapter's own memo follows it as well. Reverse geocoding stays out of scope: the street-label reader consumes Google's ranked address_components, and Photon's /reverse cannot reproduce that shape.
This commit is contained in:
1 parent
acac1e4842
commit
e21c174f76
8 files changed
+681
-43
No files matched your search
@@ -2183,7 +2183,11 @@ silently demoting every later lookup for the session.
|
||||
|
||||
### Keyless place search (August 2026)
|
||||
|
||||
- `src/keylessGeocoder.js` is a Photon (komoot/OpenStreetMap) adapter used by `searchAndFlyTo` when the Google geocode produces no result: no key configured, or a key whose Geocoding API is not enabled — Google answers HTTP 200 with `REQUEST_DENIED`, so the empty result is the detector, not an error. Google stays the primary path and is byte-unchanged when it answers, and the Places near-view recovery is only attempted when a key exists, since Places is a Google service.
|
||||
- `src/keylessGeocoder.js` is a Photon (komoot/OpenStreetMap) adapter used when the Google geocode produces no result: no key configured, or a key whose Geocoding API is not enabled — Google answers HTTP 200 with `REQUEST_DENIED`, so the empty result is the detector, not an error. Google stays the primary path and is byte-unchanged when it answers, and the Places near-view recovery is only attempted when a key exists, since Places is a Google service.
|
||||
- The fallback covers **all three** client call sites that forward-geocode a name, not just the search box: `searchAndFlyTo` (`src/locations.js`), the annotation resolver's `geocodePlace` (`src/annotations/annotationResolver.js`) and the Radio layer's "near \<place\>" lookup (`resolveRadioLocation`, `src/voice/gevActions.js`). The last of those used to THROW without a key, which surfaced as a failed voice turn rather than as a station it could not place. `src/keylessGeocoder.test.mjs` pins the inventory by counting the call sites, so a second seam added to a file that already has a fallback fails the suite too. Reverse geocoding (`?latlng=`) is deliberately NOT covered: the street-label reader consumes Google's ranked `address_components`, and Photon's `/reverse` cannot reproduce that shape.
|
||||
- For the annotation resolver the adapter also carries the feature's own `name`. OSM footprint scoring matches on that canonical name rather than on the user's words, so incidental locality tokens cannot win — "the monument near the Texas Capitol, Austin" scored on the raw utterance picks a downtown building that merely shares "Texas", "Capitol" and "Austin" (the same failure as field test 7).
|
||||
- Photon's `country` is NOT re-exported as a field. It comes back in the feature's own language ("Việt Nam", "日本", "Россия"), and `normalizeRadioCountryInput` fails CLOSED on a name it cannot map — forwarding it would filter the station list to nothing for exactly the places the lookup just resolved. The composed label still names the country.
|
||||
- A not-found is remembered only when every source consulted returned a verdict (`geocodeMissIsDefinitive`). Photon not replying is a network blip, not "no such place": caching it would keep an annotation unplaceable for the rest of the session on a network that has since recovered — the same conflation the Overpass disk cache had to be repaired for. The adapter's own memo follows the same rule, so an unanswered lookup is retried rather than replayed.
|
||||
- The adapter normalizes into the shape the Google path already produces — `lat`/`lng`, label, Google-style `types`, `{southwest,northeast}` bounds — so `geocodeNavigationMode`, `regionFramingPlan` and the region-swath cap keep running unchanged. Two translations are load-bearing and are pinned by tests: Photon's `extent` is `[west, north, east, south]`, and a specific OSM `key=value` rule beats the coarse `type` (Photon reports a lake as `water=lake` with `type: 'other'`, which framed at building range put the camera 26 m over the water; it reports a town square as `type: 'locality'`, which framed a plaza as a city).
|
||||
- The shared `viewportBias()` string is sent as Photon's `lat`/`lon` PROXIMITY bias, never as `bbox`: Google's `bounds` prefers, Photon's `bbox` filters, and the literal translation makes every off-screen search return nothing. One result per query, memoized by query+bias (misses included) to respect komoot's fair use.
|
||||
|
||||
|
||||
Reference in new issue
Block a user