fix(map): resolve clicks to rendered label features

Click handler now queries rendered features at click point and uses
the highest-priority labeled feature (POI > locality > region) as
the place identifier. Previously, clicks went straight to coord-based
reverse-geocode, causing 'Twin Falls' label clicks to resolve to
whatever feature was nearest (e.g., a radio tower).

Falls back to reverse-geocode when no labeled feature exists at the
click point. Two-click selection model and hover affordance unchanged.
This commit is contained in:
Matt 2026-04-26 07:49:08 +00:00
commit 4fcc3d1af4

View file

@ -863,6 +863,13 @@ const MapView = forwardRef(function MapView(_, ref) {
const { lng, lat } = e.lngLat const { lng, lat } = e.lngLat
const MARKER_RADIUS_PX = 14 // half of 28px preview marker const MARKER_RADIUS_PX = 14 // half of 28px preview marker
// Query rendered features at click point (label/POI priority)
const labelLayers = ['pois', 'places_subplace', 'places_locality', 'places_region', 'places_country']
const features = map.queryRenderedFeatures(e.point, { layers: labelLayers })
// Find first feature with a name (respects layer order = priority)
const labelFeature = features.find(f => f.properties?.name)
// Set click marker // Set click marker
store.setClickMarker({ store.setClickMarker({
lat, lat,
@ -870,30 +877,51 @@ const MapView = forwardRef(function MapView(_, ref) {
circleRadiusPx: MARKER_RADIUS_PX, circleRadiusPx: MARKER_RADIUS_PX,
}) })
// Immediately set a "Dropped pin" placeholder if (labelFeature) {
store.setSelectedPlace({ // Clicked a labeled feature use its properties
lat, const props = labelFeature.properties
lon: lng, store.setSelectedPlace({
name: 'Dropped pin', lat,
address: null, lon: lng,
type: null, name: props.name || 'Unknown',
source: 'map_click', address: null,
matchCode: null, type: props.kind_detail || props.kind || null,
raw: {}, source: 'basemap_label',
}) matchCode: null,
raw: {
wikidata: props.wikidata || null,
population: props.population || null,
kind: props.kind || null,
kind_detail: props.kind_detail || null,
elevation: props.elevation || null,
},
})
} else {
// No labeled feature fall back to reverse geocode
store.setSelectedPlace({
lat,
lon: lng,
name: 'Dropped pin',
address: null,
type: null,
source: 'map_click',
matchCode: null,
raw: {},
})
// Reverse geocode in background // Reverse geocode in background
fetchReverse(lat, lng).then((place) => { fetchReverse(lat, lng).then((place) => {
if (!place) return if (!place) return
const current = useStore.getState().selectedPlace const current = useStore.getState().selectedPlace
if (current && Math.abs(current.lat - lat) < 0.00001 && Math.abs(current.lon - lng) < 0.00001) { if (current && Math.abs(current.lat - lat) < 0.00001 && Math.abs(current.lon - lng) < 0.00001) {
useStore.getState().setSelectedPlace({ useStore.getState().setSelectedPlace({
...place, ...place,
lat, lat,
lon: lng, lon: lng,
}) })
} }
}) })
}
} }
}) })
map.on('load', () => { map.on('load', () => {