Skip to content

Commit

Permalink
Added support for MultiLine, MultiPolygon and MultiPoint in drawtools (
Browse files Browse the repository at this point in the history
…#1883)

Co-authored-by: Stefan Forsgren <[email protected]>
  • Loading branch information
steff-o and Stefan Forsgren authored Oct 31, 2023
1 parent 91c4aa7 commit 42f45ed
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 24 deletions.
24 changes: 3 additions & 21 deletions src/controls/editor/copyTool.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import Select from 'ol/interaction/Select';
import Feature from 'ol/Feature';
import { MultiPolygon, MultiLineString, MultiPoint } from 'ol/geom';

import dispatcher from './editdispatcher';

// Point of entry. Create on of these each time the tool is selected
// viewer: the viewer
// editLayer: the destination layer for edits
// options: the current drawTools configuration for this layer
const copyTool = function copyTool(viewer, editLayer, options) {
const copyTool = function copyTool(viewer, options) {
const map = viewer.getMap();
const destinationLayer = editLayer;
let selectLayers = [];
let hasGoups = false;

Expand Down Expand Up @@ -72,24 +71,7 @@ const copyTool = function copyTool(viewer, editLayer, options) {
const accept = window.confirm('Kopiera vald geometri? Avbryt för att välja en annan');
if (accept) {
const f = new Feature(e.selected[0].getGeometry().clone());
const featureGeometryType = f.getGeometry().getType();
const layerGeometryType = destinationLayer.get('geometryType');
// Correct geometry type to conform to edit layer
// it will fail in edit handler if geometry is incorrect type
if (featureGeometryType !== layerGeometryType) {
if (featureGeometryType === 'Polygon' && layerGeometryType === 'MultiPolygon') {
const multiPoly = new MultiPolygon([f.getGeometry()]);
f.setGeometry(multiPoly);
}
if (featureGeometryType === 'LineString' && layerGeometryType === 'MultiLineString') {
const multiLine = new MultiLineString([f.getGeometry()]);
f.setGeometry(multiLine);
}
if (featureGeometryType === 'Point' && layerGeometryType === 'MultiPoint') {
const multiPoint = new MultiPoint([f.getGeometry()]);
f.setGeometry(multiPoint);
}
}

cancelTool();
// Important! Remove handler so it won't linger
document.removeEventListener('toggleEdit', onToggleEdit, { once: true });
Expand Down
5 changes: 4 additions & 1 deletion src/controls/editor/drawtools.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ let layer;
const drawToolsSelector = function drawToolsSelector(tools, defaultLayer, v) {
const toolNames = {
Polygon: 'Polygon',
MultiPolygon: 'Polygon',
Point: 'Punkt',
MultiPoint: 'Punkt',
Line: 'Linje',
MultiLine: 'Linje',
box: 'Rektangel',
Copy: 'Kopiera'
};
Expand Down Expand Up @@ -73,7 +76,7 @@ const drawToolsSelector = function drawToolsSelector(tools, defaultLayer, v) {
// Copy tool is handled entirely in copyTool. Only notify edithandler to back off
// and call copyTool to do its stuff.
dispatcher.emitChangeEditorShapes('custom');
copyTool(viewer, layer, drawTools.find((tool) => tool.toolName === 'Copy'));
copyTool(viewer, drawTools.find((tool) => tool.toolName === 'Copy'));
break;
default:
// This is an OL shape tool. Let edithandler handle it
Expand Down
39 changes: 37 additions & 2 deletions src/controls/editor/edithandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Modify from 'ol/interaction/Modify';
import Snap from 'ol/interaction/Snap';
import Collection from 'ol/Collection';
import Feature from 'ol/Feature';
import { LineString } from 'ol/geom';
import { LineString, MultiPolygon, MultiLineString, MultiPoint } from 'ol/geom';
import { noModifierKeys } from 'ol/events/condition';
import { Button, Element as El, Modal } from '../../ui';
import Infowindow from '../../components/infowindow';
Expand Down Expand Up @@ -280,6 +280,35 @@ async function addFeature(feature) {
editAttributes(feature);
}
}
/**
* Checks if a feature's geometry type is same as current edit layer's type. If it can be converted to
* correct type it will do that e.g. creating a multi variant of a single geometry.
* @param {any} f Feature to check
* @returns {boolean} True if feature matches layer
*/
function ensureCorrectGeometryType(f) {
// Correct geometry type to conform to edit layer
const featureGeometryType = f.getGeometry().getType();
const layerGeometryType = editLayers[currentLayer].get('geometryType');
if (featureGeometryType !== layerGeometryType) {
if (featureGeometryType === 'Polygon' && layerGeometryType === 'MultiPolygon') {
const multiPoly = new MultiPolygon([f.getGeometry()]);
f.setGeometry(multiPoly);
return true;
}
if (featureGeometryType === 'LineString' && layerGeometryType === 'MultiLineString') {
const multiLine = new MultiLineString([f.getGeometry()]);
f.setGeometry(multiLine);
return true;
}
if (featureGeometryType === 'Point' && layerGeometryType === 'MultiPoint') {
const multiPoint = new MultiPoint([f.getGeometry()]);
f.setGeometry(multiPoint);
return true;
}
}
return featureGeometryType === layerGeometryType;
}

// Handler for OL Draw interaction
function onDrawEnd(evt) {
Expand All @@ -295,6 +324,12 @@ function onDrawEnd(evt) {
// freehand produces so many vertices that a clean up is still a good idea.
f.setGeometry(f.getGeometry().simplify(0.00001));

if (!ensureCorrectGeometryType(f)) {
// This is a configuration problem. You have added a tool that produces incorrect geometry type
console.error('Incorrect geometry type for layer');
return;
}

// If live validation did its job, we should not have to validate here, but freehand bypasses all controls and we can't tell if freehand was used.
if (validateOnDraw && !topology.isGeometryValid(f.getGeometry())) {
alert('Kan ej spara, geometrin är ogiltig');
Expand Down Expand Up @@ -422,7 +457,7 @@ function onCustomDrawEnd(e) {
// Check if a feature has been created, or tool canceled
const feature = e.detail.feature;
if (feature) {
if (feature.getGeometry().getType() !== editLayers[currentLayer].get('geometryType')) {
if (!ensureCorrectGeometryType(feature)) {
alert('Kan inte lägga till en geometri av den typen i det lagret');
} else {
// Must move geometry to correct property. Setting geometryName is not enough.
Expand Down
9 changes: 9 additions & 0 deletions src/controls/editor/shapes.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,20 @@ export default (drawType) => {
Line: {
type: 'LineString'
},
MultiLine: {
type: 'MultiLineString'
},
Polygon: {
type: 'Polygon'
},
MultiPolygon: {
type: 'MultiPolygon'
},
Point: {
type: 'Point'
},
MultiPoint: {
type: 'MultiPoint'
}
};

Expand Down

0 comments on commit 42f45ed

Please sign in to comment.