diff --git a/config/i18n/de.js b/config/i18n/de.js index a09afe38..63fd5af1 100644 --- a/config/i18n/de.js +++ b/config/i18n/de.js @@ -38,7 +38,9 @@ export default { update_vertex: "Feature vertex aktualisieren", update_feature: "Feature-Attribut aktualisieren", update_multi_features: "Attribute ausgewählter Features aktualisieren", - copyfeaturefromexternallayer: "Create Feature from added layer" + copyfeaturefromexternallayer: "Feature aus hinzugefügter Ebene erstellen", + addhole: "Loch hinzufügen", + deletehole: "Loch entfernen" }, toolsoftool: { measure: "Messung anzeigen", diff --git a/config/i18n/en.js b/config/i18n/en.js index 35cd163e..8e46405b 100644 --- a/config/i18n/en.js +++ b/config/i18n/en.js @@ -38,7 +38,9 @@ export default { update_vertex: "Update feature vertex", update_feature: "Update feature attribute", update_multi_features: "Update attributes of selected features", - copyfeaturefromexternallayer: "Create Feature from added layer" + copyfeaturefromexternallayer: "Create Feature from added layer", + addhole: "Add hole", + deletehole: "Remove hole" }, toolsoftool: { measure: "Show measure", diff --git a/config/i18n/fi.js b/config/i18n/fi.js index 4df58798..e177b3a2 100644 --- a/config/i18n/fi.js +++ b/config/i18n/fi.js @@ -38,7 +38,9 @@ export default { update_vertex: "Päivitä pisteen ominaisuutta", update_feature: "Päivitä ominaisuus", update_multi_features: "Muokkaa valittujen ominaisuuksien attribuutteja", - copyfeaturefromexternallayer: "Create Feature from added layer" + copyfeaturefromexternallayer: "Luo ominaisuus lisätystä tasosta", + addhole: "Lisää reikä", + deletehole: "Poista reikä" }, toolsoftool: { measure: "Show measure", diff --git a/config/i18n/fr.js b/config/i18n/fr.js index 4d40bb76..6718f608 100644 --- a/config/i18n/fr.js +++ b/config/i18n/fr.js @@ -38,7 +38,9 @@ export default { update_vertex: "Mettre à jour les sommets des fonctionnalités", update_feature: "Modifier les attributs des fonctionnalités", update_multi_features: "Modifier les attributs des fonctionnalités sélectionnées", - copyfeaturefromexternallayer: "Create Feature from added layer" + copyfeaturefromexternallayer: "Créer une fonctionnalité à partir d'une couche ajoutée", + addhole: "Ajouter un trou", + deletehole: "Supprimer le trou" }, toolsoftool: { measure: "Show measure", diff --git a/config/i18n/it.js b/config/i18n/it.js index 5bba5109..a3dc3457 100644 --- a/config/i18n/it.js +++ b/config/i18n/it.js @@ -38,7 +38,9 @@ export default { update_vertex: "Aggiorna vertici feature", update_feature: "Modifica attributi feature", update_multi_features: "Modifica gli attributi delle features selezionate", - copyfeaturefromexternallayer: "Crea feature dal layer aggiunto" + copyfeaturefromexternallayer: "Crea feature dal layer aggiunto", + addhole: "Aggiungi buco", + deletehole: "Rimuovi buco" }, toolsoftool: { measure: "Visualizza misura", diff --git a/config/i18n/ro.js b/config/i18n/ro.js index 2bb9ce62..97078d75 100644 --- a/config/i18n/ro.js +++ b/config/i18n/ro.js @@ -38,7 +38,9 @@ export default { update_vertex: "Actualizează vertecșii entității", update_feature: "Actualizează atributul entității", update_multi_features: "Actualizează atributele entităților selectate", - copyfeaturefromexternallayer: "Create Feature from added layer" + copyfeaturefromexternallayer: "Creați caracteristică din stratul adăugat", + addhole: "Adăugați gaura", + deletehole: "Scoateți gaura" }, toolsoftool: { measure: "Arată măsurătorile", diff --git a/config/i18n/se.js b/config/i18n/se.js index 2e3824e7..379bfdaa 100644 --- a/config/i18n/se.js +++ b/config/i18n/se.js @@ -38,7 +38,9 @@ export default { update_vertex: "Uppdatera punktens egenskap", update_feature: "Uppdatera egenskap", update_multi_features: "Ändra attributen för de valda funktionerna", - copyfeaturefromexternallayer: "Create Feature from added layer" + copyfeaturefromexternallayer: "Skapa funktion från tillagt lager", + addhole: "Lägg till hål", + deletehole: "Ta bort hålet" }, toolsoftool: { measure: "Show measure", diff --git a/icons/addRing.png b/icons/addRing.png new file mode 100644 index 00000000..790763e1 Binary files /dev/null and b/icons/addRing.png differ diff --git a/icons/deleteRing.png b/icons/deleteRing.png new file mode 100644 index 00000000..977b239a Binary files /dev/null and b/icons/deleteRing.png differ diff --git a/interactions/pickholesinteraction.js b/interactions/pickholesinteraction.js new file mode 100644 index 00000000..e893b1e2 --- /dev/null +++ b/interactions/pickholesinteraction.js @@ -0,0 +1,169 @@ +/** + * @since g3w-client-plugin-editing@v3.7.0 + */ +import { extractHolesFromPolygonGeometry } from '../utils/extractHolesFromPolygonGeometry'; + +const { Geometry } = g3wsdk.core.geometry; + +const PickHolesEventType = { + PICKED: 'picked' +}; + +const PickHolesEvent = function(type, coordinate, layer, features) { + this.type = type; + this.features = features; + this.coordinate = coordinate; + this.layer = layer; +}; + +export const PickHolesInteraction = function(options={}) { + + ol.interaction.Pointer.call(this, { + handleDownEvent: PickHolesInteraction.handleDownEvent_, + handleUpEvent: PickHolesInteraction.handleUpEvent_, + handleMoveEvent: PickHolesInteraction.handleMoveEvent_ + }); + + this.map = null; + + const {layer, geometryType} = options; + + //vector editing layer + this.layer = layer; + + //store layer geometry type + this.geometryType = geometryType; + + this._holeLayer = new ol.layer.Vector({ + style: new ol.style.Style({ + fill: new ol.style.Fill({ + color: 'rgba(255,255,255,0)' //set trasparent hole feature + }) + }), + source: new ol.source.Vector() + }) + + this.layer + .getSource() + .getFeatures() + .forEach( feature => this.addHoleFeature(feature)); + + //listen add feature due move map and get new feature from server + this.unByKey = this.layer + .getSource() + .on('addfeature', ({feature}) => this.addHoleFeature(feature)); + + this.pickedHoles = []; //store information about get hole +}; + +ol.inherits(PickHolesInteraction, ol.interaction.Pointer); + +/** + * Event handler Down + * @param event + * @returns {*} + * @private + */ +PickHolesInteraction.handleDownEvent_ = function(event) { + this.pickedHoles = this.holesAtPixel(event); + this._holeLayer.getSource().clear(); + return this.pickedHoles; +}; + +/** + * Eevent handler Up + * @param event + * @returns {boolean} + * @private + */ +PickHolesInteraction.handleUpEvent_ = function(event) { + if (this.pickedHoles.length > 0) { + this.dispatchEvent( + new PickHolesEvent( + PickHolesEventType.PICKED, + event.coordinate, + this._holeLayer, + this.pickedHoles) + ); + } + return true; +}; + +/** + * Get a feature from layer and check if it has hole/holes + * and add to this._holeLayer + * @param feature + */ +PickHolesInteraction.prototype.addHoleFeature = function(feature) { + const featureGeometry = feature.getGeometry(); + const id = feature.getId(); + //check if is multi geometry (MultiPolygon) + if (Geometry.isMultiGeometry(this.geometryType)) { + featureGeometry + .getPolygons() + .forEach((geometry, index) => { + extractHolesFromPolygonGeometry({ + geometry, + id, + index + }) + .forEach(hf => this._holeLayer.getSource().addFeature(hf)) + }) + } else { + //Polygon geometry + extractHolesFromPolygonGeometry({ + geometry:featureGeometry, + id, + index: 0 //just one polygon + }) + .forEach(hf => this._holeLayer.getSource().addFeature(hf)) + } +} + +/** + * Check if pointer is over hole + * @param pixel + * @param map + * @returns {*} + */ +PickHolesInteraction.prototype.holesAtPixel = function({pixel, map}={}) { + return map.getFeaturesAtPixel(pixel, { + layerFilter: layer => layer === this._holeLayer, + hitTolerance: (isMobile && isMobile.any) ? 10 : 0 + }); +}; + +/** + * Event handler move pointer + * @param event + * @private + */ +PickHolesInteraction.handleMoveEvent_ = function(event) { + const intersectingHoles = this.holesAtPixel(event); + event.map.getTargetElement().style.cursor = intersectingHoles ? 'pointer': ''; +}; + +PickHolesInteraction.prototype.shouldStopEvent = function() { + return false; +}; + +/** + * Handle when interaction it adds or remove from map + * @param map + */ +PickHolesInteraction.prototype.setMap = function(map) { + if (map) { + //case of add interaction to map + this.map = map; + map.addLayer(this._holeLayer); + ol.interaction.Pointer.prototype.setMap.call(this, map); + } else { + //case of remove interaction + const elem = this.getMap().getTargetElement(); + elem.style.cursor = ''; + this.map.removeLayer(this._holeLayer); + this.map = null; + ol.Observable.unByKey(this.unByKey); + this.unByKey = null; + } +}; diff --git a/toolboxes/toolsfactory.js b/toolboxes/toolsfactory.js index a339c75f..a0d33be4 100644 --- a/toolboxes/toolsfactory.js +++ b/toolboxes/toolsfactory.js @@ -1,25 +1,29 @@ -const { Layer } = g3wsdk.core.layer; -const { Geometry } = g3wsdk.core.geometry; -const { GUI } = g3wsdk.gui; -const { - isSameBaseGeometryType, -} = g3wsdk.core.geoutils; -const Tool = require('./tool'); -const AddFeatureWorkflow = require('../workflows/addfeatureworkflow'); -const ModifyGeometryVertexWorkflow = require('../workflows/modifygeometryvertexworkflow'); -const MoveFeatureWorkflow = require('../workflows/movefeatureworkflow'); -const DeleteFeatureWorkflow = require('../workflows/deletefeatureworkflow'); -const EditFeatureAttributesWorkflow = require('../workflows/editfeatureattributesworkflow'); -const EditTableFeaturesWorkflow = require('../workflows/edittableworkflow'); -const AddTableFeatureWorflow = require('../workflows/addtablefeatureworkflow'); -const CopyFeaturesWorflow = require('../workflows/copyfeaturesworkflow'); -const SplitFeatureWorkflow = require('../workflows/splitfeatureworkflow'); -const MergeFeaturesWorkflow = require('../workflows/mergefeaturesworkflow'); -const AddPartToMultigeometriesWorkflow = require('../workflows/addparttomultigeometriesworkflow'); +const { Layer } = g3wsdk.core.layer; +const { Geometry } = g3wsdk.core.geometry; +const { GUI } = g3wsdk.gui; +const { isSameBaseGeometryType } = g3wsdk.core.geoutils; + +const Tool = require('./tool'); +const AddFeatureWorkflow = require('../workflows/addfeatureworkflow'); +const ModifyGeometryVertexWorkflow = require('../workflows/modifygeometryvertexworkflow'); +const MoveFeatureWorkflow = require('../workflows/movefeatureworkflow'); +const DeleteFeatureWorkflow = require('../workflows/deletefeatureworkflow'); +const EditFeatureAttributesWorkflow = require('../workflows/editfeatureattributesworkflow'); +const EditTableFeaturesWorkflow = require('../workflows/edittableworkflow'); +const AddTableFeatureWorflow = require('../workflows/addtablefeatureworkflow'); +const CopyFeaturesWorflow = require('../workflows/copyfeaturesworkflow'); +const SplitFeatureWorkflow = require('../workflows/splitfeatureworkflow'); +const MergeFeaturesWorkflow = require('../workflows/mergefeaturesworkflow'); +const AddPartToMultigeometriesWorkflow = require('../workflows/addparttomultigeometriesworkflow'); const DeletePartFromMultigeometriesWorkflow = require('../workflows/deletepartfrommultigeometriesworkflow'); -const EditMultiFeatureAttributesWorkflow = require('../workflows/editmultifeatureattributesworkflow'); -const AddFeatureFromMapVectorLayersWorflow = require('../workflows/addfeaturefrommapvectorlayersworkflow'); -const CopyFeaturesFromOtherLayerWorkflow = require('../workflows/copyfeaturesfromotherlayerworkflow'); +const EditMultiFeatureAttributesWorkflow = require('../workflows/editmultifeatureattributesworkflow'); +const AddFeatureFromMapVectorLayersWorflow = require('../workflows/addfeaturefrommapvectorlayersworkflow'); +const CopyFeaturesFromOtherLayerWorkflow = require('../workflows/copyfeaturesfromotherlayerworkflow'); +/** @since g3w-client-plugin-editing@v3.7.0 */ +const AddHoleWorflow = require('../workflows/addholeworkflow'); +/** @since g3w-client-plugin-editing@v3.7.0 */ +const DeleteHoleWorflow = require('../workflows/deleteholeworkflow'); + function EditorToolsFactory() { /** @@ -220,6 +224,31 @@ function EditorToolsFactory() { type: ['delete_feature'] } }, + //Only in case of Polygon/MultiPolygon geometry + ...('Polygon' === type ? [ + { + config: { + id: 'addhole', + name: "editing.tools.addhole", + icon: "addRing.png", + layer, + row: 2, + op: AddHoleWorflow, + type: ['change_feature'] + } + }, { + config: { + id: 'deletehole', + name: "editing.tools.deletehole", + icon: "deleteRing.png", + layer, + row: 2, + op: DeleteHoleWorflow, + type: ['change_feature'] + } + } + + ] : []), { config: { id: 'editmultiattributes', @@ -422,7 +451,8 @@ function EditorToolsFactory() { ]; break; } - return capabilities ? tools.filter(tool => tool.config.type.filter(type => capabilities.includes(type)).length > 0).map(tool => { + return capabilities ? + tools.filter(tool => tool.config.type.filter(type => capabilities.includes(type)).length > 0).map(tool => { // in case of capabilities all tools on line tool.config.row = 1; return new Tool(tool.config) diff --git a/utils/deleteHoleFromPolygonGeometry.js b/utils/deleteHoleFromPolygonGeometry.js new file mode 100644 index 00000000..f08085cd --- /dev/null +++ b/utils/deleteHoleFromPolygonGeometry.js @@ -0,0 +1,23 @@ +const { Geometry } = g3wsdk.core.geometry; +/** + * Util function to remove hole feature from polygon Geometry + * + * @param geometry //feature geometry + * @param index //hole index + * + * + * + * @since g3w-client-plugin-editing@3.7.0 + */ +export function deleteHoleFromPolygonGeometry({geometry, polygonIndex, holeIndex}={}) { + + const coordinates = geometry.getCoordinates(); + (Geometry.isMultiGeometry(geometry.getType()) ? + coordinates[polygonIndex] : + coordinates + ).splice(holeIndex, 1); + + geometry.setCoordinates(coordinates); + + return geometry; +} diff --git a/utils/extractHolesFromPolygonGeometry.js b/utils/extractHolesFromPolygonGeometry.js new file mode 100644 index 00000000..ff78027f --- /dev/null +++ b/utils/extractHolesFromPolygonGeometry.js @@ -0,0 +1,27 @@ +/** + * Util function to extract hole feature from polygon Geometry + * + * @param geometry + * @param id + * @param index + * + * @returns { Array } hole features + * + * @since g3w-client-plugin-editing@3.7.0 + */ +export function extractHolesFromPolygonGeometry({geometry, id, index}={}) { + const holesFeatures = []; + const linearRingCount = geometry.getLinearRingCount(); + if ( linearRingCount > 1) { + for (let i = 1; i < linearRingCount; i++) { + holesFeatures.push(new ol.Feature({ + geometry: new ol.geom.Polygon([geometry.getLinearRing(i).getCoordinates()]), //geometry of hole + holeIndex: i, // hole index, index of hole in feature geometry + polygonIndex: index, //in case of multipolygon index of polygon inside multipolygon + featureId: id, // id of belong feature + })); + } + } + return holesFeatures; +} + diff --git a/workflows/addholeworkflow.js b/workflows/addholeworkflow.js new file mode 100644 index 00000000..88e17aa5 --- /dev/null +++ b/workflows/addholeworkflow.js @@ -0,0 +1,14 @@ +const { base, inherit } = g3wsdk.core.utils; +const EditingWorkflow = require('./editingworkflow'); +const AddHoleStep = require('./steps/addholestep'); + +function AddHoleWorflow(options={}) { + options.steps = [ + new AddHoleStep(options) + ]; + base(this, options); +} + +inherit(AddHoleWorflow, EditingWorkflow); + +module.exports = AddHoleWorflow; \ No newline at end of file diff --git a/workflows/deleteholeworkflow.js b/workflows/deleteholeworkflow.js new file mode 100644 index 00000000..93c7bd8a --- /dev/null +++ b/workflows/deleteholeworkflow.js @@ -0,0 +1,17 @@ +const { base, inherit } = g3wsdk.core.utils; +const EditingWorkflow = require('./editingworkflow'); +const PickHoleStep = require('./steps/pickholestep'); +const ChooseFeatureStep = require('./steps/choosefeaturestep'); +const DeleteHoleStep = require('./steps/deleteholestep'); +function RemoveHoleWorflow(options={}) { + options.steps = [ + new PickHoleStep(options), + new ChooseFeatureStep(options), + new DeleteHoleStep(options) + ]; + base(this, options); +} + +inherit(RemoveHoleWorflow, EditingWorkflow); + +module.exports = RemoveHoleWorflow; \ No newline at end of file diff --git a/workflows/steps/addholestep.js b/workflows/steps/addholestep.js new file mode 100644 index 00000000..0d11500c --- /dev/null +++ b/workflows/steps/addholestep.js @@ -0,0 +1,12 @@ +const {base, inherit} = g3wsdk.core.utils; +const EditingStep = require('./editingstep'); +const AddHoleTask = require('./tasks/addholetask'); +const AddHoleStep = function(options={}) { + options.task = new AddHoleTask(options); + options.help = "editing.steps.help.create_hole"; + base(this, options) +}; + +inherit(AddHoleStep, EditingStep); + +module.exports = AddHoleStep; diff --git a/workflows/steps/choosefeaturestep.js b/workflows/steps/choosefeaturestep.js index b037cba8..c99a4684 100644 --- a/workflows/steps/choosefeaturestep.js +++ b/workflows/steps/choosefeaturestep.js @@ -1,4 +1,7 @@ -const {base, inherit} = g3wsdk.core.utils; +const { + base, + inherit +} = g3wsdk.core.utils; const { Step } = g3wsdk.core.workflow; const ChooseFeatureTask = require('./tasks/choosefeaturetask'); diff --git a/workflows/steps/deleteholestep.js b/workflows/steps/deleteholestep.js new file mode 100644 index 00000000..31349e86 --- /dev/null +++ b/workflows/steps/deleteholestep.js @@ -0,0 +1,12 @@ +const {base, inherit} = g3wsdk.core.utils; +const EditingStep = require('./editingstep'); +const RemoveHoleTask = require('./tasks/deleteholetask'); +const Deleteholestep = function(options={}) { + options.task = new RemoveHoleTask(options); + options.help = "editing.steps.help.create_hole"; + base(this, options) +}; + +inherit(Deleteholestep, EditingStep); + +module.exports = Deleteholestep; diff --git a/workflows/steps/pickfeaturestep.js b/workflows/steps/pickfeaturestep.js index a75c7649..4f4d585d 100644 --- a/workflows/steps/pickfeaturestep.js +++ b/workflows/steps/pickfeaturestep.js @@ -3,8 +3,7 @@ const { Step } = g3wsdk.core.workflow; const PickFeatureTask = require('./tasks/pickfeaturetask'); const PickFeatureStep = function(options={}) { - const task = new PickFeatureTask(options); - options.task = task ; + options.task = new PickFeatureTask(options) ; options.help = "editing.steps.help.pick_feature"; base(this, options) }; diff --git a/workflows/steps/pickholestep.js b/workflows/steps/pickholestep.js new file mode 100644 index 00000000..f2e920b5 --- /dev/null +++ b/workflows/steps/pickholestep.js @@ -0,0 +1,16 @@ +const { + base, + inherit +} = g3wsdk.core.utils; +const { Step } = g3wsdk.core.workflow; +const PickHoleTask = require('./tasks/pickholetask'); + +const PickHoleStep = function(options={}) { + options.task = new PickHoleTask(options) ; + options.help = "editing.steps.help.pick_hole"; + base(this, options) +}; + +inherit(PickHoleStep, Step); + +module.exports = PickHoleStep; diff --git a/workflows/steps/tasks/addholetask.js b/workflows/steps/tasks/addholetask.js new file mode 100644 index 00000000..1384b196 --- /dev/null +++ b/workflows/steps/tasks/addholetask.js @@ -0,0 +1,152 @@ +const {GUI} = g3wsdk.gui; +const {base, inherit} = g3wsdk.core.utils; +const { + within, + Geometry: { + isMultiGeometry, + is3DGeometry, + addZValueToOLFeatureGeometry + }, + coordinatesToGeometry +} = g3wsdk.core.geoutils; +const {Geometry} = g3wsdk.core.geometry; +const EditingTask = require('./editingtask'); + +function Addholetask(options={}) { + this.drawInteraction; + this.snapInteraction; + /** + * + * @param event + * @returns {boolean|void} + * @private + * callback of pressing esc to remove last point drawed + */ + this._delKeyRemoveLastPoint = event => event.keyCode === 46 && this.removeLastPoint(); + base(this, options); +} + +inherit(Addholetask, EditingTask); + +const proto = Addholetask.prototype; + +/** + * Method to create hole on polygon + * @param holeFeature + * @returns {{newFeature, originalFeature}} + */ +proto.createHole = function(holeFeature, editingLayerSource){ + // In case of MultiPolygon + let newFeature; + let originalFeature; + + if (isMultiGeometry(this.geometryType)) { + // cycle on each MultiPolygon feature of layer Multipolygon + editingLayerSource + .getFeatures() + .find((feature) => { + //feature is a multipolygon + //find single polygon of multipolygon that contain draw hole + const findPolygonIndex = feature + .getGeometry() + .getCoordinates() + .findIndex((singlePolygonCoordinates) => within(coordinatesToGeometry('Polygon', singlePolygonCoordinates), holeFeature.getGeometry())) + //if it finds + if (findPolygonIndex !== -1) { + originalFeature = feature.clone(); + newFeature = feature; + const coordinates = newFeature.getGeometry().getCoordinates(); + coordinates[findPolygonIndex].push(holeFeature.getGeometry().getCoordinates()[0]); + newFeature.getGeometry().setCoordinates(coordinates); + return true; + } + }); + } else { // In case of Polygon + newFeature = editingLayerSource.getFeatures().find(feature => { + return within(feature.getGeometry(), holeFeature.getGeometry()) + }); + + if ("undefined" !== typeof newFeature) { + originalFeature = newFeature.clone(); + //Get hole coordinates for polygon + const coordinates = newFeature.getGeometry().getCoordinates(); + coordinates.push(holeFeature.getGeometry().getCoordinates()[0]); + newFeature.getGeometry().setCoordinates(coordinates); + } + } + return { + newFeature, + originalFeature + } +} + +proto.run = function(inputs, context) { + const d = $.Deferred(); + const originalLayer = inputs.layer; + const session = context.session; + const layerId = originalLayer.getId(); + const originalGeometryType = originalLayer.getEditingGeometryType(); + this.geometryType = Geometry.getOLGeometry(originalGeometryType); + this.drawInteraction = new ol.interaction.Draw({ + type: 'Polygon', + source: new ol.source.Vector(), + freehandCondition: ol.events.condition.never, + }); + this.addInteraction(this.drawInteraction); + this.drawInteraction.setActive(true); + this.drawInteraction.on('drawstart', ({feature}) => { + this.drawingFeature = feature; + document.addEventListener('keydown', this._delKeyRemoveLastPoint); + }); + this.drawInteraction.on('drawend', (evt) => { + // IN CASE OF Z VALUE OF COORDINATE ADD Z VALUE TO COORDINATES OF DRAW POLYGON HOLE + if (is3DGeometry(this.geometryType)) { + evt.feature.setGeometry(addZValueToOLFeatureGeometry(evt.feature.getGeometry())) + } + const {newFeature, originalFeature} = this.createHole(evt.feature, originalLayer.getEditingLayer().getSource()); + + if ("undefined" !== typeof newFeature) { + session.pushUpdate(layerId, newFeature, originalFeature); + + inputs.features.push(newFeature); + + this.fireEvent('modify', newFeature); // emit event to get from subscribers + + d.resolve(inputs); + } else { + GUI.showUserMessage({ + type: 'warning', + message: 'No hole is created' //@TODO translation + }) + d.reject(); + } + }) + + this.snapInteraction = new ol.interaction.Snap({ + source: originalLayer.getEditingLayer().getSource() + }); + + this.addInteraction(this.snapInteraction); + return d.promise(); +}; + +proto.stop = function() { + this.removeInteraction(this.drawInteraction); + this.removeInteraction(this.snapInteraction); + this.drawInteraction = null; + document.removeEventListener('keydown', this._delKeyRemoveLastPoint); + return true; +}; + +proto.removeLastPoint = function() { + if (this.drawInteraction) { + try { + this.drawInteraction.removeLastPoint(); + } + catch (err) { + console.log(err) + } + } +}; + +module.exports = Addholetask; diff --git a/workflows/steps/tasks/deleteholetask.js b/workflows/steps/tasks/deleteholetask.js new file mode 100644 index 00000000..ac116d80 --- /dev/null +++ b/workflows/steps/tasks/deleteholetask.js @@ -0,0 +1,51 @@ +import { deleteHoleFromPolygonGeometry } from '../../../utils/deleteHoleFromPolygonGeometry'; + +const {base, inherit} = g3wsdk.core.utils; + +const EditingTask = require('./editingtask'); + +function DeleteHoleTask(options={}) { + /** + * @param event + * @returns {boolean|void} + * @private + */ + base(this, options); +} + +inherit(DeleteHoleTask, EditingTask); + +const proto = DeleteHoleTask.prototype; + +proto.run = function(inputs, context) { + const d = $.Deferred(); + const originalLayer = inputs.layer; + const session = context.session; + const layerId = originalLayer.getId(); + inputs.features.forEach(fh => { + const featureId = fh.get('featureId'); //get id of the feature that has a hole + const holeIndex = fh.get('holeIndex'); + const polygonIndex = fh.get('polygonIndex'); + //get feature + const feature = originalLayer.getEditingSource().getFeatureById(featureId); + //cole original feature + const originalFeature = feature.clone(); + //change geometry + feature.setGeometry(deleteHoleFromPolygonGeometry({ + geometry: feature.getGeometry(), + holeIndex, + polygonIndex, + })); + + session.pushUpdate(layerId, feature, originalFeature); + d.resolve(inputs); + }) + + return d.resolve(); +}; + +proto.stop = function() { + return true; +}; + +module.exports = DeleteHoleTask; diff --git a/workflows/steps/tasks/editingtask.js b/workflows/steps/tasks/editingtask.js index ecfae89f..4b25cfb3 100644 --- a/workflows/steps/tasks/editingtask.js +++ b/workflows/steps/tasks/editingtask.js @@ -753,15 +753,14 @@ proto.handleRelation1_1LayerFields = async function({ } /** - * @param { Object } opts - * @param opts.relation - * @param opts.fatherFormRelationField - * + * @param relation + * @param fatherFormRelationField + * * @returns {Promise<{feature: *, locked: boolean}>} - * - * @since g3w-client-plugin-editing@v3.7.0 - * + * * @private + * + * @since g3w-client-plugin-editing@v3.7.0 */ proto._getRelation1_1ChildFeature = async function({ relation, diff --git a/workflows/steps/tasks/modifygeometryvertextask.js b/workflows/steps/tasks/modifygeometryvertextask.js index 408b7fbd..8cd08f95 100644 --- a/workflows/steps/tasks/modifygeometryvertextask.js +++ b/workflows/steps/tasks/modifygeometryvertextask.js @@ -68,7 +68,7 @@ proto.run = function(inputs, context) { inputs, context, feature - }).finally(()=>{ + }).finally(() => { newFeature = feature.clone(); session.pushUpdate(layerId, newFeature, originalFeature); inputs.features.push(newFeature); diff --git a/workflows/steps/tasks/pickholetask.js b/workflows/steps/tasks/pickholetask.js new file mode 100644 index 00000000..f02403b1 --- /dev/null +++ b/workflows/steps/tasks/pickholetask.js @@ -0,0 +1,57 @@ +import { PickHolesInteraction } from '../../../interactions/pickholesinteraction'; +const { + base, + inherit +} = g3wsdk.core.utils; +const EditingTask = require('./editingtask'); + +function PickHoleTask(options={}) { + this.pickFeatureInteraction = null; + base(this, options); +} + +inherit(PickHoleTask, EditingTask); + +const proto = PickHoleTask.prototype; + +proto.run = function(inputs) { + + const d = $.Deferred(); + + //get OL editing layer + const editingLayer = inputs.layer.getEditingLayer(); + + this.pickFeatureInteraction = new PickHolesInteraction({ + layer: editingLayer, + geometryType: inputs.layer.getEditingGeometryType() + + }); + + this.addInteraction(this.pickFeatureInteraction); + + this.pickFeatureInteraction + .on('picked', evt => { + const {features, coordinate} = evt; + if (inputs.features.length === 0) { + inputs.features = features; + inputs.coordinate = coordinate; + } + this.setAndUnsetSelectedFeaturesStyle({promise: d}); + + if (this._steps) { + this.setUserMessageStepDone('select'); + } + + d.resolve(inputs); + }); + + return d.promise() +}; + +proto.stop = function() { + this.removeInteraction(this.pickFeatureInteraction); + this.pickFeatureInteraction = null; + return true; +}; + +module.exports = PickHoleTask;