def process(self): layer = self.iface.mapCanvas().currentLayer() newFeatures = [] if layer.selectedFeatureCount() == 1: editCommand = QtCore.QCoreApplication.translate( "editcommand", "Split feature") elif layer.selectedFeatureCount() > 1: editCommand = QtCore.QCoreApplication.translate( "editcommand", "Split features") for feature in layer.selectedFeatures(): geom = feature.geometry() # if feature geometry is multipart starts split processing if geom.isMultipart(): if len(newFeatures) == 0: layer.beginEditCommand(editCommand) # Get parts from original feature parts = geom.asGeometryCollection() # update feature geometry to hold first part single geometry # (this way one of the output feature keeps the original Id) feature.setGeometry(parts.pop(0)) layer.updateFeature(feature) # create new features from parts and add them to the list of newFeatures newFeatures = newFeatures + dtutils.dtMakeFeaturesFromGeometries( layer, feature, parts) # add new features to layer if len(newFeatures) > 0: layer.addFeatures(newFeatures, False) layer.endEditCommand()
def process(self): layer = self.iface.mapCanvas().currentLayer() newFeatures = [] if layer.selectedFeatureCount() == 1: editCommand = QtCore.QCoreApplication.translate("editcommand", "Split feature") elif layer.selectedFeatureCount() > 1: editCommand = QtCore.QCoreApplication.translate("editcommand", "Split features") for feature in layer.selectedFeatures(): geom = QgsGeometry(feature.geometry()) if not geom.isGeosValid(): thisWarning = dtutils.dtGetInvalidGeomWarning(layer) dtutils.dtShowWarning(self.iface, thisWarning) continue # if feature geometry is multipart starts split processing if geom.isMultipart(): if len(newFeatures) == 0: layer.beginEditCommand(editCommand) # Get parts from original feature parts = geom.asGeometryCollection () # update feature geometry to hold first part single geometry # (this way one of the output feature keeps the original Id) feature.setGeometry(parts.pop(0)) layer.updateFeature(feature) # create new features from parts and add them to the list of newFeatures newFeatures = newFeatures + dtutils.dtMakeFeaturesFromGeometries(layer, feature, parts) # add new features to layer if len(newFeatures) > 0: layer.addFeatures(newFeatures, False) layer.endEditCommand()
def run(self): layer = self.iface.mapCanvas().currentLayer() provider = layer.dataProvider() newFeatures = [] n_of_splitted_features = 0 layer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Split features")) for feature in layer.selectedFeatures(): geom = feature.geometry() # if feature geometry is multipart starts split processing if geom.isMultipart(): n_of_splitted_features += 1 # Get parts from original feature parts = geom.asGeometryCollection () # update feature geometry to hold first part single geometry # (this way one of the output feature keeps the original Id) feature.setGeometry(parts.pop(0)) layer.updateFeature(feature) # create new features from parts and add them to the list of newFeatures newFeatures = newFeatures + dtutils.dtMakeFeaturesFromGeometries(layer, feature, parts) # add new features to layer if len(newFeatures) > 0: layer.addFeatures(newFeatures, False) layer.endEditCommand() else: layer.destroyEditCommand()
def run(self): layer = self.iface.mapCanvas().currentLayer() provider = layer.dataProvider() newFeatures = [] n_of_splitted_features = 0 layer.beginEditCommand("Split features") for feature in layer.selectedFeatures(): geom = feature.geometry() # if feature geometry is multipart starts split processing if geom.isMultipart(): n_of_splitted_features += 1 # Get parts from original feature parts = geom.asGeometryCollection () # update feature geometry to hold first part single geometry # (this way one of the output feature keeps the original Id) feature.setGeometry(parts.pop(0)) layer.updateFeature(feature) # create new features from parts and add them to the list of newFeatures newFeatures = newFeatures + dtutils.dtMakeFeaturesFromGeometries(layer, feature, parts) # add new features to layer if len(newFeatures) > 0: layer.addFeatures(newFeatures, False) layer.endEditCommand() else: layer.destroyEditCommand()
def process(self): '''Function that does all the real work''' title = QtCore.QCoreApplication.translate("digitizingtools", "Splitter") splitterLayer = dtutils.dtChooseVectorLayer(self.iface, 1, msg = QtCore.QCoreApplication.translate("digitizingtools", "splitter layer")) if splitterLayer == None: self.iface.messageBar().pushMessage(title, QtCore.QCoreApplication.translate("digitizingtools", "Please provide a line layer to split with.")) else: passiveLayer = self.iface.activeLayer() msgLst = dtutils.dtGetNoSelMessage() noSelMsg1 = msgLst[0] if splitterLayer.selectedFeatureCount() == 0: self.iface.messageBar().pushMessage(title, noSelMsg1 + " " + splitterLayer.name()) return None elif splitterLayer.selectedFeatureCount() != 1: numSelSplitMsg = dtutils.dtGetManySelMessage(splitterLayer) self.iface.messageBar().pushMessage(title, numSelSplitMsg + \ QtCore.QCoreApplication.translate("digitizingtools", " Please select only one feature to split with.")) else: if passiveLayer.selectedFeatureCount() == 0: self.iface.messageBar().pushMessage(title, noSelMsg1 + " " + passiveLayer.name() + ".\n" + \ QtCore.QCoreApplication.translate("digitizingtools", " Please select the features to be splitted.")) return None # determine srs, we work in the project's srs splitterCRSSrsid = splitterLayer.crs().srsid() passiveCRSSrsid = passiveLayer.crs().srsid() mc = self.iface.mapCanvas() renderer = mc.mapRenderer() projectCRSSrsid = renderer.destinationCrs().srsid() passiveLayer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Split features")) featuresBeingSplit = 0 featuresToAdd = [] for feat in splitterLayer.selectedFeatures(): splitterGeom = QgsGeometry(feat.geometry()) if not splitterGeom.isGeosValid(): thisWarning = dtutils.dtGetInvalidGeomWarning(splitterLayer) dtutils.dtShowWarning(self.iface, thisWarning) continue if splitterCRSSrsid != projectCRSSrsid: splitterGeom.transform(QgsCoordinateTransform(splitterCRSSrsid, projectCRSSrsid)) for selFeat in passiveLayer.selectedFeatures(): selGeom = QgsGeometry(selFeat.geometry()) if not selGeom.isGeosValid(): thisWarning = dtutils.dtGetInvalidGeomWarning(passiveLayer) dtutils.dtShowWarning(self.iface, thisWarning) continue if passiveCRSSrsid != projectCRSSrsid: selGeom.transform(QgsCoordinateTransform(passiveCRSSrsid, projectCRSSrsid)) if splitterGeom.intersects(selGeom): # we have a candidate splitterPList = dtutils.dtExtractPoints(splitterGeom) try: result, newGeometries, topoTestPoints = selGeom.splitGeometry(splitterPList, False) #QgsProject.instance().topologicalEditing()) except: self.iface.messageBar().pushMessage(title, dtutils.dtGetErrorMessage() + QtCore.QCoreApplication.translate("digitizingtools", "splitting of feature") + " " + str(selFeat.id()), level=QgsMessageBar.CRITICAL) return None if result == 0: selFeat.setGeometry(selGeom) passiveLayer.updateFeature(selFeat) if len(newGeometries) > 0: featuresBeingSplit += 1 newFeatures = dtutils.dtMakeFeaturesFromGeometries(passiveLayer, selFeat, newGeometries) for newFeat in newFeatures: newGeom = QgsGeometry(newFeat.geometry()) if passiveCRSSrsid != projectCRSSrsid: newGeom.transform(QgsCoordinateTransform( projectCRSSrsid, passiveCRSSrsid)) newFeat.setGeometry(newGeom) featuresToAdd.append(newFeat) if featuresBeingSplit > 0: passiveLayer.addFeatures(featuresToAdd, False) passiveLayer.endEditCommand() passiveLayer.removeSelection() else: passiveLayer.destroyEditCommand()
def process(self): '''Function that does all the real work''' title = QtCore.QCoreApplication.translate("digitizingtools", "Splitter") splitterLayer = dtutils.dtChooseVectorLayer( self.iface, 1, msg=QtCore.QCoreApplication.translate("digitizingtools", "splitter layer")) if splitterLayer == None: self.iface.messageBar().pushMessage( title, QtCore.QCoreApplication.translate( "digitizingtools", "Please provide a line layer to split with.")) else: passiveLayer = self.iface.activeLayer() msgLst = dtutils.dtGetNoSelMessage() noSelMsg1 = msgLst[0] if splitterLayer.selectedFeatureCount() == 0: self.iface.messageBar().pushMessage( title, noSelMsg1 + " " + splitterLayer.name()) return None elif splitterLayer.selectedFeatureCount() != 1: numSelSplitMsg = dtutils.dtGetManySelMessage(splitterLayer) self.iface.messageBar().pushMessage(title, numSelSplitMsg + \ QtCore.QCoreApplication.translate("digitizingtools", " Please select only one feature to split with.")) else: if passiveLayer.selectedFeatureCount() == 0: self.iface.messageBar().pushMessage(title, noSelMsg1 + " " + passiveLayer.name() + ".\n" + \ QtCore.QCoreApplication.translate("digitizingtools", " Please select the features to be splitted.")) return None # determine srs, we work in the project's srs splitterCRSSrsid = splitterLayer.crs().srsid() passiveCRSSrsid = passiveLayer.crs().srsid() mc = self.iface.mapCanvas() renderer = mc.mapRenderer() projectCRSSrsid = renderer.destinationCrs().srsid() passiveLayer.beginEditCommand( QtCore.QCoreApplication.translate("editcommand", "Split features")) featuresBeingSplit = 0 featuresToAdd = [] for feat in splitterLayer.selectedFeatures(): splitterGeom = feat.geometry() if splitterCRSSrsid != projectCRSSrsid: splitterGeom.transform( QgsCoordinateTransform(splitterCRSSrsid, projectCRSSrsid)) for selFeat in passiveLayer.selectedFeatures(): selGeom = selFeat.geometry() if passiveCRSSrsid != projectCRSSrsid: selGeom.transform( QgsCoordinateTransform(passiveCRSSrsid, projectCRSSrsid)) if splitterGeom.intersects( selGeom): # we have a candidate splitterPList = dtutils.dtExtractPoints( splitterGeom) try: result, newGeometries, topoTestPoints = selGeom.splitGeometry( splitterPList, False ) #QgsProject.instance().topologicalEditing()) except: self.iface.messageBar().pushMessage( title, dtutils.dtGetErrorMessage() + QtCore.QCoreApplication.translate( "digitizingtools", "splitting of feature") + " " + str(selFeat.id()), level=QgsMessageBar.CRITICAL) return None if result == 0: selFeat.setGeometry(selGeom) passiveLayer.updateFeature(selFeat) if len(newGeometries) > 0: featuresBeingSplit += 1 newFeatures = dtutils.dtMakeFeaturesFromGeometries( passiveLayer, selFeat, newGeometries) for newFeat in newFeatures: newGeom = newFeat.geometry() if passiveCRSSrsid != projectCRSSrsid: newGeom.transform( QgsCoordinateTransform( projectCRSSrsid, passiveCRSSrsid)) newFeat.setGeometry(newGeom) featuresToAdd.append(newFeat) if featuresBeingSplit > 0: passiveLayer.addFeatures(featuresToAdd, False) passiveLayer.endEditCommand() passiveLayer.removeSelection() else: passiveLayer.destroyEditCommand()
def run(self): '''Function that does all the real work''' title = QtCore.QCoreApplication.translate("digitizingtools", "Splitter") splitterLayer = dtutils.dtChooseVectorLayer(self.iface, 1, msg = QtCore.QCoreApplication.translate("digitizingtools", "splitter layer")) if splitterLayer == None: QtGui.QMessageBox.information(None, title, QtCore.QCoreApplication.translate("digitizingtools", "Please provide a line layer to split with.")) else: passiveLayer = self.iface.activeLayer() msgLst = dtutils.dtGetNoSelMessage() noSelMsg1 = msgLst[0] noSelMsg2 = msgLst[1] if splitterLayer.selectedFeatureCount() == 0: reply = QtGui.QMessageBox.question(None, title, noSelMsg1 + " " + splitterLayer.name() + "\n" + noSelMsg2, QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel ) if reply == QtGui.QMessageBox.Yes: splitterLayer.invertSelection() else: return None if splitterLayer.selectedFeatureCount() > 0: if passiveLayer.selectedFeatureCount() == 0: QtGui.QMessageBox.information(None, title, noSelMsg1 + " " + passiveLayer.name() + ".\n" + \ QtCore.QCoreApplication.translate("digitizingtools", "Please select the features to be splitted.")) return None # determine srs, we work in the project's srs splitterCRSSrsid = splitterLayer.crs().srsid() passiveCRSSrsid = passiveLayer.crs().srsid() mc = self.iface.mapCanvas() renderer = mc.mapRenderer() projectCRSSrsid = renderer.destinationCrs().srsid() passiveLayer.beginEditCommand(QtCore.QCoreApplication.translate("digitizingtools", "Split Features")) featuresBeingSplit = 0 featuresToAdd = [] for feat in splitterLayer.selectedFeatures(): splitterGeom = feat.geometry() if splitterCRSSrsid != projectCRSSrsid: splitterGeom.transform(QgsCoordinateTransform(splitterCRSSrsid, projectCRSSrsid)) for selFeat in passiveLayer.selectedFeatures(): selGeom = selFeat.geometry() if passiveCRSSrsid != projectCRSSrsid: selGeom.transform(QgsCoordinateTransform(passiveCRSSrsid, projectCRSSrsid)) if splitterGeom.intersects(selGeom): # we have a candidate splitterPList = dtutils.dtExtractPoints(splitterGeom) try: result, newGeometries, topoTestPoints = selGeom.splitGeometry(splitterPList, False) #QgsProject.instance().topologicalEditing()) except: QtGui.QMessageBox.warning(None, title, dtutils.dtGetErrorMessage() + QtCore.QCoreApplication.translate("digitizingtools", "splitting of feature") + " " + str(selFeat.id())) return None if result == 0: selFeat.setGeometry(selGeom) passiveLayer.updateFeature(selFeat) if len(newGeometries) > 0: featuresBeingSplit += 1 newFeatures = dtutils.dtMakeFeaturesFromGeometries(passiveLayer, selFeat, newGeometries) for newFeat in newFeatures: newGeom = newFeat.geometry() if passiveCRSSrsid != projectCRSSrsid: newGeom.transform(QgsCoordinateTransform( projectCRSSrsid, passiveCRSSrsid)) newFeat.setGeometry(newGeom) featuresToAdd.append(newFeat) if featuresBeingSplit > 0: passiveLayer.addFeatures(featuresToAdd, False) passiveLayer.endEditCommand() passiveLayer.removeSelection() else: passiveLayer.destroyEditCommand()
def digitizingFinished(self, splitGeom): title = QtCore.QCoreApplication.translate("digitizingtools", "Split Features") hlColor, hlFillColor, hlBuffer, hlMinWidth = dtutils.dtGetHighlightSettings() selIds = self.editLayer.selectedFeatureIds() self.editLayer.removeSelection() if self.editLayer.crs().srsid() != QgsProject.instance().crs().srsid(): splitGeom.transform(QgsCoordinateTransform( QgsProject.instance().crs(), self.editLayer.crs(), QgsProject.instance() )) splitterPList = dtutils.dtExtractPoints(splitGeom) featuresToAdd = [] # store new features in this array featuresToKeep = {} # store geoms that will stay with their id as key featuresToSplit = {} topoGeoms = [] # store all new geometries in this array for aFeat in self.editLayer.getFeatures(QgsFeatureRequest(splitGeom.boundingBox())): anId = aFeat.id() # work either on selected or all features if no selection exists if len(selIds) == 0 or selIds.count(anId) != 0: aGeom = aFeat.geometry() if splitGeom.intersects(aGeom): featuresToSplit[anId] = aFeat if len(featuresToSplit) > 0: self.editLayer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Features split")) for anId, aFeat in list(featuresToSplit.items()): aGeom = aFeat.geometry() wasMultipart = aGeom.isMultipart() and len(aGeom.asGeometryCollection()) > 1 splitResult = [] geomsToSplit = [] if wasMultipart: keepGeom = None for aPart in aGeom.asGeometryCollection(): if splitGeom.intersects(aPart): geomsToSplit.append(aPart) else: if keepGeom == None: keepGeom = aPart else: keepGeom = keepGeom.combine(aPart) else: geomsToSplit.append(aGeom) for thisGeom in geomsToSplit: try: result, newGeometries, topoTestPoints = thisGeom.splitGeometry(splitterPList, False) except: self.iface.messageBar().pushCritical(title, dtutils.dtGetErrorMessage() + QtCore.QCoreApplication.translate( "digitizingtools", "splitting of feature") + " " + str(aFeat.id())) return None if result == 0: # success if len(newGeometries) > 0: splitResult = newGeometries if wasMultipart: splitResult.append(thisGeom) if wasMultipart and len(splitResult) > 1: takeThisOne = -1 while takeThisOne == -1: for i in range(len(splitResult)): aNewGeom = splitResult[i] hl = QgsHighlight(self.iface.mapCanvas(), aNewGeom, self.editLayer) hl.setColor(hlColor) hl.setFillColor(hlFillColor) hl.setBuffer(hlBuffer) hl.setWidth(hlMinWidth) answer = QtWidgets.QMessageBox.question( None, QtCore.QCoreApplication.translate("digitizingtools", "Split Multipart Feature"), QtCore.QCoreApplication.translate("digitizingtools", "Create new feature from this part?"), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Cancel | QtWidgets.QMessageBox.NoToAll) if answer == QtWidgets.QMessageBox.Yes: takeThisOne = i break elif answer == QtWidgets.QMessageBox.NoToAll: keepGeom = aGeom newGeoms = [] takeThisOne = -2 break elif answer == QtWidgets.QMessageBox.Cancel: self.editLayer.destroyEditCommand() return None if takeThisOne == -2: break elif takeThisOne >= 0: newGeoms = [splitResult.pop(takeThisOne)] if len(splitResult) > 0: #should be for aNewGeom in splitResult: if keepGeom == None: keepGeom = aNewGeom else: keepGeom = keepGeom.combine(aNewGeom) else: # singlePart keepGeom = thisGeom newGeoms = newGeometries newFeatures = dtutils.dtMakeFeaturesFromGeometries(self.editLayer, aFeat, newGeoms) featuresToAdd = featuresToAdd + newFeatures topoGeoms = topoGeoms + newGeoms aFeat.setGeometry(keepGeom) featuresToKeep[anId] = aFeat topoGeoms.append(keepGeom) for anId, aFeat in list(featuresToKeep.items()): aGeom = aFeat.geometry() self.editLayer.updateFeature(aFeat) if len(featuresToAdd) > 0: if self.editLayer.addFeatures(featuresToAdd): if QgsProject.instance().topologicalEditing(): for aGeom in topoGeoms: self.editLayer.addTopologicalPoints(aGeom) self.editLayer.endEditCommand() else: self.editLayer.destroyEditCommand() else: self.editLayer.destroyEditCommand() if hasattr(self.editLayer, "selectByIds"): # since QGIS 2.16 self.editLayer.selectByIds(selIds) else: self.editLayer.setSelectedFeatures(selIds)
def process(self): '''Function that does all the real work''' title = QtCore.QCoreApplication.translate("digitizingtools", "Cutter") showEmptyWarning = True choice = None fidsToDelete = [] passiveLayer = self.iface.activeLayer() dlg = DtChooseCutterLayer(self.iface, self.isPolygonLayer(passiveLayer), self.lastChoice) dlg.show() result = dlg.exec_() if result != 1: self.iface.messageBar().pushMessage(title, QtCore.QCoreApplication.translate("digitizingtools", "Please provide a polygon layer to cut with.")) else: cutterLayer = dlg.cutterLayer copyPoly = dlg.copyPoly self.lastChoice= [cutterLayer, copyPoly] isSameLayer = cutterLayer == self.iface.activeLayer() if cutterLayer.selectedFeatureCount() == 0: msgLst = dtutils.dtGetNoSelMessage() noSelMsg1 = msgLst[0] noSelMsg2 = msgLst[1] if isSameLayer: self.iface.messageBar().pushMessage(title, noSelMsg1 + " " + cutterLayer.name()) return None else: reply = QtWidgets.QMessageBox.question(None, title, noSelMsg1 + " " + cutterLayer.name() + "\n" + noSelMsg2, QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No ) if reply == QtWidgets.QMessageBox.Yes: cutterLayer.invertSelection() else: return None if passiveLayer.selectedFeatureCount() == 0: msgLst = dtutils.dtGetNoSelMessage() noSelMsg1 = msgLst[0] noSelMsg2 = msgLst[1] reply = QtWidgets.QMessageBox.question(None, title, noSelMsg1 + " " + passiveLayer.name() + "\n" + noSelMsg2, QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No ) if reply == QtWidgets.QMessageBox.Yes: passiveLayer.invertSelection() else: return None idsToProcess = [] for aFeat in passiveLayer.selectedFeatures(): idsToProcess.append(aFeat.id()) if cutterLayer.selectedFeatureCount() > 0: # determine srs, we work in the project's srs cutterCRSSrsid = cutterLayer.crs().srsid() passiveCRSSrsid = passiveLayer.crs().srsid() projectCRSSrsid = QgsProject.instance().crs().srsid() passiveLayer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Cut Features")) featuresBeingCut = 0 featuresToAdd = [] tmpCutterLayer = QgsVectorLayer("Polygon?crs=" + cutterLayer.crs().authid(),"cutter","memory") tmpCutterLayer.setCrs(cutterLayer.crs()) tmpCutterLayer.startEditing() noMatchWarning = dtutils.dtGetNotMatchingGeomWarning(passiveLayer) for feat in cutterLayer.selectedFeatures(): cutterGeom = QgsGeometry(feat.geometry()) if cutterGeom.wkbType() == 6: cutterGeom = QgsGeometry.fromMultiPolygonXY(cutterGeom.asMultiPolygon()) else: cutterGeom = QgsGeometry.fromPolygonXY(cutterGeom.asPolygon()) if not cutterGeom.isGeosValid(): thisWarning = dtutils.dtGetInvalidGeomWarning(cutterLayer) dtutils.dtShowWarning(self.iface, thisWarning) continue cutterFeat = QgsFeature() cutterFeat.setGeometry(cutterGeom) tmpCutterLayer.addFeature(cutterFeat) tmpCutterLayer.commitChanges() idsToProcess = [] if isSameLayer: for aFeat in passiveLayer.getFeatures(): idsToProcess.append(aFeat.id()) else: for aFeat in passiveLayer.selectedFeatures(): idsToProcess.append(aFeat.id()) #tmpCutterLayer.invertSelection() for feat in tmpCutterLayer.getFeatures(): cutterGeom = QgsGeometry(feat.geometry()) if cutterCRSSrsid != projectCRSSrsid: cutterGeom.transform(QgsCoordinateTransform( cutterLayer.crs(), QgsProject.instance().crs(), QgsProject.instance())) if passiveCRSSrsid != projectCRSSrsid: bboxGeom = QgsGeometry(cutterGeom) bboxGeom.transform(QgsCoordinateTransform( QgsProject.instance().crs(), passiveLayer.crs(), QgsProject.instance())) bbox = bboxGeom.boundingBox() else: bbox = cutterGeom.boundingBox() passiveLayer.selectByRect(bbox) # make a new selection for selFeat in passiveLayer.selectedFeatures(): if idsToProcess.count(selFeat.id()) == 0: continue selGeom = QgsGeometry(selFeat.geometry()) if isSameLayer: if selGeom.isGeosEqual(cutterGeom): continue # do not cut the same geometry if not selGeom.isGeosValid(): thisWarning = dtutils.dtGetInvalidGeomWarning(passiveLayer) dtutils.dtShowWarning(self.iface, thisWarning) continue if passiveCRSSrsid != projectCRSSrsid: selGeom.transform(QgsCoordinateTransform( passiveLayer.crs(), QgsProject.instance().crs(), QgsProject.instance() )) if cutterGeom.intersects(selGeom): # we have a candidate newGeom = selGeom.difference(cutterGeom) if newGeom != None: if newGeom.isEmpty(): #selGeom is completely contained in cutterGeom if showEmptyWarning: choice = QtWidgets.QMessageBox.question(None, title, QtCore.QCoreApplication.translate("digitizingtools", "A feature would be completely removed by cutting. Delete this feature\'s dataset altogether?"), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.YesToAll | QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.NoToAll | QtWidgets.QMessageBox.Cancel) if choice == QtWidgets.QMessageBox.Cancel: passiveLayer.destroyEditCommand() return None else: showEmptyWarning = (choice == QtWidgets.QMessageBox.Yes or choice == QtWidgets.QMessageBox.No) if choice == QtWidgets.QMessageBox.Yes or choice == QtWidgets.QMessageBox.YesToAll: fidsToDelete.append(selFeat.id()) else: if passiveCRSSrsid != projectCRSSrsid: newGeom.transform(QgsCoordinateTransform( QgsProject.instance().crs(), passiveLayer.crs(), QgsProject.instance() )) if not self.geometryTypeMatchesLayer(passiveLayer, newGeom): newMsg = QtCore.QCoreApplication.translate( "digitizingtools", "New geometry") dtutils.dtShowWarning(self.iface, newMsg + ": " + noMatchWarning) selFeat.setGeometry(newGeom) passiveLayer.updateFeature(selFeat) featuresBeingCut += 1 if copyPoly: copyGeom = selGeom.intersection(cutterGeom) if copyGeom != None: if not copyGeom.isEmpty(): if passiveCRSSrsid != projectCRSSrsid: copyGeom.transform(QgsCoordinateTransform( QgsProject.instance().crs(), passiveLayer.crs(), QgsProject.instance())) if not self.geometryTypeMatchesLayer(passiveLayer, copyGeom): copyMsg = QtCore.QCoreApplication.translate( "digitizingtools", "Added geometry") dtutils.dtShowWarning(self.iface, copyMsg + ": " + noMatchWarning) newFeatures = dtutils.dtMakeFeaturesFromGeometries(\ passiveLayer, selFeat, [copyGeom]) for newFeat in newFeatures: featuresToAdd.append(newFeat) if featuresBeingCut > 0: if copyPoly: if passiveLayer.addFeatures(featuresToAdd): passiveLayer.endEditCommand() else: passiveLayer.destroyEditCommand() else: passiveLayer.endEditCommand() else: passiveLayer.destroyEditCommand() passiveLayer.removeSelection() if len(fidsToDelete) > 0: passiveLayer.beginEditCommand(QtCore.QCoreApplication.translate(\ "editcommand", "Delete Features")) for fid in fidsToDelete: if not passiveLayer.deleteFeature(fid): passiveLayer.destroyEditCommand() return None passiveLayer.endEditCommand() self.iface.mapCanvas().refresh()
def digitizingFinished(self, splitGeom): title = QtCore.QCoreApplication.translate("digitizingtools", "Split Features") hlColor, hlFillColor, hlBuffer, hlMinWidth = dtutils.dtGetHighlightSettings( ) selIds = self.editLayer.selectedFeatureIds() self.editLayer.removeSelection() if self.editLayer.crs().srsid() != QgsProject.instance().crs().srsid(): splitGeom.transform( QgsCoordinateTransform(QgsProject.instance().crs(), self.editLayer.crs(), QgsProject.instance())) splitterPList = dtutils.dtExtractPoints(splitGeom) featuresToAdd = [] # store new features in this array featuresToKeep = {} # store geoms that will stay with their id as key featuresToSplit = {} topoEditEnabled = QgsProject.instance().topologicalEditing() topoTestPointsAll = [] # store all topoTestPoints for all parts for aFeat in self.editLayer.getFeatures( QgsFeatureRequest(splitGeom.boundingBox())): anId = aFeat.id() # work either on selected or all features if no selection exists if len(selIds) == 0 or selIds.count(anId) != 0: aGeom = aFeat.geometry() if splitGeom.intersects(aGeom): featuresToSplit[anId] = aFeat if len(featuresToSplit) > 0: self.editLayer.beginEditCommand( QtCore.QCoreApplication.translate("editcommand", "Features split")) for anId, aFeat in list(featuresToSplit.items()): aGeom = aFeat.geometry() wasMultipart = aGeom.isMultipart() and len( aGeom.asGeometryCollection()) > 1 splitResult = [] geomsToSplit = [] if wasMultipart: keepGeom = None for aPart in aGeom.asGeometryCollection(): if splitGeom.intersects(aPart): geomsToSplit.append(aPart) else: if keepGeom == None: keepGeom = aPart else: keepGeom = keepGeom.combine(aPart) else: geomsToSplit.append(aGeom) for thisGeom in geomsToSplit: try: result, newGeometries, topoTestPoints = thisGeom.splitGeometry( splitterPList, topoEditEnabled) except: self.iface.messageBar().pushCritical( title, dtutils.dtGetErrorMessage() + QtCore.QCoreApplication.translate( "digitizingtools", "splitting of feature") + " " + str(aFeat.id())) return None topoTestPointsAll.append(topoTestPoints) if result == 0: # success if len(newGeometries) > 0: splitResult = newGeometries if wasMultipart: splitResult.append(thisGeom) if wasMultipart and len(splitResult) > 1: takeThisOne = -1 while takeThisOne == -1: for i in range(len(splitResult)): aNewGeom = splitResult[i] hl = QgsHighlight(self.iface.mapCanvas(), aNewGeom, self.editLayer) hl.setColor(hlColor) hl.setFillColor(hlFillColor) hl.setBuffer(hlBuffer) hl.setWidth(hlMinWidth) hl.show() answer = QtWidgets.QMessageBox.question( None, QtCore.QCoreApplication.translate( "digitizingtools", "Split Multipart Feature"), QtCore.QCoreApplication.translate( "digitizingtools", "Create new feature from this part?"), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Cancel | QtWidgets.QMessageBox.NoToAll) hl.hide() hl = None if answer == QtWidgets.QMessageBox.Yes: takeThisOne = i break elif answer == QtWidgets.QMessageBox.NoToAll: keepGeom = aGeom newGeoms = [] takeThisOne = -2 break elif answer == QtWidgets.QMessageBox.Cancel: self.editLayer.destroyEditCommand() return None if takeThisOne == -2: break elif takeThisOne >= 0: newGeoms = [splitResult.pop(takeThisOne)] if len(splitResult) > 0: #should be for aNewGeom in splitResult: if keepGeom == None: keepGeom = aNewGeom else: keepGeom = keepGeom.combine(aNewGeom) else: # singlePart keepGeom = thisGeom newGeoms = newGeometries newFeatures = dtutils.dtMakeFeaturesFromGeometries( self.editLayer, aFeat, newGeoms) featuresToAdd = featuresToAdd + newFeatures aFeat.setGeometry(keepGeom) featuresToKeep[anId] = aFeat for anId, aFeat in list(featuresToKeep.items()): aGeom = aFeat.geometry() self.editLayer.updateFeature(aFeat) if len(featuresToAdd) > 0: if self.editLayer.addFeatures(featuresToAdd): for topoTestPoint in topoTestPointsAll: for pt in topoTestPoint: self.editLayer.addTopologicalPoints(pt) self.editLayer.endEditCommand() else: self.editLayer.destroyEditCommand() else: self.editLayer.destroyEditCommand() if hasattr(self.editLayer, "selectByIds"): # since QGIS 2.16 self.editLayer.selectByIds(selIds) else: self.editLayer.setSelectedFeatures(selIds)