QGIS/python/plugins/fTools/tools/doGeoprocessing.py

1639 lines
75 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
#-----------------------------------------------------------
#
# fTools
# Copyright (C) 2008-2011 Carson Farmer
# EMAIL: carson.farmer (at) gmail.com
# WEB : http://www.ftools.ca/fTools.html
#
# A collection of data management and analysis tools for vector data
#
# Geoprocessing functions adapted from 'Geoprocessing Plugin',
# (C) 2008 by Dr. Horst Duester, Stefan Ziegler
#-----------------------------------------------------------
#
# licensed under the terms of GNU GPL 2
#
# 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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#---------------------------------------------------------------------
from PyQt4.QtCore import SIGNAL, QObject, Qt, QFile, QThread, QVariant
from PyQt4.QtGui import QDialog, QDoubleValidator, QDialogButtonBox, QMessageBox
from qgis.core import QGis, QgsVectorFileWriter, QgsFeature, QgsGeometry, QgsFields, QgsField, QgsFeatureRequest, QgsPoint, QgsDistanceArea
from ui_frmGeoprocessing import Ui_Dialog
import ftools_utils
class GeoprocessingDialog(QDialog, Ui_Dialog):
def __init__(self, iface, function):
QDialog.__init__(self, iface.mainWindow())
self.iface = iface
self.setupUi(self)
self.param.setValidator(QDoubleValidator(self.param))
self.myFunction = function
QObject.connect(self.btnBrowse, SIGNAL("clicked()"), self.outFile)
QObject.connect(self.inShapeA, SIGNAL("currentIndexChanged(QString)"), self.checkA)
QObject.connect(self.inShapeB, SIGNAL("currentIndexChanged(QString)"), self.checkB)
if function == 4 or function == 1 or function == 2:
QObject.connect(self.inShapeA, SIGNAL("currentIndexChanged(QString)"), self.update)
self.manageGui()
self.success = False
self.cancel_close = self.buttonBox_2.button(QDialogButtonBox.Close)
self.buttonOk = self.buttonBox_2.button(QDialogButtonBox.Ok)
self.progressBar.setValue(0)
def checkA(self):
inputLayer = unicode(self.inShapeA.currentText())
if inputLayer != "":
changedLayer = ftools_utils.getVectorLayerByName(inputLayer)
if changedLayer.selectedFeatureCount() != 0:
self.useSelectedA.setCheckState(Qt.Checked)
else:
self.useSelectedA.setCheckState(Qt.Unchecked)
def checkB(self):
inputLayer = unicode(self.inShapeB.currentText())
if inputLayer != "":
changedLayer = ftools_utils.getVectorLayerByName(inputLayer)
if changedLayer.selectedFeatureCount() != 0:
self.useSelectedB.setCheckState(Qt.Checked)
else:
self.useSelectedB.setCheckState(Qt.Unchecked)
def update(self):
self.attrib.clear()
inputLayer = unicode(self.inShapeA.currentText())
if inputLayer != "":
changedLayer = ftools_utils.getVectorLayerByName(inputLayer)
changedField = changedLayer.dataProvider().fields()
for f in changedField:
self.attrib.addItem(unicode(f.name()))
if self.myFunction == 4:
self.attrib.addItem("--- " + self.tr("Dissolve all") + " ---")
def accept(self):
if self.inShapeA.currentText() == "":
QMessageBox.warning(self, self.tr("Geoprocessing"), self.tr("Please specify an input layer"))
elif self.inShapeB.isVisible() and self.inShapeB.currentText() == "":
QMessageBox.warning(self, self.tr("Geoprocessing"), self.tr("Please specify a difference/intersect/union layer"))
elif self.param.isEnabled() and self.param.isVisible() and self.param.text() == "":
QMessageBox.warning(self, self.tr("Geoprocessing"), self.tr("Please specify valid buffer value"))
elif self.attrib.isEnabled() and self.attrib.isVisible() and self.attrib.currentText() == "":
QMessageBox.warning(self, self.tr("Geoprocessing"), self.tr("Please specify dissolve field"))
elif self.outShape.text() == "":
QMessageBox.warning(self, self.tr("Geoprocessing"), self.tr("Please specify output shapefile"))
else:
changedLayerA = ftools_utils.getVectorLayerByName(self.inShapeA.currentText())
changedLayerB = ftools_utils.getVectorLayerByName(self.inShapeB.currentText())
# check for selection in layer A
if self.useSelectedA.isChecked() and changedLayerA.selectedFeatureCount() == 0:
QMessageBox.warning(self, self.tr("Geoprocessing"), self.tr("No features selected, please uncheck 'Use selected' or make a selection"))
# check for selection in layer B
elif self.inShapeB.isVisible() and self.useSelectedB.isChecked() and changedLayerB.selectedFeatureCount() == 0:
QMessageBox.warning(self, self.tr("Geoprocessing"), self.tr("No features selected, please uncheck 'Use selected' or make a selection"))
else:
self.outShape.clear()
if self.attrib.isEnabled():
self.geoprocessing(self.inShapeA.currentText(), self.inShapeB.currentText(),
unicode(self.attrib.currentText()), self.mergeOutput.checkState(), self.useSelectedA.checkState(),
self.useSelectedB.checkState(), self.spnSegments.value())
else:
if self.param.isEnabled() and self.param.isVisible():
parameter = float(self.param.text())
else:
parameter = None
self.geoprocessing(self.inShapeA.currentText(), self.inShapeB.currentText(),
parameter, self.mergeOutput.checkState(), self.useSelectedA.checkState(), self.useSelectedB.checkState(), self.spnSegments.value())
def outFile(self):
self.outShape.clear()
(self.shapefileName, self.encoding) = ftools_utils.saveDialog(self)
if self.shapefileName is None or self.encoding is None:
return
self.outShape.setText(self.shapefileName)
def manageGui(self):
if self.myFunction == 1: # Buffer
self.label_2.hide()
self.inShapeB.hide()
self.useSelectedB.hide()
self.label_4.hide()
self.setWindowTitle(self.tr("Buffer(s)"))
elif self.myFunction == 2: # Convex hull
self.label_2.hide()
self.inShapeB.hide()
self.useSelectedB.hide()
self.rdoBuffer.setText(self.tr("Create single minimum convex hull"))
self.rdoField.setText(self.tr("Create convex hulls based on input field"))
self.label_4.hide()
self.param.hide()
self.lblSegments.hide()
self.spnSegments.hide()
self.setWindowTitle(self.tr("Convex hull(s)"))
self.mergeOutput.hide()
elif self.myFunction == 4: # Dissolve
self.label_2.hide()
self.inShapeB.hide()
self.useSelectedB.hide()
self.rdoBuffer.hide()
self.attrib.setEnabled(True)
self.param.hide()
self.rdoField.hide()
self.mergeOutput.hide()
self.lblSegments.hide()
self.spnSegments.hide()
self.setWindowTitle(self.tr("Dissolve"))
else:
self.rdoBuffer.hide()
self.param.hide()
self.label_4.hide()
self.rdoField.hide()
self.attrib.hide()
self.mergeOutput.hide()
self.lblSegments.hide()
self.spnSegments.hide()
if self.myFunction == 3: # Difference
self.label_2.setText(self.tr("Difference layer"))
self.setWindowTitle(self.tr("Difference"))
elif self.myFunction == 5: # Intersect
self.label_2.setText(self.tr("Intersect layer"))
self.setWindowTitle(self.tr("Intersect"))
elif self.myFunction == 7: # Symmetrical difference
self.label_2.setText(self.tr("Difference layer"))
self.setWindowTitle(self.tr("Symmetrical difference"))
self.useSelectedA.hide()
self.useSelectedB.hide()
elif self.myFunction == 8: # Clip
self.label_2.setText(self.tr("Clip layer"))
self.setWindowTitle(self.tr("Clip"))
else: # Union
self.label_2.setText(self.tr("Union layer"))
self.setWindowTitle(self.tr("Union"))
self.useSelectedA.hide()
self.useSelectedB.hide()
self.resize(381, 100)
self.populateLayers()
def populateLayers(self):
myListA = []
myListB = []
self.inShapeA.clear()
self.inShapeB.clear()
if self.myFunction == 4:
myListA = ftools_utils.getLayerNames([QGis.Line, QGis.Polygon])
myListB = []
else:
myListA = ftools_utils.getLayerNames([QGis.Point, QGis.Line, QGis.Polygon])
myListB = ftools_utils.getLayerNames([QGis.Point, QGis.Line, QGis.Polygon])
self.inShapeA.addItems(myListA)
self.inShapeB.addItems(myListB)
#1: Buffer
#2: Convex Hull
#3: Difference
#4: Dissolve
#5: Intersection
#6: Union
#7: Symetrical Difference
#8: Clip
def geoprocessing(self, myLayerA, myLayerB, myParam, myMerge, mySelectionA, mySelectionB, mySegments):
check = QFile(self.shapefileName)
if check.exists():
if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName):
QMessageBox.warning(self, self.tr("Geoprocessing"), self.tr("Unable to delete existing shapefile."))
return
self.buttonOk.setEnabled(False)
self.testThread = geoprocessingThread(
self.iface.mainWindow(), self, self.myFunction, myLayerA,
myLayerB, myParam, myMerge, mySelectionA, mySelectionB, mySegments, self.shapefileName, self.encoding
)
QObject.connect(self.testThread, SIGNAL("runFinished(PyQt_PyObject)"), self.runFinishedFromThread)
QObject.connect(self.testThread, SIGNAL("runStatus(PyQt_PyObject)"), self.runStatusFromThread)
QObject.connect(self.testThread, SIGNAL("runRange(PyQt_PyObject)"), self.runRangeFromThread)
self.cancel_close.setText(self.tr("Cancel"))
QObject.connect(self.cancel_close, SIGNAL("clicked()"), self.cancelThread)
self.testThread.start()
return True
def cancelThread(self):
self.testThread.stop()
self.buttonOk.setEnabled(True)
def runFinishedFromThread(self, results):
self.testThread.stop()
self.buttonOk.setEnabled(True)
self.cancel_close.setText(self.tr("Close"))
QObject.disconnect(self.cancel_close, SIGNAL("clicked()"), self.cancelThread)
out_text = ""
if results[3] is not None:
QMessageBox.warning(self, self.tr("Geoprocessing"),
self.tr("No output created. File creation error:\n%s") % (results[3]))
return
if (not results[2] is None and not results[2]) or not results[1] or not results[0]:
out_text = self.tr("\nWarnings:")
end_text = self.tr("\nSome output geometries may be missing or invalid.\n\nWould you like to add the new layer anyway?")
else:
out_text = ""
end_text = ""
if not results[2] is None:
if not results[2]:
out_text = out_text + self.tr("\nInput CRS error: Different input coordinate reference systems detected, results may not be as expected.")
else:
out_text = out_text + self.tr("\nInput CRS error: One or more input layers missing coordinate reference information, results may not be as expected.")
if not results[1]:
out_text = out_text + self.tr("\nFeature geometry error: One or more output features ignored due to invalid geometry.")
if not results[0]:
out_text = out_text + self.tr("\nGEOS geoprocessing error: One or more input features have invalid geometry.")
if self.addToCanvasCheck.isChecked():
addCanvasCheck = ftools_utils.addShapeToCanvas(unicode(self.shapefileName))
if not addCanvasCheck:
QMessageBox.warning(self, self.tr("Geoprocessing"), self.tr("Error loading output shapefile:\n%s") % (unicode(self.shapefileName)))
self.populateLayers()
else:
QMessageBox.information(self, self.tr("Geoprocessing"), self.tr("Created output shapefile:\n%s\n%s%s") % (unicode(self.shapefileName), out_text, end_text))
def runStatusFromThread(self, status):
self.progressBar.setValue(status)
def runRangeFromThread(self, range_vals):
self.progressBar.setRange(range_vals[0], range_vals[1])
class geoprocessingThread(QThread):
def __init__(self, parentThread, parentObject, function, myLayerA, myLayerB,
myParam, myMerge, mySelectionA, mySelectionB, mySegments, myName, myEncoding):
QThread.__init__(self, parentThread)
self.parent = parentObject
self.running = False
self.myFunction = function
self.myLayerA = myLayerA
self.myLayerB = myLayerB
self.myParam = myParam
self.myMerge = myMerge
self.mySelectionA = mySelectionA
self.mySelectionB = mySelectionB
self.mySegments = int(mySegments)
self.myName = myName
self.myEncoding = myEncoding
def run(self):
self.running = True
self.vlayerA = ftools_utils.getVectorLayerByName(self.myLayerA)
error = None
if self.myFunction == 1 or self.myFunction == 2 or self.myFunction == 4:
(self.myParam, useField) = self.checkParameter(self.vlayerA, self.myParam)
if self.myParam is not None:
if self.myFunction == 1:
geos, feature, match, error = self.buffering(useField)
elif self.myFunction == 2:
geos, feature, match, error = self.convex_hull(useField)
elif self.myFunction == 4:
geos, feature, match, error = self.dissolve(useField)
else:
self.vlayerB = ftools_utils.getVectorLayerByName(self.myLayerB)
if self.myFunction == 3:
geos, feature, match, error = self.difference()
elif self.myFunction == 5:
geos, feature, match, error = self.intersect()
elif self.myFunction == 6:
geos, feature, match, error = self.union()
elif self.myFunction == 7:
2015-10-01 19:11:47 +02:00
geos, feature, match, error = self.symmetrical_difference()
elif self.myFunction == 8:
geos, feature, match, error = self.clip()
self.emit(SIGNAL("runFinished(PyQt_PyObject)"), (geos, feature, match, error))
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
def stop(self):
self.running = False
def buffering(self, useField):
GEOS_EXCEPT = True
FEATURE_EXCEPT = True
vproviderA = self.vlayerA.dataProvider()
writer = QgsVectorFileWriter(self.myName, self.myEncoding, vproviderA.fields(),
QGis.WKBPolygon, vproviderA.crs())
# check if writer was created properly, if not, return with error
if writer.hasError():
return GEOS_EXCEPT, FEATURE_EXCEPT, True, writer.errorMessage()
outFeat = QgsFeature()
inFeat = QgsFeature()
inGeom = QgsGeometry()
outGeom = QgsGeometry()
nElement = 0
# there is selection in input layer
if self.mySelectionA:
nFeat = self.vlayerA.selectedFeatureCount()
selectionA = self.vlayerA.selectedFeatures()
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
# with dissolve
if self.myMerge:
first = True
for inFeat in selectionA:
atMap = inFeat.attributes()
if useField:
value = atMap[self.myParam].doDouble()[0]
else:
value = self.myParam
inGeom = QgsGeometry(inFeat.geometry())
try:
outGeom = inGeom.buffer(float(value), self.mySegments)
if first:
tempGeom = QgsGeometry(outGeom)
first = False
else:
try:
tempGeom = tempGeom.combine(outGeom)
except:
GEOS_EXCEPT = False
continue
except:
GEOS_EXCEPT = False
continue
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
try:
outFeat.setGeometry(tempGeom)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
# without dissolve
else:
for inFeat in selectionA:
atMap = inFeat.attributes()
if useField:
value = atMap[self.myParam]
else:
value = self.myParam
inGeom = QgsGeometry(inFeat.geometry())
try:
outGeom = inGeom.buffer(float(value), self.mySegments)
if not outGeom.isGeosEmpty():
try:
outFeat.setGeometry(outGeom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
except:
GEOS_EXCEPT = False
continue
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
# there is no selection in input layer
else:
nFeat = vproviderA.featureCount()
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
# with dissolve
if self.myMerge:
first = True
fit = vproviderA.getFeatures()
while fit.nextFeature(inFeat):
atMap = inFeat.attributes()
if useField:
value = atMap[self.myParam]
else:
value = self.myParam
inGeom = QgsGeometry(inFeat.geometry())
try:
outGeom = inGeom.buffer(float(value), self.mySegments)
if first:
tempGeom = QgsGeometry(outGeom)
first = False
else:
try:
tempGeom = tempGeom.combine(outGeom)
except:
GEOS_EXCEPT = False
continue
except:
GEOS_EXCEPT = False
continue
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
try:
outFeat.setGeometry(tempGeom)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
# without dissolve
else:
fit = vproviderA.getFeatures()
while fit.nextFeature(inFeat):
atMap = inFeat.attributes()
if useField:
value = atMap[self.myParam]
else:
value = self.myParam
inGeom = QgsGeometry(inFeat.geometry())
try:
outGeom = inGeom.buffer(float(value), self.mySegments)
if not outGeom.isGeosEmpty():
try:
outFeat.setGeometry(outGeom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
except:
GEOS_EXCEPT = False
continue
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
del writer
return GEOS_EXCEPT, FEATURE_EXCEPT, True, None
def convex_hull(self, useField):
GEOS_EXCEPT = True
FEATURE_EXCEPT = True
vproviderA = self.vlayerA.dataProvider()
#
outFeatFields = QgsFields()
if useField:
importedField = vproviderA.fields().at(self.myParam)
importedFieldName = importedField.name()
#
outFeatFields.extend(vproviderA.fields())
# creating area and perimeter fields
areaField = QgsField("area", QVariant.Double)
perimField = QgsField("perim", QVariant.Double)
# appending fields
outFeatFields.append(areaField)
outFeatFields.append(perimField)
#
writer = QgsVectorFileWriter(self.myName, self.myEncoding, outFeatFields,
QGis.WKBPolygon, vproviderA.crs())
if writer.hasError():
return GEOS_EXCEPT, FEATURE_EXCEPT, True, writer.errorMessage()
inFeat = QgsFeature()
outFeat = QgsFeature()
# set feature fields
outFeat.setFields(outFeatFields)
#
inGeom = QgsGeometry()
outGeom = QgsGeometry()
nElement = 0
# there is selection in input layer
if self.mySelectionA:
nFeat = self.vlayerA.selectedFeatureCount()
selectionA = self.vlayerA.selectedFeatures()
if useField:
unique = ftools_utils.getUniqueValues(vproviderA, self.myParam)
nFeat = nFeat * len(unique)
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
for i in unique:
first = True
hull = []
for inFeat in selectionA:
atMap = inFeat.attributes()
idVar = atMap[self.myParam]
if idVar == i:
if first:
firstFeature = QgsFeature(inFeat)
first = False
inGeom = QgsGeometry(inFeat.geometry())
points = ftools_utils.extractPoints(inGeom)
hull.extend(points)
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
if len(hull) >= 3:
tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
try:
outGeom = tmpGeom.convexHull()
outFeat.setGeometry(outGeom)
(area, perim) = self.simpleMeasure(outGeom)
for f in firstFeature.fields():
outFeat.setAttribute(f.name(), firstFeature.attribute(f.name()))
outFeat.setAttribute("area", area)
outFeat.setAttribute("perim", perim)
writer.addFeature(outFeat)
except:
GEOS_EXCEPT = False
continue
else:
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
hull = []
for inFeat in selectionA:
inGeom = QgsGeometry(inFeat.geometry())
points = ftools_utils.extractPoints(inGeom)
hull.extend(points)
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
try:
outGeom = tmpGeom.convexHull()
outFeat.setGeometry(outGeom)
(area, perim) = self.simpleMeasure(outGeom)
for f in inFeat.fields():
outFeat.setAttribute(f.name(), inFeat.attribute(f.name()))
outFeat.setAttribute("area", area)
outFeat.setAttribute("perim", perim)
writer.addFeature(outFeat)
except:
GEOS_EXCEPT = False
# there is no selection in input layer
else:
nFeat = vproviderA.featureCount()
if useField:
unique = ftools_utils.getUniqueValues(vproviderA, self.myParam)
nFeat = nFeat * len(unique)
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
for i in unique:
first = True
hull = []
fitA = vproviderA.getFeatures()
while fitA.nextFeature(inFeat):
idVar = inFeat.attribute(importedFieldName)
if idVar == i:
if first:
firstFeature = QgsFeature(inFeat)
first = False
inGeom = QgsGeometry(inFeat.geometry())
points = ftools_utils.extractPoints(inGeom)
hull.extend(points)
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
if len(hull) >= 3:
tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
try:
outGeom = tmpGeom.convexHull()
outFeat.setGeometry(outGeom)
(area, perim) = self.simpleMeasure(outGeom)
for f in firstFeature.fields():
outFeat.setAttribute(f.name(), firstFeature.attribute(f.name()))
outFeat.setAttribute("area", area)
outFeat.setAttribute("perim", perim)
writer.addFeature(outFeat)
except:
GEOS_EXCEPT = False
continue
else:
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
hull = []
fitA = vproviderA.getFeatures()
while fitA.nextFeature(inFeat):
inGeom = QgsGeometry(inFeat.geometry())
points = ftools_utils.extractPoints(inGeom)
hull.extend(points)
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull))
try:
outGeom = tmpGeom.convexHull()
outFeat.setGeometry(outGeom)
(area, perim) = self.simpleMeasure(outGeom)
for f in inFeat.fields():
outFeat.setAttribute(f.name(), inFeat.attribute(f.name()))
outFeat.setAttribute("area", area)
outFeat.setAttribute("perim", perim)
writer.addFeature(outFeat)
except:
GEOS_EXCEPT = False
del writer
return GEOS_EXCEPT, FEATURE_EXCEPT, True, None
def dissolve(self, useField):
GEOS_EXCEPT = True
FEATURE_EXCEPT = True
vproviderA = self.vlayerA.dataProvider()
writer = QgsVectorFileWriter(self.myName, self.myEncoding, vproviderA.fields(),
vproviderA.geometryType(), vproviderA.crs())
if writer.hasError():
return GEOS_EXCEPT, FEATURE_EXCEPT, True, writer.errorMessage()
inFeat = QgsFeature()
outFeat = QgsFeature()
nElement = 0
attrs = None
# there is selection in input layer
if self.mySelectionA:
nFeat = self.vlayerA.selectedFeatureCount()
selectionA = self.vlayerA.selectedFeatures()
if not useField:
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
first = True
for inFeat in selectionA:
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
if first:
attrs = inFeat.attributes()
tmpInGeom = QgsGeometry(inFeat.geometry())
outFeat.setGeometry(tmpInGeom)
first = False
else:
tmpInGeom = QgsGeometry(inFeat.geometry())
tmpOutGeom = QgsGeometry(outFeat.geometry())
try:
tmpOutGeom = QgsGeometry(tmpOutGeom.combine(tmpInGeom))
outFeat.setGeometry(tmpOutGeom)
except:
GEOS_EXCEPT = False
continue
outFeat.setAttributes(attrs)
writer.addFeature(outFeat)
else:
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
outFeats = {}
attrs = {}
for inFeat in selectionA:
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
atMap = inFeat.attributes()
tempItem = unicode(atMap[self.myParam]).strip()
if not (tempItem in outFeats):
outFeats[tempItem] = QgsGeometry(inFeat.geometry())
attrs[tempItem] = atMap
else:
try:
outFeats[tempItem] = outFeats[tempItem].combine(inFeat.geometry())
except:
GEOS_EXCEPT = False
continue
for k in outFeats.keys():
feature = QgsFeature()
feature.setAttributes(attrs[k])
feature.setGeometry(outFeats[k])
writer.addFeature(feature)
# there is no selection in input layer
else:
nFeat = vproviderA.featureCount()
if not useField:
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
first = True
fitA = vproviderA.getFeatures()
while fitA.nextFeature(inFeat):
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
if first:
attrs = inFeat.attributes()
tmpInGeom = QgsGeometry(inFeat.geometry())
outFeat.setGeometry(tmpInGeom)
first = False
else:
tmpInGeom = QgsGeometry(inFeat.geometry())
tmpOutGeom = QgsGeometry(outFeat.geometry())
try:
tmpOutGeom = QgsGeometry(tmpOutGeom.combine(tmpInGeom))
outFeat.setGeometry(tmpOutGeom)
except:
GEOS_EXCEPT = False
continue
outFeat.setAttributes(attrs)
writer.addFeature(outFeat)
else:
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
outFeats = {}
attrs = {}
fitA = vproviderA.getFeatures()
while fitA.nextFeature(inFeat):
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
atMap = inFeat.attributes()
tempItem = unicode(atMap[self.myParam]).strip()
if not (tempItem in outFeats):
outFeats[tempItem] = QgsGeometry(inFeat.geometry())
attrs[tempItem] = atMap
else:
try:
outFeats[tempItem] = outFeats[tempItem].combine(inFeat.geometry())
except:
GEOS_EXCEPT = False
continue
for k in outFeats.keys():
feature = QgsFeature()
feature.setAttributes(attrs[k])
feature.setGeometry(outFeats[k])
writer.addFeature(feature)
del writer
return GEOS_EXCEPT, FEATURE_EXCEPT, True, None
def difference(self):
GEOS_EXCEPT = True
FEATURE_EXCEPT = True
vproviderA = self.vlayerA.dataProvider()
vproviderB = self.vlayerB.dataProvider()
# check for crs compatibility
crsA = vproviderA.crs()
crsB = vproviderB.crs()
if not crsA.isValid() or not crsB.isValid():
crs_match = None
else:
crs_match = crsA == crsB
writer = QgsVectorFileWriter(self.myName, self.myEncoding, vproviderA.fields(),
vproviderA.geometryType(), vproviderA.crs())
if writer.hasError():
return GEOS_EXCEPT, FEATURE_EXCEPT, crs_match, writer.errorMessage()
inFeatA = QgsFeature()
inFeatB = QgsFeature()
outFeat = QgsFeature()
nElement = 0
index = ftools_utils.createIndex(vproviderB)
# there is selection in input layer
if self.mySelectionA:
nFeat = self.vlayerA.selectedFeatureCount()
selectionA = self.vlayerA.selectedFeatures()
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
# we have selection in overlay layer
if self.mySelectionB:
selectionB = self.vlayerB.selectedFeaturesIds()
for inFeatA in selectionA:
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
add = True
geom = QgsGeometry(inFeatA.geometry())
diff_geom = QgsGeometry(geom)
atMap = inFeatA.attributes()
intersects = index.intersects(geom.boundingBox())
for id in intersects:
# is intersect feature in selection
if id in selectionB:
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
try:
if diff_geom.intersects(tmpGeom):
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
except:
GEOS_EXCEPT = False
add = False
break
if add:
try:
outFeat.setGeometry(diff_geom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
# we have no selection in overlay layer
else:
for inFeatA in selectionA:
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
add = True
geom = QgsGeometry(inFeatA.geometry())
diff_geom = QgsGeometry(geom)
atMap = inFeatA.attributes()
intersects = index.intersects(geom.boundingBox())
for id in intersects:
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
try:
if diff_geom.intersects(tmpGeom):
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
except:
GEOS_EXCEPT = False
add = False
break
if add:
try:
outFeat.setGeometry(diff_geom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
# there is no selection in input layer
else:
nFeat = vproviderA.featureCount()
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
# we have selection in overlay layer
if self.mySelectionB:
selectionB = self.vlayerB.selectedFeaturesIds()
fitA = vproviderA.getFeatures()
while fitA.nextFeature(inFeatA):
nElement += 1
add = True
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
geom = QgsGeometry(inFeatA.geometry())
diff_geom = QgsGeometry(geom)
atMap = inFeatA.attributes()
intersects = index.intersects(geom.boundingBox())
for id in intersects:
# now check if id in selection
if id in selectionB:
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
try:
if diff_geom.intersects(tmpGeom):
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
except:
GEOS_EXCEPT = False
add = False
break
if add:
try:
outFeat.setGeometry(diff_geom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
# we have no selection in overlay layer
else:
fitA = vproviderA.getFeatures()
while fitA.nextFeature(inFeatA):
nElement += 1
add = True
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
geom = QgsGeometry(inFeatA.geometry())
diff_geom = QgsGeometry(geom)
atMap = inFeatA.attributes()
intersects = index.intersects(geom.boundingBox())
for id in intersects:
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
try:
if diff_geom.intersects(tmpGeom):
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
if diff_geom.isGeosEmpty():
GEOS_EXCEPT = False
add = False
break
except:
GEOS_EXCEPT = False
add = False
break
if add:
try:
outFeat.setGeometry(diff_geom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
del writer
return GEOS_EXCEPT, FEATURE_EXCEPT, crs_match, None
def intersect(self):
GEOS_EXCEPT = True
FEATURE_EXCEPT = True
vproviderA = self.vlayerA.dataProvider()
vproviderB = self.vlayerB.dataProvider()
# check for crs compatibility
crsA = vproviderA.crs()
crsB = vproviderB.crs()
if not crsA.isValid() or not crsB.isValid():
crs_match = None
else:
crs_match = crsA == crsB
fields = ftools_utils.combineVectorFields(self.vlayerA, self.vlayerB)
writer = QgsVectorFileWriter(self.myName, self.myEncoding, fields,
vproviderA.geometryType(), vproviderA.crs())
if writer.hasError():
return GEOS_EXCEPT, FEATURE_EXCEPT, crs_match, writer.errorMessage()
inFeatA = QgsFeature()
inFeatB = QgsFeature()
outFeat = QgsFeature()
nElement = 0
index = ftools_utils.createIndex(vproviderB)
# there is selection in input layer
if self.mySelectionA:
nFeat = self.vlayerA.selectedFeatureCount()
selectionA = self.vlayerA.selectedFeatures()
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
# we have selection in overlay layer
if self.mySelectionB:
selectionB = self.vlayerB.selectedFeaturesIds()
for inFeatA in selectionA:
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
geom = QgsGeometry(inFeatA.geometry())
atMapA = inFeatA.attributes()
intersects = index.intersects(geom.boundingBox())
for id in intersects:
if id in selectionB:
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
try:
if geom.intersects(tmpGeom):
atMapB = inFeatB.attributes()
int_geom = QgsGeometry(geom.intersection(tmpGeom))
if int_geom.wkbType() == 0:
int_com = geom.combine(tmpGeom)
int_sym = geom.symDifference(tmpGeom)
int_geom = QgsGeometry(int_com.difference(int_sym))
try:
# Geometry list: prevents writing error
# in geometries of different types
# produced by the intersection
# fix #3549
gList = ftools_utils.getGeomType(geom.wkbType())
if int_geom.wkbType() in gList:
outFeat.setGeometry(int_geom)
outFeat.setAttributes(atMapA + atMapB)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
except:
GEOS_EXCEPT = False
break
# we don't have selection in overlay layer
else:
for inFeatA in selectionA:
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
geom = QgsGeometry(inFeatA.geometry())
atMapA = inFeatA.attributes()
intersects = index.intersects(geom.boundingBox())
for id in intersects:
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
try:
if geom.intersects(tmpGeom):
atMapB = inFeatB.attributes()
int_geom = QgsGeometry(geom.intersection(tmpGeom))
if int_geom.wkbType() == 0:
int_com = geom.combine(tmpGeom)
int_sym = geom.symDifference(tmpGeom)
int_geom = QgsGeometry(int_com.difference(int_sym))
try:
gList = ftools_utils.getGeomType(geom.wkbType())
if int_geom.wkbType() in gList:
outFeat.setGeometry(int_geom)
outFeat.setAttributes(atMapA + atMapB)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
except:
GEOS_EXCEPT = False
break
# there is no selection in input layer
else:
nFeat = vproviderA.featureCount()
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
# we have selection in overlay layer
if self.mySelectionB:
selectionB = self.vlayerB.selectedFeaturesIds()
fitA = vproviderA.getFeatures()
while fitA.nextFeature(inFeatA):
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
geom = QgsGeometry(inFeatA.geometry())
atMapA = inFeatA.attributes()
intersects = index.intersects(geom.boundingBox())
for id in intersects:
if id in selectionB:
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
try:
if geom.intersects(tmpGeom):
atMapB = inFeatB.attributes()
int_geom = QgsGeometry(geom.intersection(tmpGeom))
if int_geom.wkbType() == 0:
int_com = geom.combine(tmpGeom)
int_sym = geom.symDifference(tmpGeom)
int_geom = QgsGeometry(int_com.difference(int_sym))
try:
gList = ftools_utils.getGeomType(geom.wkbType())
if int_geom.wkbType() in gList:
outFeat.setGeometry(int_geom)
outFeat.setAttributes(atMapA + atMapB)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
except:
GEOS_EXCEPT = False
break
# we have no selection in overlay layer
else:
fitA = vproviderA.getFeatures()
while fitA.nextFeature(inFeatA):
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
geom = QgsGeometry(inFeatA.geometry())
atMapA = inFeatA.attributes()
intersects = index.intersects(geom.boundingBox())
for id in intersects:
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
try:
if geom.intersects(tmpGeom):
atMapB = inFeatB.attributes()
int_geom = QgsGeometry(geom.intersection(tmpGeom))
if int_geom.wkbType() == 0:
int_com = geom.combine(tmpGeom)
int_sym = geom.symDifference(tmpGeom)
int_geom = QgsGeometry(int_com.difference(int_sym))
try:
gList = ftools_utils.getGeomType(geom.wkbType())
if int_geom.wkbType() in gList:
outFeat.setGeometry(int_geom)
outFeat.setAttributes(atMapA + atMapB)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
except:
GEOS_EXCEPT = False
break
del writer
return GEOS_EXCEPT, FEATURE_EXCEPT, crs_match, None
def union(self):
GEOS_EXCEPT = True
FEATURE_EXCEPT = True
vproviderA = self.vlayerA.dataProvider()
vproviderB = self.vlayerB.dataProvider()
# check for crs compatibility
crsA = vproviderA.crs()
crsB = vproviderB.crs()
if not crsA.isValid() or not crsB.isValid():
crs_match = None
else:
crs_match = crsA == crsB
fields = ftools_utils.combineVectorFields(self.vlayerA, self.vlayerB)
writer = QgsVectorFileWriter(self.myName, self.myEncoding, fields,
vproviderA.geometryType(), vproviderA.crs())
if writer.hasError():
return GEOS_EXCEPT, FEATURE_EXCEPT, crs_match, writer.errorMessage()
inFeatA = QgsFeature()
inFeatB = QgsFeature()
outFeat = QgsFeature()
indexA = ftools_utils.createIndex(vproviderB)
indexB = ftools_utils.createIndex(vproviderA)
nFeat = vproviderA.featureCount() + vproviderB.featureCount()
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
count = 0
nElement = 0
2012-06-15 18:27:52 +02:00
fitA = vproviderA.getFeatures()
while fitA.nextFeature(inFeatA):
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
nElement += 1
lstIntersectingB = []
geom = QgsGeometry(inFeatA.geometry())
atMapA = inFeatA.attributes()
intersects = indexA.intersects(geom.boundingBox())
if len(intersects) < 1:
try:
outFeat.setGeometry(geom)
outFeat.setAttributes(atMapA)
writer.addFeature(outFeat)
except:
# this really shouldn't happen, as we
# haven't edited the input geom at all
FEATURE_EXCEPT = False
else:
for id in intersects:
count += 1
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
atMapB = inFeatB.attributes()
tmpGeom = QgsGeometry(inFeatB.geometry())
try:
if geom.intersects(tmpGeom):
int_geom = geom.intersection(tmpGeom)
lstIntersectingB.append(tmpGeom)
if int_geom is None:
# There was a problem creating the intersection
GEOS_EXCEPT = False
int_geom = QgsGeometry()
else:
int_geom = QgsGeometry(int_geom)
if int_geom.wkbType() == 0:
# intersection produced different geometry types
temp_list = int_geom.asGeometryCollection()
for i in temp_list:
if i.type() == geom.type():
int_geom = QgsGeometry(i)
try:
outFeat.setGeometry(int_geom)
outFeat.setAttributes(atMapA + atMapB)
writer.addFeature(outFeat)
except Exception as err:
FEATURE_EXCEPT = False
else:
# Geometry list: prevents writing error
# in geometries of different types
# produced by the intersection
# fix #3549
gList = ftools_utils.getGeomType(geom.wkbType())
if int_geom.wkbType() in gList:
try:
outFeat.setGeometry(int_geom)
outFeat.setAttributes(atMapA + atMapB)
writer.addFeature(outFeat)
except Exception as err:
FEATURE_EXCEPT = False
except Exception as err:
GEOS_EXCEPT = False
2013-02-18 00:25:12 +01:00
try:
# the remaining bit of inFeatA's geometry
# if there is nothing left, this will just silently fail and we're good
diff_geom = QgsGeometry(geom)
if len(lstIntersectingB) != 0:
intB = QgsGeometry.unaryUnion(lstIntersectingB)
diff_geom = diff_geom.difference(intB)
if diff_geom.wkbType() == 0:
temp_list = diff_geom.asGeometryCollection()
for i in temp_list:
if i.type() == geom.type():
diff_geom = QgsGeometry(i)
outFeat.setGeometry(diff_geom)
outFeat.setAttributes(atMapA)
writer.addFeature(outFeat)
except Exception as err:
2012-05-26 14:27:48 +02:00
FEATURE_EXCEPT = False
length = len(vproviderA.fields())
atMapA = [None] * length
fitB = vproviderB.getFeatures()
while fitB.nextFeature(inFeatB):
add = False
geom = QgsGeometry(inFeatB.geometry())
diff_geom = QgsGeometry(geom)
atMap = atMapA + inFeatB.attributes()
intersects = indexB.intersects(geom.boundingBox())
if len(intersects) < 1:
try:
outFeat.setGeometry(geom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except Exception as err:
FEATURE_EXCEPT = False
else:
for id in intersects:
vproviderA.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatA)
tmpGeom = QgsGeometry(inFeatA.geometry())
try:
if diff_geom.intersects(tmpGeom):
add = True
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
else:
# this only happends if the bounding box
# intersects, but the geometry doesn't
outFeat.setGeometry(diff_geom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except Exception as err:
add = False
GEOS_EXCEPT = False
if add:
try:
outFeat.setGeometry(diff_geom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except Exception as err:
FEATURE_EXCEPT = False
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
nElement += 1
del writer
return GEOS_EXCEPT, FEATURE_EXCEPT, crs_match, None
2015-10-01 19:11:47 +02:00
def symmetrical_difference(self):
GEOS_EXCEPT = True
FEATURE_EXCEPT = True
vproviderA = self.vlayerA.dataProvider()
vproviderB = self.vlayerB.dataProvider()
# check for crs compatibility
crsA = vproviderA.crs()
crsB = vproviderB.crs()
if not crsA.isValid() or not crsB.isValid():
crs_match = None
else:
crs_match = crsA == crsB
fields = ftools_utils.combineVectorFields(self.vlayerA, self.vlayerB)
writer = QgsVectorFileWriter(self.myName, self.myEncoding, fields,
vproviderA.geometryType(), vproviderA.crs())
if writer.hasError():
return GEOS_EXCEPT, FEATURE_EXCEPT, crs_match, writer.errorMessage()
inFeatA = QgsFeature()
inFeatB = QgsFeature()
outFeat = QgsFeature()
indexA = ftools_utils.createIndex(vproviderB)
indexB = ftools_utils.createIndex(vproviderA)
nFeat = vproviderA.featureCount() * vproviderB.featureCount()
nElement = 0
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
fitA = vproviderA.getFeatures()
while fitA.nextFeature(inFeatA):
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
add = True
geom = QgsGeometry(inFeatA.geometry())
diff_geom = QgsGeometry(geom)
atMapA = inFeatA.attributes()
intersects = indexA.intersects(geom.boundingBox())
for id in intersects:
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
try:
if diff_geom.intersects(tmpGeom):
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
except:
add = False
GEOS_EXCEPT = False
break
if add:
try:
outFeat.setGeometry(diff_geom)
outFeat.setAttributes(atMapA)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
length = len(vproviderA.fields())
fitB = vproviderB.getFeatures()
while fitB.nextFeature(inFeatA):
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
add = True
geom = QgsGeometry(inFeatA.geometry())
diff_geom = QgsGeometry(geom)
atMap = inFeatA.attributes()
atMap = [None] * length + atMap
intersects = indexB.intersects(geom.boundingBox())
for id in intersects:
vproviderA.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
try:
if diff_geom.intersects(tmpGeom):
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
except:
add = False
GEOS_EXCEPT = False
break
if add:
try:
outFeat.setGeometry(diff_geom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
del writer
return GEOS_EXCEPT, FEATURE_EXCEPT, crs_match, None
def clip(self):
GEOS_EXCEPT = True
FEATURE_EXCEPT = True
vproviderA = self.vlayerA.dataProvider()
vproviderB = self.vlayerB.dataProvider()
# check for crs compatibility
crsA = vproviderA.crs()
crsB = vproviderB.crs()
if not crsA.isValid() or not crsB.isValid():
crs_match = None
else:
crs_match = crsA == crsB
writer = QgsVectorFileWriter(self.myName, self.myEncoding, vproviderA.fields(),
vproviderA.geometryType(), vproviderA.crs())
if writer.hasError():
return GEOS_EXCEPT, FEATURE_EXCEPT, crs_match, writer.errorMessage()
inFeatA = QgsFeature()
inFeatB = QgsFeature()
outFeat = QgsFeature()
index = ftools_utils.createIndex(vproviderB)
nElement = 0
# there is selection in input layer
if self.mySelectionA:
nFeat = self.vlayerA.selectedFeatureCount()
selectionA = self.vlayerA.selectedFeatures()
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
# we have selection in overlay layer
if self.mySelectionB:
selectionB = self.vlayerB.selectedFeaturesIds()
for inFeatA in selectionA:
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
geom = QgsGeometry(inFeatA.geometry())
atMap = inFeatA.attributes()
intersects = index.intersects(geom.boundingBox())
found = False
first = True
for id in intersects:
if id in selectionB:
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
if tmpGeom.intersects(geom):
found = True
if first:
outFeat.setGeometry(QgsGeometry(tmpGeom))
first = False
else:
try:
cur_geom = QgsGeometry(outFeat.geometry())
new_geom = QgsGeometry(cur_geom.combine(tmpGeom))
outFeat.setGeometry(QgsGeometry(new_geom))
except:
GEOS_EXCEPT = False
break
if found:
try:
cur_geom = QgsGeometry(outFeat.geometry())
new_geom = QgsGeometry(geom.intersection(cur_geom))
if new_geom.wkbType() == 0:
int_com = QgsGeometry(geom.combine(cur_geom))
int_sym = QgsGeometry(geom.symDifference(cur_geom))
new_geom = QgsGeometry(int_com.difference(int_sym))
try:
outFeat.setGeometry(new_geom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
except:
GEOS_EXCEPT = False
continue
# we have no selection in overlay layer
else:
for inFeatA in selectionA:
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
geom = QgsGeometry(inFeatA.geometry())
atMap = inFeatA.attributes()
intersects = index.intersects(geom.boundingBox())
found = False
first = True
for id in intersects:
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
if tmpGeom.intersects(geom):
found = True
if first:
outFeat.setGeometry(QgsGeometry(tmpGeom))
first = False
else:
try:
cur_geom = QgsGeometry(outFeat.geometry())
new_geom = QgsGeometry(cur_geom.combine(tmpGeom))
outFeat.setGeometry(QgsGeometry(new_geom))
except:
GEOS_EXCEPT = False
break
if found:
try:
cur_geom = QgsGeometry(outFeat.geometry())
new_geom = QgsGeometry(geom.intersection(cur_geom))
if new_geom.wkbType() == 0:
int_com = QgsGeometry(geom.combine(cur_geom))
int_sym = QgsGeometry(geom.symDifference(cur_geom))
new_geom = QgsGeometry(int_com.difference(int_sym))
try:
outFeat.setGeometry(new_geom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
except:
GEOS_EXCEPT = False
continue
# there is no selection in input layer
else:
nFeat = vproviderA.featureCount()
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
# we have selection in overlay layer
if self.mySelectionB:
selectionB = self.vlayerB.selectedFeaturesIds()
fitA = vproviderA.getFeatures()
while fitA.nextFeature(inFeatA):
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
geom = QgsGeometry(inFeatA.geometry())
atMap = inFeatA.attributes()
intersects = index.intersects(geom.boundingBox())
found = False
first = True
for id in intersects:
if id in selectionB:
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
if tmpGeom.intersects(geom):
found = True
if first:
outFeat.setGeometry(QgsGeometry(tmpGeom))
first = False
else:
try:
cur_geom = QgsGeometry(outFeat.geometry())
new_geom = QgsGeometry(cur_geom.combine(tmpGeom))
outFeat.setGeometry(QgsGeometry(new_geom))
except:
GEOS_EXCEPT = False
break
if found:
try:
cur_geom = QgsGeometry(outFeat.geometry())
new_geom = QgsGeometry(geom.intersection(cur_geom))
if new_geom.wkbType() == 0:
int_com = QgsGeometry(geom.combine(cur_geom))
int_sym = QgsGeometry(geom.symDifference(cur_geom))
new_geom = QgsGeometry(int_com.difference(int_sym))
try:
outFeat.setGeometry(new_geom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
except:
GEOS_EXCEPT = False
continue
# we have no selection in overlay layer
else:
fitA = vproviderA.getFeatures()
while fitA.nextFeature(inFeatA):
nElement += 1
self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
geom = QgsGeometry(inFeatA.geometry())
atMap = inFeatA.attributes()
intersects = index.intersects(geom.boundingBox())
first = True
found = False
if len(intersects) > 0:
for id in intersects:
vproviderB.getFeatures(QgsFeatureRequest().setFilterFid(int(id))).nextFeature(inFeatB)
tmpGeom = QgsGeometry(inFeatB.geometry())
if tmpGeom.intersects(geom):
found = True
if first:
outFeat.setGeometry(QgsGeometry(tmpGeom))
first = False
else:
try:
cur_geom = QgsGeometry(outFeat.geometry())
new_geom = QgsGeometry(cur_geom.combine(tmpGeom))
outFeat.setGeometry(QgsGeometry(new_geom))
except:
GEOS_EXCEPT = False
break
if found:
try:
cur_geom = QgsGeometry(outFeat.geometry())
new_geom = QgsGeometry(geom.intersection(cur_geom))
if new_geom.wkbType() == 0:
int_com = QgsGeometry(geom.combine(cur_geom))
int_sym = QgsGeometry(geom.symDifference(cur_geom))
new_geom = QgsGeometry(int_com.difference(int_sym))
try:
outFeat.setGeometry(new_geom)
outFeat.setAttributes(atMap)
writer.addFeature(outFeat)
except:
FEATURE_EXCEPT = False
continue
except:
GEOS_EXCEPT = False
continue
del writer
return GEOS_EXCEPT, FEATURE_EXCEPT, crs_match, None
def checkParameter(self, layer, param):
if self.myFunction == 1:
if isinstance(param, unicode):
check = layer.dataProvider().fieldNameIndex(param)
if check == -1:
return (None, False)
else:
return (check, True)
else:
if isinstance(param, float) or isinstance(param, int):
return (param, False)
else:
return (None, False)
elif self.myFunction == 2:
if param is not None:
if isinstance(param, unicode):
check = layer.dataProvider().fieldNameIndex(param)
if check == -1:
return (None, False)
else:
return (check, True)
else:
return (None, False)
else:
return (True, False)
elif self.myFunction == 4:
if isinstance(param, unicode):
check = layer.dataProvider().fieldNameIndex(param)
if check == -1:
return (check, False)
else:
return (check, True)
else:
return (None, False)
def simpleMeasure(self, inGeom):
if inGeom.wkbType() == QGis.WKBPoint:
pt = QgsPoint()
pt = inGeom.asPoint()
attr1 = pt.x()
attr2 = pt.y()
else:
measure = QgsDistanceArea()
attr1 = measure.measure(inGeom)
if inGeom.type() == QGis.Polygon:
attr2 = self.perimMeasure(inGeom, measure)
else:
attr2 = attr1
return (attr1, attr2)
def perimMeasure(self, inGeom, measure):
value = 0.00
if inGeom.isMultipart():
poly = inGeom.asMultiPolygon()
for k in poly:
for j in k:
value = value + measure.measureLine(j)
else:
poly = inGeom.asPolygon()
for k in poly:
value = value + measure.measureLine(k)
return value