[英]How to change map zoom dynamically when clicking on a marker in react leaflet v.3.x?
i tried to find many things regards this but i can't make it work.我试图找到很多关于这个的东西,但我无法让它发挥作用。 what i want is when click on marker map got center on that location and got full zoom.我想要的是当单击标记 map 时,它会在该位置居中并得到完全缩放。 for example i have total 23 markers on all around Unites states and initial map zoom is 4. what i want is if user click on marker in map then map center change to that marker lat, lng and got zoom in for suppose to 14 from 4. markeres are render already i don't want markers renders in function MyMapComponent.例如,我在 Unites 各州周围共有 23 个标记,初始 map 缩放为 4。我想要的是,如果用户单击 map 中的标记,然后 map 中心更改为该标记的纬度、经度并放大假设从 4 到 14 . markeres 已经渲染 我不想在 function MyMapComponent 中渲染标记。 it come from API data.它来自 API 数据。 there is no clue how to do.不知道该怎么做。 i tried useMapEvents but it works on map click not marker click and if i use markers eventHandlers click i can't call map useMapEvents to set lat, lng and change zoom.我尝试了 useMapEvents但它适用于 map 单击而不是标记单击,如果我使用标记eventHandlers单击我不能调用 map useMapEvents来设置纬度、经度和更改缩放。
Here is my code:这是我的代码:
function MyMapComponent() {
const map = useMapEvents({
click: () => {
let data = {lat: 46.8835319, lng: -114.0348327}
map.flyTo(data, 18)
}
})
return null}
above code is i need to change map center and zoom上面的代码是我需要更改 map 中心和缩放
<div className="project-view-section">
<MapContainer bounds={outerBounds} center={[37.2755, -104.6571]} zoom={mapOptions.zoom} scrollWheelZoom={false}>
<MyMapComponent />
<LayersControl position="topright">
<LayersControl.BaseLayer checked name="Mapbox Satellite">
<TileLayer
url={'https://api.mapbox.com/styles/v1/mapbox/satellite-v9/tiles/256/{z}/{x}/{y}@2x?access_token='+MAPBOX_TOKEN}
attribution="Map data © <a href="https://www.mapbox.com/">Mapbox</a>"
/>
</LayersControl.BaseLayer>
<LayersControl.BaseLayer name="Mapbox Streets">
<TileLayer
url={'https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/256/{z}/{x}/{y}@2x?access_token='+MAPBOX_TOKEN}
attribution="Map data © <a href="https://www.mapbox.com/">Mapbox</a>"
/>
</LayersControl.BaseLayer>
</LayersControl>
<MarkerClusterGroup>
{
state.markersData.map((element, index) =>
<Marker
key={index}
marker_index={index}
position={element}
icon={icon}
eventHandlers={{click: () => {test()},}}>
</Marker>
)
}
</MarkerClusterGroup>
</MapContainer>
</div>
is there any way to accomplish this?有什么办法可以做到这一点?
You should use eventHandlers
prop on Marker and listen to click event.您应该在 Marker 上使用eventHandlers
道具并收听点击事件。 Then use native leaflet's code: map.setView(coords, zoom)
然后使用原生传单的代码: map.setView(coords, zoom)
function Markers({ data }) {
const map = useMap();
return (
data.length > 0 &&
data.map((marker, index) => {
return (
<Marker
eventHandlers={{
click: () => {
map.setView(
[
marker.geometry.coordinates[1],
marker.geometry.coordinates[0]
],
14
);
}
}}
key={index}
position={{
lat: marker.geometry.coordinates[1], // your api structure
lng: marker.geometry.coordinates[0] // your api structure
}}
icon={icon}
>
<Popup>
<span>{marker.properties.label}</span>
</Popup>
</Marker>
);
})
);
}
Use Markers comp as a MapContainer child then.然后将 Markers comp 用作 MapContainer 子项。
import React, { useState, useRef, useEffect } from 'react';
import {
MapContainer,
Marker,
Popup,
TileLayer,
useMap
} from 'react-leaflet';
import L from 'leaflet';
import { v4 as uuidv4 } from 'uuid';
import 'leaflet/dist/leaflet.css';
import { useTranslation } from 'react-i18next';
const iconMarker = new L.Icon({
iconUrl: require('../assets/images/loc.png'),
iconAnchor: [25, 50],
popupAnchor: [0, -30],
iconSize: new L.Point(50, 50),
});
function Markers({ data, isActive }) {
const map = useMap();
const [refReady, setRefReady] = useState(false);
let popupRef = useRef();
useEffect(() => {
if (refReady && isActive) {
popupRef.addTo(map);
}
}, [isActive, refReady, map]);
return (
data.length > 0 &&
data.map((marker, index) => {
return (
<Marker
key={index}
eventHandlers={{
click: () => {
map.setView([marker.latitude, marker.longitude], 16);
},
}}
position={{
lat: marker.latitude,
lng: marker.longitude,
}}
icon={iconMarker}
>
<Popup
ref={(r) => {
popupRef = r;
setRefReady(true);
}}
>
<span>{marker.name}</span>
</Popup>
</Marker>
);
})
);
}
const Map = ({ devices }) => {
const { t } = useTranslation();
const locationLati = [devices?.map((location) => location.latitude)];
const latitudeList = [...locationLati[0]];
const locationLongi = [devices?.map((location) => location.longitude)];
const longitudeList = [...locationLongi[0]];
let positionCurrent = [latitudeList[0], longitudeList[0]];
const newDevice = [...devices].reverse();
return (
<MapContainer
center={[0,0]}
zoom={12}
markerZoomAnimation={true}
>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Markers data={newDevice} isActive />
</MapContainer>
);
};
export default Map;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.