I'm trying to get the coordinate points from a drawn polygon in an Open layers map using react.
I'm having 2 problems
I cannot subscribed to the
drawendcause when I do the function that I want trigger on that even does not gets trigered. When I uses another event,clickfor example my function runs?I cannot get
event.feature.getGeometry()to get the actual coordinates from my polygon. I works when I use points and the geometry of points, but not of polygons?
For example the below code works when I'm subscribing to click event on the Map and I can get the geometry for each point.
import { useEffect, useState } from "react";
export function useWatchOnMapDrawPolygon(mapRef) {
const [polygonCoords, setPolygonCoords] = useState([]);
const onDrawEnd = (event: any) => {
const olMap = event.map;
console.log("event.map inside useWatchOnMapDrawPolygon", olMap);
console.log("olMap.getLayers", olMap.getLayers());
olMap.forEachFeatureAtPixel(event.pixel, (feature: any) => {
const featureId = feature.getId();
const extent = feature?.getGeometry()?.getExtent();
console.log("featureId", featureId); // undefined
console.log("extent", extent); // (4) [119175.69299028325, 175330.0603457574, 155684.03674028325, 201845.0525332574]0: 119175.692990283251: 175330.06034575742: 155684.036740283253: 201845.0525332574length: 4[[Prototype]]: Array(0)
setPolygonCoords(extent); // (4) [119175.69299028325, 175330.0603457574, 155684.03674028325, 201845.0525332574]0: 119175.692990283251: 175330.06034575742: 155684.036740283253: 201845.0525332574length: 4[[Prototype]]: Array(0)
});
};
useEffect(() => {
if (!(mapRef && mapRef.current && mapRef.current.map)) {
return;
}
mapRef.current.map.on("click", onDrawEnd);
() => mapRef.current.map.un("click", onDrawEnd);
}, [mapRef?.current?.map]);
console.log("polygonCoords", polygonCoords);
return polygonCoords;
}
But when I try to do the same using the drawend event my function onDrawEnd does not run and event.feature comes back undefined.
In the example below I'm tracking click event to force the onDrawEnd fn to run but then I do not get the data that I want which is coordinates from a polygon [[], [], ...etc]
import { useEffect, useState } from "react";
export function useWatchOnMapDrawPolygon(mapRef) {
const [polygonCoords, setPolygonCoords] = useState([]);
const onDrawEnd = (event: any) => {
const olMap = event.map;
console.log("event.map inside useWatchOnMapDrawPolygon", olMap); // [NOTE]: This is the map object,
console.log("olMap.getLayers", olMap.getLayers()); // [NOTE]: This is the layers object
const polygonFeature = event.feature; // [Error]: Event does not have a feature property
const polygonGeometry = polygonFeature.getGeometry(); // [ERROR]: Cannot read property 'getGeometry' of undefined
const polygonCoordinates = polygonGeometry.getCoordinates();
setPolygonCoords(polygonCoordinates); // [ERROR]
};
useEffect(() => {
if (!(mapRef && mapRef.current && mapRef.current.map)) {
return;
}
mapRef.current.map.on("click", onDrawEnd);
() => mapRef.current.map.un("click", onDrawEnd); // [NOTE]: I have tried `drawend` event, but it does not register it for some reason, and yet I can draw on the map. When I change to `click` or `moveend` it runs the onDrawEnd function.
}, [mapRef?.current?.map]);
console.log("polygonCoords", polygonCoords);
return polygonCoords;
}
The
drawendevent is on the interaction, not on the map. The map does not emit adrawendevent.You are missing a
returnstatement inuseEffect, simply declaring a function is not enough, you have to return it.forEachFeatureAtPixeldoes not work if you click inside a hole of the polygon, make sure your polygons are solid. You can also check thehitToleranceparameter.Also, I would advise against using
useEffectfor handling Openlayers maps as you will run into problems when React mounts and unmounts your components.I don't know why the polygons