Describe the Issue When feature is deleted and new feature is added for vertices to update. The new feature is created twice. Every time this cycle is repeated. Function deleteVertex have the the code of this problem.
Actual Result new duplicate feature is added.
Expected Result Only 1 new feature should be created.
Reproduce Steps Add a feature. Remove the Feature any 1 index of coordinates. Remove the old Feature. Add the this new modified version of Feature using addFeatures.
Question Also I want to know if there is any easy way to add or remove the vertices.
Code
const MapOverLay = ({
type,
viewport,
setViewport,
save,
close,
previousFeatures,
defaultViewPort,
}) => {
const editorRef = useRef(null);
const featureRef = useRef(null);
const locateIconRef = useRef(false);
const [previousFeature, setPreviousFeature] = useState(previousFeatures);
const [mapData, setMapData] = useState({
editor: {
type: previousFeatures.length ? 'Editing' : '',
mode: previousFeatures.length ? new EditingMode() : null,
selectedFeatureIndex: null,
},
});
const onSelect = map => {
if (map.selectedEditHandleIndex !== null) {
featureRef.current = {
type: 'selectedEditHandleIndex',
index: map.selectedEditHandleIndex,
featureIndex: map.selectedFeatureIndex,
};
}
else {
featureRef.current = {
type: 'selectedFeatureIndex',
index: map.selectedFeatureIndex,
};
}
};
const onUpdate = ({ editType, data }) => {
if (editType === 'addFeature') {
const temp_data = makeClone(mapData);
temp_data.editor.type = 'Editing';
temp_data.editor.mode = new EditingMode();
setMapData(temp_data);
}
if (previousFeatures.length) {
setPreviousFeature(data);
}
};
const deleteVertex = () => {
const feature = editorRef.current.getFeatures()[0];
if (feature.geometry.coordinates[0].length !== 2) {
feature.geometry.coordinates[0].splice(featureRef.current.index, 1);
editorRef.current.deleteFeatures(featureRef.current.featureIndex);
editorRef.current.addFeatures(feature);
console.log('Delete');
}
else {
editorRef.current.deleteFeatures(featureRef.current.featureIndex);
}
featureRef.current = null;
};
// console.log(editorRef.current);
const deleteFeature = () => {
if (previousFeature.length) {
setPreviousFeature([]);
}
else {
editorRef.current.deleteFeatures(featureRef.current.index);
}
save([]);
};
const onDelete = () => {
if (featureRef.current !== null) {
switch (featureRef.current.type) {
case 'selectedEditHandleIndex':
deleteVertex();
return;
case 'selectedFeatureIndex':
deleteFeature();
return;
default:
break;
}
}
};
const onSave = map => {
save(map.getFeatures());
};
const getDrawModeStyle = () => {
switch (type) {
case 'Polygon':
return style.polygon;
case 'Point':
return style.point;
}
};
const getDrawModePressedStyle = () => {
switch (type) {
case 'Polygon':
return style.pressed_polygon;
case 'Point':
return style.pressed_point;
}
};
const getDrawMode = () => {
switch (type) {
case 'Polygon':
return new DrawPolygonMode();
case 'Point':
return new DrawPointMode();
}
};
const onToolClick = () => {
if (editorRef.current.getFeatures().length === 0) {
const temp_data = makeClone(mapData);
if (type === temp_data.editor.type) {
temp_data.editor.type = '';
temp_data.editor.mode = null;
setMapData(temp_data);
}
else {
temp_data.editor.type = type;
temp_data.editor.mode = getDrawMode();
setMapData(temp_data);
}
}
};
const locate = map => {
locateIconRef.current = true;
const features = map.getFeatures();
if (features.length) {
const center = centerOfMass(features[0]);
setViewport(prevState => ({
...prevState,
zoom: 10,
longitude: center.geometry.coordinates[0],
latitude: center.geometry.coordinates[1],
}));
}
else {
defaultViewPort();
}
};
const viewPortChangeFromMap = nextViewport => {
locateIconRef.current = false;
setViewport(nextViewport);
};
const _renderDrawTools = () => {
// copy from mapbox
return (
<>
<div className='mapboxgl-ctrl-top-left'>
<div className={['mapboxgl-ctrl-group mapboxgl-ctrl', style.navigation_group_top_left].join(' ')}>
<button
className="mapbox-gl-draw_ctrl-draw-btn"
title="Save"
onClick={() => onSave(editorRef.current)}
/>
<button
id={getDrawModeStyle()}
className={
[
'mapbox-gl-draw_ctrl-draw-btn mapbox-gl-draw_polygon',
mapData.editor.type === type ? getDrawModePressedStyle() : '',
].join(' ')
}
title="Select"
onClick={() => onToolClick()}
/>
<button
className="mapbox-gl-draw_ctrl-draw-btn mapbox-gl-draw_trash"
title="Remove"
onClick={onDelete}
/>
</div>
</div>
<div className='mapboxgl-ctrl-top-right'>
<div className={['mapboxgl-ctrl-group mapboxgl-ctrl', style.navigation_group_top_right].join(' ')}>
<button
className="mapbox-gl-draw_ctrl-draw-btn"
title="Close"
onClick={close}
/>
</div>
</div>
<div className='mapboxgl-ctrl-bottom-right'>
<div className={['mapboxgl-ctrl-group mapboxgl-ctrl', style.navigation_group_bottom_right].join(' ')}>
<button
className="mapbox-gl-draw_ctrl-draw-btn"
title="Focus"
onClick={() => locate(editorRef.current)}
/>
</div>
</div>
</>
);
};
return (
<ReactMapGL
{...viewport}
mapStyle="mapbox://styles/giddyops/ckips5wdw61xb17qs3eorsoj9"
mapboxApiAccessToken={MAPBOX_TOKEN}
onViewportChange={viewPortChangeFromMap}
attributionControl={false}
transitionDuration={1000}
transitionInterpolator={locateIconRef.current ? new FlyToInterpolator() : null}
>
<Editor
ref={editorRef}
mode={mapData.editor.mode}
clickRadius={12}
features={previousFeature.length ? previousFeature : null}
onSelect={onSelect}
onUpdate={onUpdate}
editHandleShape={'circle'}
featureStyle={getFeatureStyle}
editHandleStyle={getEditHandleStyle}
onClick={e => console.log(e)}
/>
{_renderDrawTools()}
</ReactMapGL>
);
};
I have reviewed your code and found out that it could be issue that delete features was finished deleting way after than adding feature. you can solve this issue by making the following changes: