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 process(self): layer = self.iface.activeLayer() layer.featureAdded.connect(self.featureAdded) numRingsFilled = 0 aborted = False for featureToFill in layer.selectedFeatures(): geom = QgsGeometry(featureToFill.geometry()) if not geom.isGeosValid(): thisWarning = dtutils.dtGetInvalidGeomWarning(layer) dtutils.dtShowWarning(self.iface, thisWarning) continue rings = dtutils.dtExtractRings(geom) for aRing in rings: if numRingsFilled == 0: defaultAttributeMap = dtutils.dtGetDefaultAttributeMap( layer) layer.beginEditCommand( QtCore.QCoreApplication.translate( "editcommand", "Fill rings")) if self.iface.vectorLayerTools().addFeature( layer, defaultValues=defaultAttributeMap, defaultGeometry=aRing): layer.featureAdded.disconnect(self.featureAdded) else: layer.featureAdded.disconnect(self.featureAdded) layer.destroyEditCommand() aborted = True break else: aFeat = dtutils.dtCopyFeature(layer, srcFid=self.newFid) aFeat.setGeometry(aRing) layer.addFeature(aFeat) numRingsFilled += 1 if aborted: break layer.endEditCommand() self.canvas.refresh()
def process(self): layer = self.iface.activeLayer() layer.featureAdded.connect(self.featureAdded) numRingsFilled = 0 aborted = False for featureToFill in layer.selectedFeatures(): geom = QgsGeometry(featureToFill.geometry()) if not geom.isGeosValid(): thisWarning = dtutils.dtGetInvalidGeomWarning(layer) dtutils.dtShowWarning(self.iface, thisWarning) continue rings = dtutils.dtExtractRings(geom) for aRing in rings: if numRingsFilled == 0: defaultAttributeMap = dtutils.dtGetDefaultAttributeMap(layer) layer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Fill rings")) if self.iface.vectorLayerTools().addFeature(layer, defaultValues = defaultAttributeMap, defaultGeometry = aRing): layer.featureAdded.disconnect(self.featureAdded) else: layer.featureAdded.disconnect(self.featureAdded) layer.destroyEditCommand() aborted = True break else: aFeat = dtutils.dtCopyFeature(layer, srcFid = self.newFid) aFeat.setGeometry(aRing) layer.addFeature(aFeat) numRingsFilled += 1 if aborted: break layer.endEditCommand() self.canvas.refresh()
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) layer.endEditCommand()
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", "Clipper") processLayer = self.iface.activeLayer() msgLst = dtutils.dtGetNoSelMessage() noSelMsg1 = msgLst[0] if processLayer.selectedFeatureCount() == 0: self.iface.messageBar().pushMessage( title, noSelMsg1 + " " + processLayer.name()) return None else: clipperGeoms = [] for feat in processLayer.selectedFeatures(): clipperGeom = feat.geometry() if not clipperGeom.isGeosValid(): thisWarning = dtutils.dtGetInvalidGeomWarning(processLayer) dtutils.dtShowWarning(self.iface, thisWarning) continue else: clipperGeoms.append(clipperGeom) if len(clipperGeoms) == 0: return None # could be only invalid geoms selected processLayer.invertSelection() idsToProcess = [] processLayer.beginEditCommand( QtCore.QCoreApplication.translate( "editcommand", "Clip Features" )) featuresBeingClipped = 0 for aFeat in processLayer.selectedFeatures(): idsToProcess.append(aFeat.id()) for clipperGeom in clipperGeoms: bbox = clipperGeom.boundingBox() processLayer.selectByRect(bbox) # make a new selection for selFeat in processLayer.selectedFeatures(): if idsToProcess.count(selFeat.id()) == 0: continue selGeom = selFeat.geometry() if not selGeom.isGeosValid(): thisWarning = dtutils.dtGetInvalidGeomWarning(processLayer) dtutils.dtShowWarning(self.iface, thisWarning) continue if clipperGeom.intersects(selGeom): # we have a candidate newGeom = selGeom.intersection(clipperGeom) if newGeom != None: if not newGeom.isEmpty(): if newGeom.area() > 0: selFeat.setGeometry(newGeom) processLayer.updateFeature(selFeat) featuresBeingClipped += 1 processLayer.removeSelection() self.iface.mapCanvas().refresh() if featuresBeingClipped == 0: processLayer.destroyEditCommand() else: processLayer.endEditCommand()
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 process(self): '''Function that does all the real work''' title = QtCore.QCoreApplication.translate( "digitizingtools", "Clipper") clipperLayer = dtutils.dtChooseVectorLayer( self.iface, 2, msg = QtCore.QCoreApplication.translate( "digitizingtools", "clipper layer" )) if clipperLayer == None: self.iface.messageBar().pushMessage( title, QtCore.QCoreApplication.translate( "digitizingtools", "Please provide a polygon layer to clip with." )) else: passiveLayer = self.iface.activeLayer() msgLst = dtutils.dtGetNoSelMessage() noSelMsg1 = msgLst[0] noSelMsg2 = msgLst[1] if clipperLayer.selectedFeatureCount() == 0: self.iface.messageBar().pushMessage( title, noSelMsg1 + " " + clipperLayer.name()) return None elif clipperLayer.selectedFeatureCount() != 1: numSelSplitMsg = dtutils.dtGetManySelMessage(clipperLayer) self.iface.messageBar().pushMessage(title, numSelSplitMsg + \ QtCore.QCoreApplication.translate( "digitizingtools", " Please select only one feature to clip with." )) else: if passiveLayer.selectedFeatureCount() == 0: msgLst = dtutils.dtGetNoSelMessage() noSelMsg1 = msgLst[0] noSelMsg2 = msgLst[1] reply = QtGui.QMessageBox.question(None, title, noSelMsg1 + " " + passiveLayer.name() + "\n" + noSelMsg2, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No ) if reply == QtGui.QMessageBox.Yes: passiveLayer.invertSelection() else: return None idsToProcess = [] for aFeat in passiveLayer.selectedFeatures(): idsToProcess.append(aFeat.id()) if clipperLayer.selectedFeatureCount() > 0: # determine srs, we work in the project's srs clipperCRSSrsid = clipperLayer.crs().srsid() passiveCRSSrsid = passiveLayer.crs().srsid() mc = self.iface.mapCanvas() renderer = mc.mapRenderer() projectCRSSrsid = renderer.destinationCrs().srsid() passiveLayer.beginEditCommand( QtCore.QCoreApplication.translate( "editcommand", "Clip Features" )) featuresBeingClipped = 0 for feat in clipperLayer.selectedFeatures(): clipperGeom = QgsGeometry(feat.geometry()) if not clipperGeom.isGeosValid(): thisWarning = dtutils.dtGetInvalidGeomWarning(clipperLayer) dtutils.dtShowWarning(self.iface, thisWarning) continue if clipperCRSSrsid != projectCRSSrsid: clipperGeom.transform(QgsCoordinateTransform( clipperCRSSrsid, projectCRSSrsid )) bbox = clipperGeom.boundingBox() passiveLayer.select(bbox, False) # make a new selection for selFeat in passiveLayer.selectedFeatures(): if idsToProcess.count(selFeat.id()) == 0: continue 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 clipperGeom.intersects(selGeom): # we have a candidate newGeom = selGeom.intersection(clipperGeom) if newGeom != None: if not newGeom.isGeosEmpty(): if passiveCRSSrsid != projectCRSSrsid: newGeom.transform(QgsCoordinateTransform( projectCRSSrsid, passiveCRSSrsid)) selFeat.setGeometry(newGeom) passiveLayer.updateFeature(selFeat) featuresBeingClipped += 1 if featuresBeingClipped == 0: passiveLayer.destroyEditCommand() else: passiveLayer.endEditCommand() passiveLayer.removeSelection() self.iface.mapCanvas().refresh()
def process(self): '''Function that does all the real work''' title = QtCore.QCoreApplication.translate("digitizingtools", "Cutter") showEmptyWarning = True choice = None fidsToDelete = [] cutterLayer = dtutils.dtChooseVectorLayer(self.iface, 2, msg = QtCore.QCoreApplication.translate("digitizingtools", "cutter layer")) if cutterLayer == None: self.iface.messageBar().pushMessage(title, QtCore.QCoreApplication.translate("digitizingtools", "Please provide a polygon layer to cut with.")) else: passiveLayer = self.iface.activeLayer() if cutterLayer.selectedFeatureCount() == 0: msgLst = dtutils.dtGetNoSelMessage() noSelMsg1 = msgLst[0] noSelMsg2 = msgLst[1] reply = QtGui.QMessageBox.question(None, title, noSelMsg1 + " " + cutterLayer.name() + "\n" + noSelMsg2, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No ) if reply == QtGui.QMessageBox.Yes: cutterLayer.invertSelection() else: return None if passiveLayer.selectedFeatureCount() == 0: msgLst = dtutils.dtGetNoSelMessage() noSelMsg1 = msgLst[0] noSelMsg2 = msgLst[1] reply = QtGui.QMessageBox.question(None, title, noSelMsg1 + " " + passiveLayer.name() + "\n" + noSelMsg2, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No ) if reply == QtGui.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() mc = self.iface.mapCanvas() renderer = mc.mapRenderer() projectCRSSrsid = renderer.destinationCrs().srsid() passiveLayer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Cut Features")) featuresBeingCut = 0 for feat in cutterLayer.selectedFeatures(): cutterGeom = QgsGeometry(feat.geometry()) if not cutterGeom.isGeosValid(): thisWarning = dtutils.dtGetInvalidGeomWarning(cutterLayer) dtutils.dtShowWarning(self.iface, thisWarning) continue if cutterCRSSrsid != projectCRSSrsid: cutterGeom.transform(QgsCoordinateTransform(cutterCRSSrsid, projectCRSSrsid)) bbox = cutterGeom.boundingBox() passiveLayer.select(bbox, False) # make a new selection for selFeat in passiveLayer.selectedFeatures(): if idsToProcess.count(selFeat.id()) == 0: continue 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 cutterGeom.intersects(selGeom): # we have a candidate newGeom = selGeom.difference(cutterGeom) if newGeom != None: if newGeom.isGeosEmpty(): #selGeom is completely contained in cutterGeom if showEmptyWarning: choice = QtGui.QMessageBox.question(None, title, QtCore.QCoreApplication.translate("digitizingtools", "A feature would be completely removed by cutting. Delete this feature\'s dataset altogether?"), QtGui.QMessageBox.Yes | QtGui.QMessageBox.YesToAll | QtGui.QMessageBox.No | QtGui.QMessageBox.NoToAll | QtGui.QMessageBox.Cancel) if choice == QtGui.QMessageBox.Cancel: passiveLayer.destroyEditCommand() return None else: showEmptyWarning = (choice == QtGui.QMessageBox.Yes or choice == QtGui.QMessageBox.No) if choice == QtGui.QMessageBox.Yes or choice == QtGui.QMessageBox.YesToAll: fidsToDelete.append(selFeat.id()) else: if passiveCRSSrsid != projectCRSSrsid: newGeom.transform(QgsCoordinateTransform( projectCRSSrsid, passiveCRSSrsid)) selFeat.setGeometry(newGeom) passiveLayer.updateFeature(selFeat) #if passiveLayer.changeGeometry(selFeat.id(), newGeom): featuresBeingCut += 1 if featuresBeingCut > 0: 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 process(self): '''Function that does all the real work''' title = QtCore.QCoreApplication.translate("digitizingtools", "Cutter") showEmptyWarning = True choice = None fidsToDelete = [] processLayer = self.iface.activeLayer() if processLayer.selectedFeatureCount() == 0: msgLst = dtutils.dtGetNoSelMessage() noSelMsg1 = msgLst[0] noSelMsg2 = msgLst[1] else: cutterGeoms = [] for feat in processLayer.selectedFeatures(): cutterGeom = feat.geometry() if not cutterGeom.isGeosValid(): thisWarning = dtutils.dtGetInvalidGeomWarning(processLayer) dtutils.dtShowWarning(self.iface, thisWarning) continue else: cutterGeoms.append(cutterGeom) if len(cutterGeoms) == 0: return None # could be only invalid geoms selected processLayer.invertSelection() idsToProcess = [] for aFeat in processLayer.selectedFeatures(): # was: if isSameLayer: # for aFeat in processLayer.getFeatures() idsToProcess.append(aFeat.id()) processLayer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Cut Features")) featuresBeingCut = 0 noMatchWarning = dtutils.dtGetNotMatchingGeomWarning(processLayer) for cutterGeom in cutterGeoms: if cutterGeom.wkbType() == 6: cutterGeom = QgsGeometry.fromMultiPolygonXY(cutterGeom.asMultiPolygon()) else: cutterGeom = QgsGeometry.fromPolygonXY(cutterGeom.asPolygon()) bbox = cutterGeom.boundingBox() processLayer.selectByRect(bbox) # make a new selection for selFeat in processLayer.selectedFeatures(): if idsToProcess.count(selFeat.id()) == 0: continue selGeom = selFeat.geometry() if selGeom.isGeosEqual(cutterGeom): continue # do not cut the same geometry if not selGeom.isGeosValid(): thisWarning = dtutils.dtGetInvalidGeomWarning(processLayer) dtutils.dtShowWarning(self.iface, thisWarning) continue if cutterGeom.intersects(selGeom): # we have a candidate newGeom = selGeom.difference(cutterGeom) if newGeom != None: if newGeom.isEmpty() or newGeom.area() == 0: #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: processLayer.destroyEditCommand() processLayer.removeSelection() 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 not self.geometryTypeMatchesLayer(processLayer, newGeom): newMsg = QtCore.QCoreApplication.translate( "digitizingtools", "New geometry") dtutils.dtShowWarning(self.iface, newMsg + ": " + noMatchWarning) selFeat.setGeometry(newGeom) processLayer.updateFeature(selFeat) featuresBeingCut += 1 if len(fidsToDelete) > 0: for fid in fidsToDelete: if not processLayer.deleteFeature(fid): processLayer.destroyEditCommand() return None if featuresBeingCut > 0 or len(fidsToDelete) > 0: processLayer.endEditCommand() else: # nothing happened processLayer.destroyEditCommand() processLayer.removeSelection() self.iface.mapCanvas().refresh()