Port Fix Geometry algorithm to new API

This commit is contained in:
Nyall Dawson 2017-06-26 12:44:11 +10:00
parent ec7477cac7
commit b88ad8e1ce
3 changed files with 36 additions and 38 deletions

View File

@ -27,16 +27,15 @@ __revision__ = '$Format:%H$'
from qgis.core import (QgsWkbTypes, from qgis.core import (QgsWkbTypes,
QgsFeatureSink, QgsFeatureSink,
QgsFeatureRequest,
QgsProcessingFeatureSource,
QgsGeometry, QgsGeometry,
QgsApplication, QgsProcessingParameterDefinition,
QgsMessageLog, QgsProcessingParameterFeatureSource,
QgsProcessingUtils) QgsProcessingParameterFeatureSink,
QgsProcessingOutputVectorLayer)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.parameters import ParameterVector
from processing.core.outputs import OutputVector
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.tools import dataobjects
class FixGeometry(QgisAlgorithm): class FixGeometry(QgisAlgorithm):
@ -52,11 +51,9 @@ class FixGeometry(QgisAlgorithm):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.addParameter(ParameterVector(self.INPUT, self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Input layer'), [QgsProcessingParameterDefinition.TypeVectorLine, QgsProcessingParameterDefinition.TypeVectorPolygon]))
self.tr('Input Layer'), self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Fixed geometries')))
[dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_LINE])) self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Fixed geometries")))
self.addOutput(OutputVector(self.OUTPUT,
self.tr('Layer with fixed geometries')))
def name(self): def name(self):
return 'fixgeometries' return 'fixgeometries'
@ -65,22 +62,22 @@ class FixGeometry(QgisAlgorithm):
return self.tr('Fix geometries') return self.tr('Fix geometries')
def processAlgorithm(self, parameters, context, feedback): def processAlgorithm(self, parameters, context, feedback):
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) source = self.parameterAsSource(parameters, self.INPUT, context)
writer = self.getOutputFromName( (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
self.OUTPUT).getVectorWriter(layer.fields(), QgsWkbTypes.multiType(layer.wkbType()), layer.crs(), context) source.fields(), QgsWkbTypes.multiType(source.wkbType()), source.sourceCrs())
features = QgsProcessingUtils.getFeatures(layer, context) features = source.getFeatures(QgsFeatureRequest(), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks)
if QgsProcessingUtils.featureCount(layer, context) == 0: total = 100.0 / source.featureCount() if source.featureCount() else 0
raise GeoAlgorithmExecutionException(self.tr('There are no features in the input layer'))
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
for current, inputFeature in enumerate(features): for current, inputFeature in enumerate(features):
if feedback.isCanceled():
break
outputFeature = inputFeature outputFeature = inputFeature
if inputFeature.geometry(): if inputFeature.geometry():
outputGeometry = inputFeature.geometry().makeValid() outputGeometry = inputFeature.geometry().makeValid()
if not outputGeometry: if not outputGeometry:
QgsMessageLog.logMessage('makeValid failed for feature {}'.format(inputFeature.id()), self.tr('Processing'), QgsMessageLog.WARNING) feedback.pushInfo('makeValid failed for feature {}'.format(inputFeature.id()))
if outputGeometry.wkbType() == QgsWkbTypes.Unknown or QgsWkbTypes.flatType(outputGeometry.geometry().wkbType()) == QgsWkbTypes.GeometryCollection: if outputGeometry.wkbType() == QgsWkbTypes.Unknown or QgsWkbTypes.flatType(outputGeometry.geometry().wkbType()) == QgsWkbTypes.GeometryCollection:
tmpGeometries = outputGeometry.asGeometryCollection() tmpGeometries = outputGeometry.asGeometryCollection()
@ -89,7 +86,7 @@ class FixGeometry(QgisAlgorithm):
try: try:
g.convertToMultiType() g.convertToMultiType()
outputFeature.setGeometry(QgsGeometry(g)) outputFeature.setGeometry(QgsGeometry(g))
writer.addFeature(outputFeature, QgsFeatureSink.FastInsert) sink.addFeature(outputFeature, QgsFeatureSink.FastInsert)
except: except:
pass pass
feedback.setProgress(int(current * total)) feedback.setProgress(int(current * total))
@ -98,7 +95,7 @@ class FixGeometry(QgisAlgorithm):
outputGeometry.convertToMultiType() outputGeometry.convertToMultiType()
outputFeature.setGeometry(outputGeometry) outputFeature.setGeometry(outputGeometry)
writer.addFeature(outputFeature, QgsFeatureSink.FastInsert) sink.addFeature(outputFeature, QgsFeatureSink.FastInsert)
feedback.setProgress(int(current * total)) feedback.setProgress(int(current * total))
del writer return {self.OUTPUT: dest_id}

View File

@ -54,6 +54,7 @@ from .DensifyGeometries import DensifyGeometries
from .DensifyGeometriesInterval import DensifyGeometriesInterval from .DensifyGeometriesInterval import DensifyGeometriesInterval
from .DropGeometry import DropGeometry from .DropGeometry import DropGeometry
from .ExtentFromLayer import ExtentFromLayer from .ExtentFromLayer import ExtentFromLayer
from .FixGeometry import FixGeometry
from .GridPolygon import GridPolygon from .GridPolygon import GridPolygon
from .ImportIntoPostGIS import ImportIntoPostGIS from .ImportIntoPostGIS import ImportIntoPostGIS
from .Merge import Merge from .Merge import Merge
@ -168,7 +169,6 @@ from .VectorSplit import VectorSplit
# from .ServiceAreaFromLayer import ServiceAreaFromLayer # from .ServiceAreaFromLayer import ServiceAreaFromLayer
# from .TruncateTable import TruncateTable # from .TruncateTable import TruncateTable
# from .Polygonize import Polygonize # from .Polygonize import Polygonize
# from .FixGeometry import FixGeometry
# from .ExecuteSQL import ExecuteSQL # from .ExecuteSQL import ExecuteSQL
# from .FindProjection import FindProjection # from .FindProjection import FindProjection
# from .TopoColors import TopoColor # from .TopoColors import TopoColor
@ -240,7 +240,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
# ShortestPathPointToPoint(), ShortestPathPointToLayer(), # ShortestPathPointToPoint(), ShortestPathPointToLayer(),
# ShortestPathLayerToPoint(), ServiceAreaFromPoint(), # ShortestPathLayerToPoint(), ServiceAreaFromPoint(),
# ServiceAreaFromLayer(), TruncateTable(), Polygonize(), # ServiceAreaFromLayer(), TruncateTable(), Polygonize(),
# FixGeometry(), ExecuteSQL(), FindProjection(), # ExecuteSQL(), FindProjection(),
# TopoColor(), EliminateSelection() # TopoColor(), EliminateSelection()
# ] # ]
algs = [AddTableField(), algs = [AddTableField(),
@ -257,6 +257,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
DensifyGeometriesInterval(), DensifyGeometriesInterval(),
DropGeometry(), DropGeometry(),
ExtentFromLayer(), ExtentFromLayer(),
FixGeometry(),
GridPolygon(), GridPolygon(),
ImportIntoPostGIS(), ImportIntoPostGIS(),
Merge(), Merge(),

View File

@ -2275,18 +2275,18 @@ tests:
# OUTPUT_LAYER: # OUTPUT_LAYER:
# name: expected/zonal_statistics.gml # name: expected/zonal_statistics.gml
# type: vector # type: vector
#
# - algorithm: qgis:fixgeometries - algorithm: qgis:fixgeometries
# name: Fix geometries name: Fix geometries
# params: params:
# INPUT: INPUT:
# name: invalidgeometries.gml name: invalidgeometries.gml
# type: vector type: vector
# results: results:
# OUTPUT: OUTPUT:
# name: expected/valid.gml name: expected/valid.gml
# type: vector type: vector
#
# - algorithm: qgis:polygonize # - algorithm: qgis:polygonize
# name: Polygonize # name: Polygonize
# params: # params: