React Leaflet:动态添加标记
React Leaflet: Add markers dynamically
如何在 React-Leaflet 地图中动态添加标记?
我想在用户点击地图时添加新标记。我无法让它工作。
import React, { Component } from 'react'
import { render } from 'react-dom';
import Control from 'react-leaflet-control';
import { Map, Marker, Popup, TileLayer, ZoomControl, ScaleControl } from 'react-leaflet';
import './Points.scss'
export default class PointsMap extends Component {
state = {
lat: 50.2,
lng: 30.2,
zoom: 13,
}
handleClick = (e) => {
this.addMarker();
}
addMarker() {
// A) Following raises error:
var marker3 = L.marker([50.5, 30.5]).addTo(this.refs.map);
// B) With following marker doesn't appear on map:
const position2 = [50,30];
<Marker map={this.refs.map} position={position2} />
}
render () {
const position = [this.state.lat, this.state.lng]
return (
<Map ref='map' center={position} zoom={this.state.zoom} onClick= {this.handleClick} >
<ZoomControl position="topright" />
<ScaleControl position="bottomright" />
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
/>
<Marker map={this.refs.map} position={position} >
<Popup>
<span>A pretty CSS3 popup. <br /> Easily customizable.</span>
</Popup>
</Marker>
</Map>
)
}
}
在 addMarker() 中,我尝试添加新标记。我尝试通过两种方式做到这一点:
A)
var marker3 = L.marker([50.5, 30.5]).addTo(this.refs.map);
引发错误:
Uncaught TypeError: map.addLayer is not a function
at NewClass.addTo (leaflet-src.js:3937)
at PointsMap.addMarker (Points.js?12f5:54)
B)
const position2 = [50,30];
<Marker map={this.refs.map} position={position2} />
它没有添加任何新标记,也没有引发任何错误。
你知道如何动态地 add/remove 标记吗?
为了充分利用 react-leaflet,您应该考虑如何以某种方式设计地图渲染React 生命周期处理标记的点击和显示。 React-leaflet 为您处理几乎所有的传单繁琐工作。
您应该使用组件的状态或道具来跟踪组件显示的标记。因此,与其手动调用 L.marker
,不如渲染一个新的 <Marker>
组件。
点击地图后添加标记的反应方式如下:
class SimpleExample extends React.Component {
constructor() {
super();
this.state = {
markers: [[51.505, -0.09]]
};
}
addMarker = (e) => {
const {markers} = this.state
markers.push(e.latlng)
this.setState({markers})
}
render() {
return (
<Map
center={[51.505, -0.09]}
onClick={this.addMarker}
zoom={13}
>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
/>
{this.state.markers.map((position, idx) =>
<Marker key={`marker-${idx}`} position={position}>
<Popup>
<span>A pretty CSS3 popup. <br/> Easily customizable.</span>
</Popup>
</Marker>
)}
</Map>
);
}
}
这是一个 jsfiddle:https://jsfiddle.net/q2v7t59h/413/
我使用了下面的代码,它成功运行了。在这段代码中,用户只能在一个位置添加一个标记,它可以改变:
注意导入leaflet.css文件
有时在添加传单文件后,图像加载会出现两个错误。要解决这些错误,请在导入部分导入 marker-icon.png 和 marker-shadow.png,然后在下面定义 L.Marker.prototype.options.icon link。
如果地图不显示,将高度和宽度(style={{width: '100%',height: '400px'}}) 添加到地图标签作为样式
import React from 'react';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';
class OSMap extends React.Component {
constructor() {
super();
this.state = {
markers: [[35.6892, 51.3890]],
};
}
addMarker = (e) => {
const { markers } = this.state;
markers.pop();
markers.push(e.latlng);
this.setState({ markers });
}
render() {
let DefaultIcon = L.icon({
iconUrl: icon,
shadowUrl: iconShadow
});
L.Marker.prototype.options.icon = DefaultIcon;
return (
<div>
<Map
center={[35.6892, 51.3890]}
onClick={this.addMarker}
zoom={13}
maxZoom={18}
minZoom={5}
style={{width: '100%',height: '400px'}}
>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
/>
{this.state.markers.map((position, idx) =>
<Marker key={`marker-${idx}`} position={position}></Marker>
)}
</Map>
</div>
);
}
}
export default OSMap;
对于任何使用React Leaflet v3(基于钩子并且使用MapContainer
而不是Map
)的人,您可以使用以下代码在点上添加标记地图被点击:
function LocationMarkers() {
const initialMarkers: LatLng[] = [new LatLng(51.505, -0.09)];
const [markers, setMarkers] = useState(initialMarkers);
const map = useMapEvents({
click(e) {
markers.push(e.latlng);
setMarkers((prevValue) => [...prevValue, e.latlng]);
}
});
return (
<React.Fragment>
{markers.map(marker => <Marker position={marker} ></Marker>)}
</React.Fragment>
);
}
function LeafletMap() {
const mapCentre = new LatLng(51.505, -0.09);
return (
<MapContainer center={mapCentre}>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<LocationMarkers />
</MapContainer>
);
}
此方法定义了一个函数 LocationMarkers
,它可以包含在 <MapContainer>...</MapContainer>
标记中。 LocationMarkers
使用 useMapEvents hook 来侦听地图事件(在本例中为 click
)并在收到事件时执行操作。 useState
用于管理要在地图上显示的标记数组。
如何在 React-Leaflet 地图中动态添加标记?
我想在用户点击地图时添加新标记。我无法让它工作。
import React, { Component } from 'react'
import { render } from 'react-dom';
import Control from 'react-leaflet-control';
import { Map, Marker, Popup, TileLayer, ZoomControl, ScaleControl } from 'react-leaflet';
import './Points.scss'
export default class PointsMap extends Component {
state = {
lat: 50.2,
lng: 30.2,
zoom: 13,
}
handleClick = (e) => {
this.addMarker();
}
addMarker() {
// A) Following raises error:
var marker3 = L.marker([50.5, 30.5]).addTo(this.refs.map);
// B) With following marker doesn't appear on map:
const position2 = [50,30];
<Marker map={this.refs.map} position={position2} />
}
render () {
const position = [this.state.lat, this.state.lng]
return (
<Map ref='map' center={position} zoom={this.state.zoom} onClick= {this.handleClick} >
<ZoomControl position="topright" />
<ScaleControl position="bottomright" />
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
/>
<Marker map={this.refs.map} position={position} >
<Popup>
<span>A pretty CSS3 popup. <br /> Easily customizable.</span>
</Popup>
</Marker>
</Map>
)
}
}
在 addMarker() 中,我尝试添加新标记。我尝试通过两种方式做到这一点:
A)
var marker3 = L.marker([50.5, 30.5]).addTo(this.refs.map);
引发错误:
Uncaught TypeError: map.addLayer is not a function
at NewClass.addTo (leaflet-src.js:3937)
at PointsMap.addMarker (Points.js?12f5:54)
B)
const position2 = [50,30];
<Marker map={this.refs.map} position={position2} />
它没有添加任何新标记,也没有引发任何错误。
你知道如何动态地 add/remove 标记吗?
为了充分利用 react-leaflet,您应该考虑如何以某种方式设计地图渲染React 生命周期处理标记的点击和显示。 React-leaflet 为您处理几乎所有的传单繁琐工作。
您应该使用组件的状态或道具来跟踪组件显示的标记。因此,与其手动调用 L.marker
,不如渲染一个新的 <Marker>
组件。
点击地图后添加标记的反应方式如下:
class SimpleExample extends React.Component {
constructor() {
super();
this.state = {
markers: [[51.505, -0.09]]
};
}
addMarker = (e) => {
const {markers} = this.state
markers.push(e.latlng)
this.setState({markers})
}
render() {
return (
<Map
center={[51.505, -0.09]}
onClick={this.addMarker}
zoom={13}
>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
/>
{this.state.markers.map((position, idx) =>
<Marker key={`marker-${idx}`} position={position}>
<Popup>
<span>A pretty CSS3 popup. <br/> Easily customizable.</span>
</Popup>
</Marker>
)}
</Map>
);
}
}
这是一个 jsfiddle:https://jsfiddle.net/q2v7t59h/413/
我使用了下面的代码,它成功运行了。在这段代码中,用户只能在一个位置添加一个标记,它可以改变:
注意导入leaflet.css文件
有时在添加传单文件后,图像加载会出现两个错误。要解决这些错误,请在导入部分导入 marker-icon.png 和 marker-shadow.png,然后在下面定义 L.Marker.prototype.options.icon link。
如果地图不显示,将高度和宽度(style={{width: '100%',height: '400px'}}) 添加到地图标签作为样式
import React from 'react';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';
class OSMap extends React.Component {
constructor() {
super();
this.state = {
markers: [[35.6892, 51.3890]],
};
}
addMarker = (e) => {
const { markers } = this.state;
markers.pop();
markers.push(e.latlng);
this.setState({ markers });
}
render() {
let DefaultIcon = L.icon({
iconUrl: icon,
shadowUrl: iconShadow
});
L.Marker.prototype.options.icon = DefaultIcon;
return (
<div>
<Map
center={[35.6892, 51.3890]}
onClick={this.addMarker}
zoom={13}
maxZoom={18}
minZoom={5}
style={{width: '100%',height: '400px'}}
>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
/>
{this.state.markers.map((position, idx) =>
<Marker key={`marker-${idx}`} position={position}></Marker>
)}
</Map>
</div>
);
}
}
export default OSMap;
对于任何使用React Leaflet v3(基于钩子并且使用MapContainer
而不是Map
)的人,您可以使用以下代码在点上添加标记地图被点击:
function LocationMarkers() {
const initialMarkers: LatLng[] = [new LatLng(51.505, -0.09)];
const [markers, setMarkers] = useState(initialMarkers);
const map = useMapEvents({
click(e) {
markers.push(e.latlng);
setMarkers((prevValue) => [...prevValue, e.latlng]);
}
});
return (
<React.Fragment>
{markers.map(marker => <Marker position={marker} ></Marker>)}
</React.Fragment>
);
}
function LeafletMap() {
const mapCentre = new LatLng(51.505, -0.09);
return (
<MapContainer center={mapCentre}>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<LocationMarkers />
</MapContainer>
);
}
此方法定义了一个函数 LocationMarkers
,它可以包含在 <MapContainer>...</MapContainer>
标记中。 LocationMarkers
使用 useMapEvents hook 来侦听地图事件(在本例中为 click
)并在收到事件时执行操作。 useState
用于管理要在地图上显示的标记数组。