def run(self): '''Function that does all the real work''' self.title = QtCore.QCoreApplication.translate("digitizingtools", "Fill gap") self.canvas.setMapTool(self.tool) layer = self.iface.activeLayer() self.doIgnoreTool = True try: self.tool.vertexFound.disconnect(self.vertexSnapped) # disconnect if it was already connectedd, so slot gets called only once! except: pass self.tool.vertexFound.connect(self.vertexSnapped) self.act_fillGap.setChecked(True) if layer.selectedFeatureCount() == 0: QtGui.QMessageBox.information(None, self.title, dtutils.dtGetNoSelMessage()[0] + " " + layer.name() + ".\n" + \ QtCore.QCoreApplication.translate("digitizingtools", "Please select all features that surround the gap to be filled.")) return None else: reply = QtGui.QMessageBox.question(None, self.title, QtCore.QCoreApplication.translate("digitizingtools", "Fill all gaps between selected polygons?"), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No | QtGui.QMessageBox.Cancel) if reply == QtGui.QMessageBox.Yes: self.fillGaps() return None elif reply == QtGui.QMessageBox.No: self.doIgnoreTool = False
def run(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: QtGui.QMessageBox.information(None, 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.Cancel ) if reply == QtGui.QMessageBox.Yes: cutterLayer.invertSelection() else: return None 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 = feat.geometry() if cutterCRSSrsid != projectCRSSrsid: cutterGeom.transform(QgsCoordinateTransform(cutterCRSSrsid, projectCRSSrsid)) bbox = cutterGeom.boundingBox() passiveLayer.select(bbox, False) # make a new selection for selFeat in passiveLayer.selectedFeatures(): selGeom = selFeat.geometry() 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", "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 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 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 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 = [] 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 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 = feat.geometry() if cutterCRSSrsid != projectCRSSrsid: cutterGeom.transform( QgsCoordinateTransform(cutterCRSSrsid, projectCRSSrsid)) bbox = cutterGeom.boundingBox() passiveLayer.select(bbox, False) # make a new selection for selFeat in passiveLayer.selectedFeatures(): selGeom = selFeat.geometry() 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 = [] 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 = [] 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()