我正在使用leaflet.js来开发具有整页地图的绘图层工具。用户将绘制一组图层来描述工业产品的零件。
传单地图及其图层应适合屏幕。例如,如果用户使用1920x1080分辨率的pc在左下角绘制一个圆,则应该使用1366x768分辨率的pc在左下角看到一个圆。传单地图可以正确调整页面的大小,但是在本例中,由于我的电脑中的经纬度,圆圈不在屏幕上。
我尝试使用invalidateSize,maxBounds,fitBounds等开发此示例,但尚未成功。如何开发这种情况?
从1366x768的外观加载了相同的GeoJSON,(注意左上角):
地图(反应):
const corner1 = L.latLng(-180, -180);
const corner2 = L.latLng(180, 180);
const bounds = L.latLngBounds(corner1, corner2);
<Map
ref={map => {
this.tryToCreate(map);
}}
className="c-leaflet-map-map"
center={[0, 0]}
zoom={0}
maxZoom={10}
zoomControl={false}
onzoomend={this.zoomLevelsChange}
maxBounds={bounds}
maxBoundsViscosity={1.0}
zoomSnap={0}
crs={L.CRS.Simple}
>
<ImageOverlay
bounds={map.backgroundImageBounds || map.bounds}
attribution="&copy TofnaTech"
url={
map.backgroundImage ||
map.backgroundImageURL ||
TransparentImage
}
opacity={map.opacity}
className={cn({ transparentImage: !map.backgroundImage })}
/>
<FeatureGroup
ref={controller => {
this.controller = controller;
this.tryToCreate();
}}
>
<EditControl
position="topleft"
onCreated={this._onCreated}
onEditStart={this.onEditStart}
onEditStop={this.onEditStop}
onEdited={this.onEdited}
draw={{
polyline: false,
polygon: {
shapeOptions: { ...defaultShapeOptions }
},
rectangle: {
shapeOptions: { ...defaultShapeOptions }
},
circle: {
shapeOptions: { ...defaultShapeOptions }
},
marker: false,
circlemarker: false
}}
edit={{
remove: false
}}
/></Map>
使用React-Leaflet有点不同。您可以在componentDidMount
中完成您想做的事情,您可以在其中引用地图,然后在其上调用fitBounds。
编辑:添加矩形
但是,下一个问题是解决方案。 Leaflet将保持长宽比,因此,无论屏幕和浏览器的长宽比如何,如果您始终希望它显示在屏幕的左下角,则实际上您需要动态绘制圆角(或矩形)。因此,在componentDidMount
中,在设置新边界之后,就可以获取这些边界,并定义一个矩形(或其他任何形状)以始终在相对于getBounds()._southWest
边界的同一位置进行渲染。在此代码中,我将此代码包装在setTimeout
中,因为动画需要一点时间,并且该时刻需要过去才能从getBounds()
中获得新的边界值。我敢肯定有一种减少或减少动画时间的方法。
为了将矩形保持在同一位置,我为地图编写了一个onMove
函数,以始终重新计算位置,而不用四处移动地图或调整窗口大小。
请注意,在此示例中,矩形的大小有点小巧,但是我认为使用CRS获得一致的大小会更容易,因为CRS比经纬度和经度要均匀得多。
class Map extends React.Component {
state = {
rectCoords: null
};
componentDidMount() {
const map = this.mapReference.leafletElement;
window.map = map;
console.log("Initiates with bounds:", map.getBounds());
map.fitBounds([[32.852169, -90.5322], [33.852169, -85.5322]]);
setTimeout(() => {
console.log("Bounds immediately reset to", map.getBounds());
const rectCoords = [
[
map.getBounds()._southWest.lat + 0.1,
map.getBounds()._southWest.lng + 0.1
],
[
map.getBounds()._southWest.lat + 1,
map.getBounds()._southWest.lng + 1
]
];
this.setState({ rectCoords });
}, 500);
}
onMapmove = () => {
const map = this.mapReference.leafletElement;
const rectCoords = [
[
map.getBounds()._southWest.lat + 0.1,
map.getBounds()._southWest.lng + 0.1
],
[map.getBounds()._southWest.lat + 1, map.getBounds()._southWest.lng + 1]
];
this.setState({ rectCoords });
}
render() {
return (
<LeafletMap
ref={mapReference => this.mapReference = mapReference}
zoom={4}
center={[33.852169, -100.5322]}
onMove={() => this.onMapmove() } >
<TileLayer ... />
{this.state.rectCoords && (
<Rectangle
bounds={this.state.rectCoords}
color={"#ff7800"}
weight={1}
/>
)}
</LeafletMap>
);
}
}
因此,即使地图以某些范围开始,它也会立即将其调整为所需的范围,并始终在同一位置的左下角呈现矩形。
Here是一个有效的代码框。我相信这也可以适合使用CRS Simple。