使用 Leaflet-react 时如何调用 fitBounds()?
Posted
技术标签:
【中文标题】使用 Leaflet-react 时如何调用 fitBounds()?【英文标题】:How do you call fitBounds() when using leaflet-react? 【发布时间】:2018-11-24 11:55:26 【问题描述】:我不知道如何在 Leaflet 地图上调用 fitBounds()。
如果我只是使用香草传单,此解决方案将完美运行:Zoom to fit all markers in Mapbox or Leaflet
不幸的是,我正在使用 react-leaflet。
如果我只是单独使用传单,这就是解决方案。
var leafletMap = new L.featureGroup([marker1, marker2, marker3]);
map.fitBounds(leafletMap.getBounds());
我认为这段代码(我的代码)this.mapRef.current.leafletElement
等价于var leafletMap = new L.featureGroup([marker1, marker2, marker3]); leafletMap.getBounds();
,但是在 react-leaflet 中map.fitBounds();
等价于什么?
基本上,我试图在地图上显示多个标记并相应地调整视图(放大、缩小、飞到等)。
这是我的代码。
import React, createRef, Component from 'react'
import Map, TileLayer, Marker, Popup, FeatureGroup from 'react-leaflet'
export default class MasterLeafletMap extends Component
constructor(props)
super(props);
this.markers = this.markers.bind(this);
this.handleClick = this.handleClick.bind(this);
this.mapRef = createRef()
handleClick()
const leafletMap = this.mapRef.current.leafletElement;
this.mapRef.current.fitBounds(leafletMap.getBounds()); // Doesn't work
leafletMap.fitBounds(leafletMap.getBounds()); // Doesn't work (just trying to get the bounds of the markers that are there and adjust the view)
this.mapRef.current.leafletElement.flyToBounds(leafletMap.getBounds()); // Doesn't work
markers()
if (this.props.search.items instanceof Array)
return this.props.search.items.map(function(object, i)
const position = [object._geoloc.lat, object._geoloc.lng];
return <Marker position=position>
<Popup>
<span>
<h4>object.title</h4>
object.address, <br /> object.city, object.state, object.zip <br /> object._geoloc.lat, object._geoloc.lng
</span>
</Popup>
</Marker>
)
render()
const hasLoaded = this.props.search.items instanceof Array;
if (!hasLoaded)
return null;
const position = [this.props.search.items[0]._geoloc.lat, this.props.search.items[0]._geoloc.lng];
return (
<div className="leaflet-map-container">
<div onClick=this.handleClick>Hello</div>
<Map center=position zoom=13 ref=this.mapRef>
<TileLayer
attribution="&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"
url="https://s.tile.openstreetmap.org/z/x/y.png"
/>
<FeatureGroup>
this.markers()
</FeatureGroup>
</Map>
</div>
)
提前致谢。
【问题讨论】:
我试图理解你的例子。当您调用map.fitBounds()
时,您应该提供您希望地图适合的边界。由于您尝试在当前边界上 fitBounds 我猜什么都不会发生?您可以尝试在标记数组的所有 LatLng 值上拟合边界吗? (我认为标记数组 === this.props.search.items
?
【参考方案1】:
这是一个如何通过react-leaflet
完成它的示例
handleClick()
const map = this.mapRef.current.leafletElement; //get native Map instance
const group = this.groupRef.current.leafletElement; //get native featureGroup instance
map.fitBounds(group.getBounds());
在哪里
<div>
<button onClick=this.handleClick>Zoom</button>
<Map
center=this.props.center
zoom=this.props.zoom
ref=this.mapRef
>
<TileLayer
attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://s.tile.openstreetmap.org/z/x/y.png"
/>
<FeatureGroup ref=this.groupRef>
this.props.locations.map(location => (
<Marker
key=location.name
position= lat: location.lat, lng: location.lng
>
<Popup>
<span>
<h4>location.name</h4>
</span>
</Popup>
</Marker>
))
</FeatureGroup>
</Map>
</div>
对应于
var leafletMap = new L.featureGroup([marker1, marker2, marker3]);
map.fitBounds(leafletMap.getBounds());
Here is a demo
【讨论】:
感谢瓦迪姆!你的回答就是我要找的! Спасибо! :) 有什么办法不使用ref 您可以将this.mapRef.current.leafletElement
替换为useMap()
以将其中一个引用替换为钩子。这有点干净:react-leaflet.js.org/docs/api-map/#usemap。我也在使用 React 钩子,发现 getBounds
定义在 current
而不是 leafletElement
这样 map.fitBounds(groupRef.current.getBounds())
工作。【参考方案2】:
如果您希望在地图加载时出现这种行为,您可以使用onlayeradd
事件。
例子:
const fitToCustomLayer = () =>
if (mapRef.current && customAreaRef.current) //we will get inside just once when loading
const map = mapRef.current.leafletElement
const layer = customAreaRef.current.leafletElement
map.fitBounds(layer.getBounds().pad(0.5))
return (
<Map ref=mapRef onlayeradd=fitToCustomLayer>
<LayersControl position="topright">
<Overlay checked key="customArea" name="Área de interesse">
<GeoJSON ref=customAreaRef data=collection style=geoJSONStyle />
</Overlay>
<BaseLayer name="Open Street Map">
<TileLayer attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://s.tile.openstreetmap.org/z/x/y.png"/>
</BaseLayer>
</LayersControl>
</Map>
)
*编辑:如果参考层是最后一层,这似乎不起作用。将它放在基础层之前不会影响渲染并且可以工作。
如果您出于正当目的需要使用onlayeradd
,请确保添加另一个标志以避免进入if
并再次触发fitBounds
并丢失地图的当前位置。
Ps:我尝试了react-leaflet的onload
方法,但是it doesn't seems to work。
【讨论】:
这样fitBounds
可以被多次调用。 onlayeradd
被所有层调用,因此对于GeoJSON
之后的每一层,这些引用存在。一种可能的解决方法是将GeoJSON
ref 替换为useCallback hook。以上是关于使用 Leaflet-react 时如何调用 fitBounds()?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 BlackBerry 5.0 及更高版本的 J2ME 代码中使用 wifi 调用 HTTP URL?
XCUITest - 如何在应用程序运行时禁用 Wi Fi?
当 Wi-Fi Direct 范围内的对等点不再可用时,如何通知?