def __init__(self, iface, toolBar): # Save reference to the QGIS interface self.iface = iface self.canvas = self.iface.mapCanvas() self.gui = None # Points and Markers self.p1 = None self.p2 = None self.m1 = None self.m2 = None self.selected_feature = None #create action self.node_mover = QtGui.QAction( QtGui.QIcon(":/MovePolygonNodeByArea.png"), QtCore.QCoreApplication.translate( "digitizingtools", "Automatically modify polygon to target area moving one node"), self.iface.mainWindow()) self.node_mover.triggered.connect(self.run) self.iface.currentLayerChanged.connect(self.enable) toolBar.addAction(self.node_mover) self.enable() self.tool = DtSelectVertexTool(self.canvas)
def __init__(self, iface, toolBar, icon, tooltip, iconBatch, tooltipBatch, geometryTypes=[0, 1, 2], numVertices=1, dtName=None): DtDualTool.__init__(self, iface, toolBar, icon, tooltip, iconBatch, tooltipBatch, geometryTypes, dtName) self.tool = DtSelectVertexTool(self.canvas, numVertices)
def __init__(self, iface, toolBar): # Save reference to the QGIS interface self.iface = iface self.canvas = self.iface.mapCanvas() self.tool = DtSelectVertexTool(self.canvas) self.doIgnoreTool = False #create action self.act_fillGap = QtGui.QAction(QtGui.QIcon(":/fillGap.png"), QtCore.QCoreApplication.translate("digitizingtools", "Fill gap"), self.iface.mainWindow()) self.act_fillGap.setCheckable(True) self.canvas.mapToolSet.connect(self.deactivate) self.act_fillGap.triggered.connect(self.run) self.iface.currentLayerChanged.connect(self.enable) toolBar.addAction(self.act_fillGap) self.enable()
class DtFillGap(): '''Fill gaps between selected features of the active layer with new features''' def __init__(self, iface, toolBar): # Save reference to the QGIS interface self.iface = iface self.canvas = self.iface.mapCanvas() self.tool = DtSelectVertexTool(self.canvas) self.doIgnoreTool = False #create action self.act_fillGap = QtGui.QAction(QtGui.QIcon(":/fillGap.png"), QtCore.QCoreApplication.translate("digitizingtools", "Fill gap"), self.iface.mainWindow()) self.act_fillGap.setCheckable(True) self.canvas.mapToolSet.connect(self.deactivate) self.act_fillGap.triggered.connect(self.run) self.iface.currentLayerChanged.connect(self.enable) toolBar.addAction(self.act_fillGap) self.enable() def deactivate(self, thisTool): if thisTool != self.tool: self.tool.clear() self.act_fillGap.setChecked(False) try: self.tool.vertexFound.disconnect(self.vertexSnapped) except: pass 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 vertexSnapped(self, snapResult): if not self.doIgnoreTool: snappedVertex = snapResult[0][0] self.fillGaps(snappedVertex) self.tool.clear() def fillGaps(self, snappedVertex = None): layer = self.iface.activeLayer() if layer.selectedFeatureCount() == 0: layer.invertSelection() multiGeom = None for aFeat in layer.selectedFeatures(): aGeom = aFeat.geometry() if not aGeom.isGeosValid(): QtGui.QMessageBox.warning(None, self.title, dtutils.dtGetInvalidGeomWarning()) return None # fill rings contained in the polygon if aGeom.isMultipart(): tempGeom = None for poly in aGeom.asMultiPolygon(): noRingGeom = self.deleteRings(poly) if tempGeom == None: tempGeom = noRingGeom else: tempGeom = tempGeom.combine(noRingGeom) else: tempGeom = self.deleteRings(aGeom.asPolygon()) # make a large polygon from all selected if multiGeom == None: multiGeom = tempGeom else: multiGeom = multiGeom.combine(tempGeom) rings = dtutils.dtExtractRings(multiGeom) if len(rings) == 0: QtGui.QMessageBox.warning(None, self.title, QtCore.QCoreApplication.translate("digitizingtools", "There are no gaps between the polygons.") ) else: if snappedVertex != None: thisRing = None for aRing in rings: for aPoint in dtutils.dtExtractPoints(aRing): if aPoint.x() == snappedVertex.x() and aPoint.y() == snappedVertex.y(): thisRing = aRing break if thisRing != None: newFeat = dtutils.dtCreateFeature(layer) layer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Fill gap")) if self.iface.openFeatureForm(layer, newFeat, True): newFeat.setGeometry(thisRing) layer.addFeature(newFeat) layer.endEditCommand() else: layer.destroyEditCommand() else: QtGui.QMessageBox.warning(None, self.title, QtCore.QCoreApplication.translate("digitizingtools", "The selected gap is not closed.") ) else: newFeat = dtutils.dtCreateFeature(layer) layer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Fill gaps")) if self.iface.openFeatureForm(layer, newFeat): for aRing in rings: aFeat = dtutils.dtCopyFeature(layer, newFeat) aFeat.setGeometry(aRing) layer.addFeature(aFeat) layer.endEditCommand() self.canvas.refresh() def deleteRings(self, poly): outGeom = QgsGeometry.fromPolygon(poly) if len(poly) > 1: # we have rings rings = dtutils.dtExtractRings(outGeom) for aRing in rings: outGeom = outGeom.combine(aRing) return outGeom def enable(self): '''Enables/disables the corresponding button.''' # Disable the Button by default self.act_fillGap.setEnabled(False) layer = self.iface.activeLayer() if layer <> None: #Only for vector layers. if layer.type() == QgsMapLayer.VectorLayer: # only for polygon layers if layer.geometryType() == 2: self.act_fillGap.setEnabled(layer.isEditable()) try: layer.editingStarted.disconnect(self.enable) # disconnect, will be reconnected except: pass try: layer.editingStopped.disconnect(self.enable) # when it becomes active layer again except: pass layer.editingStarted.connect(self.enable) layer.editingStopped.connect(self.enable)
class DtFillRing(): '''Fill selected ring/all rings in selected feature in active polygon layer''' def __init__(self, iface, toolBar): # Save reference to the QGIS interface self.iface = iface self.canvas = self.iface.mapCanvas() #create action self.act_fillRing = QtGui.QAction(QtGui.QIcon(":/fillRing.png"), QtCore.QCoreApplication.translate("digitizingtools", "Fill ring"), self.iface.mainWindow()) self.act_fillRing.setCheckable(True) self.canvas.mapToolSet.connect(self.deactivate) self.act_fillRing.triggered.connect(self.run) self.iface.currentLayerChanged.connect(self.enable) toolBar.addAction(self.act_fillRing) self.enable() self.tool = DtSelectVertexTool(self.canvas) self.doIgnoreTool = False def deactivate(self, thisTool): self.tool.clear() if thisTool != self.tool: self.act_fillRing.setChecked(False) try: self.tool.vertexFound.disconnect(self.vertexSnapped) except: pass def run(self): '''Function that does all the real work''' title = QtCore.QCoreApplication.translate("digitizingtools", "Fill ring") layer = self.iface.activeLayer() self.canvas.setMapTool(self.tool) #Connect to the DtSelectVertexTool self.doIgnoreTool = False 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_fillRing.setChecked(True) if layer.selectedFeatureCount() > 0: reply = QtGui.QMessageBox.question(None, title, QtCore.QCoreApplication.translate("digitizingtools", "Fill all rings in all selected polygons?"), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No | QtGui.QMessageBox.Cancel) if reply == QtGui.QMessageBox.Yes: self.fillRings(layer.selectedFeaturesIds()) self.doIgnoreTool = True elif reply == QtGui.QMessageBox.No: layer.removeSelection() self.canvas.refresh() else: self.doIgnoreTool = True def vertexSnapped(self, snapResult): if not self.doIgnoreTool: snappedVertex = snapResult[0][0] snappedFid = snapResult[2][0] layer = self.iface.activeLayer() thisRing = None feat = dtutils.dtGetFeatureForId(layer, snappedFid) if feat != None: geom = feat.geometry() rings = dtutils.dtExtractRings(geom) for aRing in rings: for aPoint in dtutils.dtExtractPoints(aRing): if aPoint.x() == snappedVertex.x() and aPoint.y() == snappedVertex.y(): thisRing = aRing break if thisRing != None: newFeat = dtutils.dtCreateFeature(layer) layer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Fill ring")) if self.iface.openFeatureForm(layer, newFeat, True): # let user edit attributes newFeat.setGeometry(thisRing) layer.addFeature(newFeat) layer.endEditCommand() self.canvas.refresh() else: layer.destroyEditCommand() self.tool.clear() def fillRings(self, forFids): layer = self.iface.activeLayer() newFeat = dtutils.dtCreateFeature(layer) layer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Fill rings")) if self.iface.openFeatureForm(layer, newFeat): for fid in forFids: featureToFill = dtutils.dtGetFeatureForId(layer, fid) if featureToFill != None: geom = featureToFill.geometry() rings = dtutils.dtExtractRings(geom) for aRing in rings: aFeat = dtutils.dtCopyFeature(layer, newFeat) aFeat.setGeometry(aRing) #for i in range(layer.pendingFields().count()): layer.addFeature(aFeat) layer.endEditCommand() self.canvas.refresh() else: layer.destroyEditCommand() def enable(self): '''Enables/disables the corresponding button.''' # Disable the Button by default self.act_fillRing.setEnabled(False) layer = self.iface.activeLayer() if layer <> None: #Only for vector layers. if layer.type() == QgsMapLayer.VectorLayer: # only for polygon layers if layer.geometryType() == 2: self.act_fillRing.setEnabled(layer.isEditable()) try: layer.editingStarted.disconnect(self.enable) # disconnect, will be reconnected except: pass try: layer.editingStopped.disconnect(self.enable) # when it becomes active layer again except: pass layer.editingStarted.connect(self.enable) layer.editingStopped.connect(self.enable)