Source code for dtcutter
# -*- coding: utf-8 -*-
"""
dtcutter
---------
Part of DigitizingTools, a QGIS plugin that
subsumes different tools neded during digitizing sessions
"""
"""
* begin : 2013-02-25
* copyright : (C) 2013 by Bernhard Ströbl
* email : bernhard.stroebl@jena.de
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
from PyQt4 import QtCore, QtGui
from qgis.core import *
import icons_rc
import dtutils
[docs]class DtCutWithPolygon():
'''Cut out from active editable layer with selected polygon from another layer'''
def __init__(self, iface, toolBar):
# Save reference to the QGIS interface
self.iface = iface
#create action
self.act_cutter = QtGui.QAction(QtGui.QIcon(":/cutter.png"),
QtCore.QCoreApplication.translate("digitizingtools", "Cut with polygon from another layer"), self.iface.mainWindow())
self.act_cutter.triggered.connect(self.run)
self.iface.currentLayerChanged.connect(self.enable)
toolBar.addAction(self.act_cutter)
self.enable()
[docs] def run(self):
'''Function that does all the real work'''
title = QtCore.QCoreApplication.translate("digitizingtools", "Cutter")
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("digitizingtools", "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 passiveCRSSrsid != projectCRSSrsid:
newGeom.transform(QgsCoordinateTransform( projectCRSSrsid, passiveCRSSrsid))
if passiveLayer.changeGeometry(selFeat.id(), newGeom):
featuresBeingCut += 1
if featuresBeingCut > 0:
passiveLayer.endEditCommand()
passiveLayer.removeSelection()
else:
passiveLayer.destroyEditCommand()
[docs] def enable(self):
'''Enables/disables the corresponding button.'''
# Disable the Button by default
self.act_cutter.setEnabled(False)
layer = self.iface.activeLayer()
if layer <> None:
## Only for vector layers.
if layer.type() == 0:
# not for point layers
if layer.geometryType != 0:
# enable if editable
self.act_cutter.setEnabled(layer.isEditable())
layer.editingStarted.connect(self.enable)
layer.editingStopped.connect(self.enable)