I am building a React app at the moment and need to move from MapBox to Openlayers as thats what my client uses internally. Really struggling with basic functionality to get openlayers maps to react to events. At the moment, I am trying a simple 'click button, re-centre map' but can not get it to work. Can anybody help? It's got to be something simple I am doing wrong.
I am using Openlayers v 6.0.1 (ol).
import React, { useState, useEffect, useRef } from "react";
import Map from "ol/Map.js";
import View from "ol/View.js";
import Overlay from "ol/Overlay.js";
import LayerTile from "ol/layer/Tile.js";
import SourceOSM from "ol/source/OSM.js";
import * as proj from "ol/proj";
const MapView2 = () => {
// set state
const [center, setCenter] = useState(proj.fromLonLat([0, 0])); // set center of map at 0,0
const [zoom, setZoom] = useState(3); // set aoom
const posGreenwich = proj.fromLonLat([0, 51.47]);
// set initial map objects
const view = new View({
center: center,
zoom: zoom
});
const map = new Map({
target: null, // set this in componentDidMount useEffect[]
layers: [
new LayerTile({
source: new SourceOSM()
})
],
view: view
});
const overlayRef = useRef(null);
const popUpRef = useRef(null);
// useEffect Hooks
// [] = component did mount
// set the initial map targets
useEffect(() => {
map.setTarget("map");
map.on("moveend", () => {
setCenter(map.getView().getCenter());
setZoom(map.getView().getZoom());
});
// Basic overlay to show where i want the new center to be
const overlay = new Overlay({
position: posGreenwich,
element: overlayRef.current,
positioning: "center-center",
stopEvent: false
});
map.addOverlay(overlay);
// clean up upon component unmount
return () => {
console.log("will unmount");
map.setTarget(null);
};
}, []);
// ***** IT DOESNT WORK *******
useEffect(() => {
// [center, zoom] this fires after each time the center or zoom state is updated
// it should animate the view move
console.log("UseEffect Center & Zoom", center, zoom);
console.log("View", JSON.stringify(view)); // if you check this, the view correctly has a new center and zoom
// view has a new center and zoom but will not move to it automatically
// try to force it to move here
// DOESN'T WORK - how do I get the map to move???? :(
view.animate({ zoom: zoom }, { center: center }, { duration: 2000 });
}, [center, zoom]);
// helpers
const btnAction = () => {
// when button is clicked, recentre map
// this does not work :(
setCenter(posGreenwich);
setZoom(6);
};
// render
return (
<div>
<div id="map" style={{ width: "100vw", height: "100vh" }}></div>
<div
style={styles.bluecircle}
ref={overlayRef}
id="overlay"
title="overlay"
/>
<button
style={{
position: "absolute",
right: 10,
top: 10,
backgroundColor: "white"
}}
onClick={() => {
btnAction();
}}
>
CLICK
</button>
</div>
);
};
export default MapView2;
const styles = {
bluecircle: {
width: 30,
height: 30,
border: "1px solid #088",
bordeRadius: "15",
backgroundColor: "#0ff",
opacity: 0.5,
zIndex: 9999
}
};
I was having a similar problem and solved it by using useState for the map variable, such as:
const [map] = useState(
new Map({
target: null, // set this in componentDidMount useEffect[]
layers: [
new LayerTile({
source: new SourceOSM()
})
],
view: view
})
);
Then, inside useEffect:
map.getView.animate({ zoom: zoom }, { center: center }, { duration: 2000 });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With