我正在使用导入的 GeoJSON 数据创建地图。我正在尝试创建一个“查找我”按钮,该按钮将缩放到用户的位置并获取与封闭区域(由 GeoJSON 层定义)关联的属性。当用户单击地图时,我能够获取该属性,但我不知道如何在使用 map.locate() 函数时获取该属性。
我尝试使用 onEachRegion 将 locationfound 侦听器添加到 GeoJSON 组件,但它似乎没有触发。 '定位' 属性是按钮设置的状态,用于触发 map.locate() 函数。
//...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} />
)
}
我最终使用 Turf.js 来确定哪个区域包含用户位置。
export const getRegionContainingPoint = (point: number[]) => {
let region = '';
// Loop through geojson object and check if point is inside. Return region number
turf.featureEach(BCRData as FeatureCollection, function (currentFeature, featureIndex) {
let containsPt = false;
// convert geometry collection to feature collection
const flattenedCollection = turf.flatten(currentFeature);
// loop through resulting collection
turf.featureEach(flattenedCollection, function (flattenedFeature, flatIndex) {
const ptInGeometry = turf.booleanPointInPolygon(point, flattenedFeature);
if (ptInGeometry) containsPt = true;
})
// get property value if point is found in feature
if (containsPt) {
const props = currentFeature.properties;
if (props) {
region = String(props['BCR']);
}
}
})
return region;
}