Open
Description
I have a custom draw control here:
import React, { useCallback } from "react";
import mapboxgl from "mapbox-gl";
import MapboxDraw from "@mapbox/mapbox-gl-draw";
import { useControl } from "react-map-gl";
import CheapRuler from "cheap-ruler";
import * as turf from "@turf/turf";
import "@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css";
import "mapbox-gl/dist/mapbox-gl.css";
const DrawControl = (props) => {
const {
onCreate = () => {},
onUpdate = () => {},
onDelete = () => {},
position = "top-right",
} = props;
const handleRender = useCallback(({ target: map }) => {
if (!map) return;
let labelFeatures = [];
const drawControl = map._controls.find(
(control) => control instanceof MapboxDraw
);
if (!drawControl) return;
const all = drawControl.getAll();
const ruler = new CheapRuler(map.getCenter().lat, "meters");
if (all && all.features) {
all.features.forEach((feature) => {
switch (turf.getType(feature)) {
case "Point":
if (feature.geometry.coordinates.length > 0) {
const label = `${feature.geometry.coordinates[1].toFixed(
4
)}, ${feature.geometry.coordinates[0].toFixed(4)}`;
labelFeatures.push(
turf.point(feature.geometry.coordinates, {
type: "point",
label,
})
);
}
break;
case "LineString":
if (feature.geometry.coordinates.length > 0) {
const length = ruler.lineDistance(feature.geometry.coordinates);
const midpoint = ruler.along(
feature.geometry.coordinates,
length / 2
);
const label = `${Math.round(length)} m`;
labelFeatures.push(turf.point(midpoint, { type: "line", label }));
}
break;
case "Polygon":
if (
feature.geometry.coordinates.length > 0 &&
feature.geometry.coordinates[0].length > 3
) {
const area = turf.area(feature);
const centroid = turf.centroid(feature).geometry.coordinates;
const label = `${(area * 0.000247105).toFixed(2)} acres`; // Convert to acres
labelFeatures.push(turf.point(centroid, { type: "area", label }));
}
break;
}
});
}
if (map.getSource("measurements-source")) {
map.getSource("measurements-source").setData({
type: "FeatureCollection",
features: labelFeatures,
});
} else {
map.addSource("measurements-source", {
type: "geojson",
data: {
type: "FeatureCollection",
features: labelFeatures,
},
});
map.addLayer({
id: "measurements-layer",
type: "symbol",
source: "measurements-source",
layout: {
"text-field": ["get", "label"],
"text-size": 14,
"text-anchor": "center",
"text-offset": [0, 1.2],
"text-allow-overlap": true,
},
paint: {
"text-color": "#ff0000",
},
});
}
}, []);
useControl(
() => new MapboxDraw({ ...props }),
({ map }) => {
map.on("draw.create", onCreate);
map.on("draw.update", onUpdate);
map.on("draw.delete", onDelete);
map.on("draw.render", handleRender);
return () => {
map.off("draw.create", onCreate);
map.off("draw.update", onUpdate);
map.off("draw.delete", onDelete);
map.off("draw.render", handleRender);
};
},
{ position }
);
return null;
};
export default DrawControl;
In the Map.jsx component:
{drawingMode && (
<DrawControl
displayControlsDefault={false}
controls={{
polygon: "true",
trash: "true",
}}
defaultMode="draw_polygon"
onCreate={onUpdate}
onUpdate={onUpdate}
onDelete={onDelete}
/>
)}
It works totally fine on local instance but once a build is created and deployed on Linux server, the onCreate, onUpdate, onDelete events are not captured on the user interface.