developmentseed / developmentseed/eo-predictor
Add place search (Nominatim) on the map
- Dominant language
- TypeScript
- Stars
- 22
- Forks
- 2
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 2
Description
## Summary
Add a search control on the map that lets users type a place name (city, address, country) and fly the map to it, using [Nominatim](https://nominatim.org/) (OpenStreetMap's geocoder) as the lookup source.
## Why
There's currently no way to navigate the map to a specific place by name — users have to manually pan/zoom the globe. A lightweight search-to-navigate control makes it much faster to get to an area of interest before optionally loading a precise AOI (see #90).
## Proposed approach
- Add the control inside the map component (`App.tsx`), using `map.addControl()` — same pattern already used for `NavigationControl` and `GeolocateControl` (`App.tsx:274-278`).
- Recommended implementation: [`@maplibre/maplibre-gl-geocoder`](https://github.com/maplibre/maplibre-gl-geocoder), a standard MapLibre control, configured with a custom `geocoderApi` that queries Nominatim's `/search` endpoint instead of its default provider. This avoids building a results-dropdown UI from scratch.
- Alternative: build a custom control with shadcn `Input` + `Popover` (neither is installed yet — would need `pnpm dlx shadcn@latest add input popover`) for tighter visual match with the rest of the UI. More work, more control over styling.
- On selecting a result, use Nominatim's returned `boundingbox` with `map.fitBounds()` — the same fit-bounds pattern already used for AOI uploads (`aoiUtils.ts`, `AoiUpload.tsx`), with a `maxZoom` cap (~8) so small results (e.g. a single address) don't over-zoom. Since Nominatim's bbox is naturally tighter for cities and wider for countries, this gives "lower zoom for a country" behavior without a hardcoded zoom-level table.
- No backend changes — pure client-side fetch to Nominatim's public API. Need to check and respect [Nominatim's usage policy](https://operations.osmfoundation.org/policies/nominatim/) (rate limits, required `User-Agent`/referer, no heavy/automated use) — may want to self-host or use a commercial Nominatim provider if usage grows.
## Open questions
- Do we need debounce/rate-limiting on keystroke search to stay within Nominatim's usage policy?
- Should results be scoped/biased (e.g. bounding box bias) or global?
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in App.tsx at the map control setup around lines 274-278, then review the fit-bounds pattern in aoiUtils.ts and AoiUpload.tsx. Choose and integrate the search control with Nominatim, fit selected results using their bounding boxes with a max-zoom cap, and verify the implementation follows Nominatim's usage policy.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 62/100