fix(place): add reverse geocode fallback for place details

When a place is selected without osm_type/osm_id (e.g., clicking
on a basemap label), trigger a reverse geocode to obtain the OSM
identifiers. This enables fetching place details including boundary,
wiki_summary, and other enriched data.

The existing placeDetails useEffect will then fire once the
osm_type/osm_id are available in the selectedPlace.raw object.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ubuntu 2026-04-29 18:32:41 +00:00
commit 497a671504
2 changed files with 53 additions and 2 deletions

View file

@ -6,7 +6,7 @@ import {
import OpeningHours from "opening_hours"
import toast from "react-hot-toast"
import { useStore } from "../store"
import { fetchElevation, fetchPlaceDetails, fetchPlaceByWikidata, fetchDriveTime, fetchNearbyContacts, fetchLandclass } from "../api"
import { fetchElevation, fetchPlaceDetails, fetchPlaceByWikidata, fetchDriveTime, fetchNearbyContacts, fetchLandclass, fetchReverse } from "../api"
import { hasFeature } from "../config"
import { buildAddress } from "../utils/place"
@ -328,6 +328,32 @@ export function PlaceCard({ place, variant = "preview", expanded = true, onToggl
return () => { cancelled = true }
}, [placeLat, placeLon])
// Reverse geocode to get OSM type/id if not present (e.g., basemap label clicks)
useEffect(() => {
if (!hasFeature('has_nominatim_details')) return
if (osmType && osmId) return
if (placeLat == null || placeLon == null) return
// Skip for dropped pins - they get reverse geocoded by MapView
if (place?.source === 'map_click') return
const controller = new AbortController()
fetchReverse(placeLat, placeLon).then((result) => {
if (controller.signal.aborted) return
if (result?.raw?.osm_type && result?.raw?.osm_id) {
const current = useStore.getState().selectedPlace
if (current && current.lat === placeLat && current.lon === placeLon) {
// Merge OSM data into raw, preserving existing data
useStore.getState().setSelectedPlace({
...current,
raw: { ...current.raw, osm_type: result.raw.osm_type, osm_id: result.raw.osm_id }
})
}
}
})
return () => controller.abort()
}, [placeLat, placeLon, osmType, osmId, place?.source])
useEffect(() => {
if (!hasFeature("has_nominatim_details") || !osmType || !osmId) { setPlaceDetails(null); return }
const controller = new AbortController()