I am creating a map with imported GeoJSON data. I am trying to create a Find Me button that will zoom to the user's location and get a property associated with the enclosing region (as defined by the GeoJSON layer). I am able to get the property when the user clicks the map, but I can't figure out how to get the property when the map.locate() function is used.
I've tried adding a locationfound listener to the GeoJSON component using onEachRegion but it doesn't seem to fire. The 'locating' prop is a state set by the button to trigger the map.locate() function.
//...Imports
export const MapView: React.FC<{
setRegion: any,
locating: boolean,
setLocating: any
}> = (props) => {
const geoStyle = {
fillOpacity: 0,
weight: 0.5
}
const onEachRegion = (region: Feature, layer: L.Layer) => {
const code = region.properties?.BCR;
layer.on({
click: (event: L.LeafletEvent) => {
props.setRegion(code)
}
})
layer.on({
locationfound: (event: L.LeafletEvent) => {
props.setRegion(code)
}
})
}
return(
<div>
<MapContainer center={[45, -95]} zoom={3} attributionControl={false} ref={setMapRef}>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>
contributors'
url="https://tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<AttributionControl prefix={'Leaflet'}/>
<GeoJSON
data={BCRData as GeoJsonObject}
style={geoStyle}
onEachFeature={onEachRegion}
/>
<LocationMarker locating={props.locating} setLocating={props.setLocating} />
</MapContainer>
</div>
)
}
export const LocationMarker: React.FC<{
locating: boolean,
setLocating: any,
}> = (props) => {
const [position, setPosition] = useState<LatLngExpression>([0,0]);
const didMount = useRef(false);
const icon = L.icon( {
iconUrl: '/images/marker-icon.png',
iconAnchor: [12, 41],
});
const map = useMapEvents({
click(e) {
setPosition(e.latlng)
},
locationfound(e) {
setPosition(e.latlng)
map.flyTo(e.latlng, 8)
}
})
useEffect(() => {
if (props.locating) {
map.locate()
props.setLocating(false)
}
}, [props.locating]);
return(
<Marker position={position} icon={icon} />
)
}