[processing] added ‘invalid feature handling’ option

This commit is contained in:
volaya 2016-12-15 09:43:31 +01:00 committed by Alexander Bruy
parent 3e80a52995
commit e8c149ed42
2 changed files with 39 additions and 1 deletions

View File

@ -52,6 +52,7 @@ class ProcessingConfig(object):
VECTOR_POLYGON_STYLE = 'VECTOR_POLYGON_STYLE'
SHOW_RECENT_ALGORITHMS = 'SHOW_RECENT_ALGORITHMS'
USE_SELECTED = 'USE_SELECTED'
FILTER_INVALID_GEOMETRIES = 'FILTER_INVALID_GEOMETRIES'
USE_FILENAME_AS_LAYER_NAME = 'USE_FILENAME_AS_LAYER_NAME'
KEEP_DIALOG_OPEN = 'KEEP_DIALOG_OPEN'
SHOW_DEBUG_IN_DIALOG = 'SHOW_DEBUG_IN_DIALOG'
@ -84,6 +85,14 @@ class ProcessingConfig(object):
ProcessingConfig.tr('General'),
ProcessingConfig.USE_SELECTED,
ProcessingConfig.tr('Use only selected features'), True))
invalidFeaturesOptions = [ProcessingConfig.tr('Do not filter (better performance'),
ProcessingConfig.tr('Ignore features with invalid geometries'),
ProcessingConfig.tr('Stop algorithm execution when a geometry is invalid')]
ProcessingConfig.addSetting(Setting(
ProcessingConfig.tr('General'),
ProcessingConfig.FILTER_INVALID_GEOMETRIES,
ProcessingConfig.tr('Invalid features filtering'), invalidFeaturesOptions[2],
valuetype=Setting.SELECTION, options=invalidFeaturesOptions))
ProcessingConfig.addSetting(Setting(
ProcessingConfig.tr('General'),
ProcessingConfig.USE_FILENAME_AS_LAYER_NAME,

View File

@ -24,6 +24,7 @@ from builtins import str
from builtins import range
from builtins import object
__author__ = 'Victor Olaya'
__date__ = 'February 2013'
__copyright__ = '(C) 2013, Victor Olaya'
@ -42,13 +43,14 @@ import io
import psycopg2
from osgeo import ogr
from qgis.PyQt.QtCore import QVariant, QSettings
from qgis.PyQt.QtCore import QVariant, QSettings, QCoreApplication
from qgis.core import (Qgis, QgsFields, QgsField, QgsGeometry, QgsRectangle, QgsWkbTypes,
QgsSpatialIndex, QgsProject, QgsMapLayer, QgsVectorLayer,
QgsVectorFileWriter, QgsDistanceArea, QgsDataSourceUri, QgsCredentials,
QgsFeatureRequest, QgsWkbTypes)
from processing.core.ProcessingConfig import ProcessingConfig
from processing.core.ProcessingLog import ProcessingLog
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.tools import dataobjects, spatialite, postgis
@ -95,6 +97,8 @@ def features(layer, request=QgsFeatureRequest()):
"""
class Features(object):
DO_NOT_CHECK, IGNORE, RAISE_EXCEPTION = range(3)
def __init__(self, layer, request):
self.layer = layer
self.selection = False
@ -104,6 +108,27 @@ def features(layer, request=QgsFeatureRequest()):
self.selection = True
else:
self.iter = layer.getFeatures(request)
invalidFeaturesMethod = ProcessingConfig.getSetting(ProcessingConfig.FILTER_INVALID_GEOMETRIES)
def filterFeature(f, ignoreInvalid):
geom = f.geometry()
if geom is None:
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
self.tr('Feature with NULL geometry found.'))
elif not geom.isGeosValid():
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
self.tr('GEOS geoprocessing error: One or more input features have invalid geometry.'))
if ignoreInvalid:
return False
else:
raise GeoAlgorithmExecutionException(self.tr('Features with invalid geometries found. Please fix these errors or specify the "Ignore invalid input features" flag'))
return True
if invalidFeaturesMethod == self.IGNORE:
self.iter = filter(filterFeature, self.iter, True)
elif invalidFeaturesMethod == self.RAISE_EXCEPTION:
self.iter = filter(filterFeature, self.iter, False)
def __iter__(self):
return self.iter
@ -113,6 +138,10 @@ def features(layer, request=QgsFeatureRequest()):
return int(self.layer.selectedFeatureCount())
else:
return int(self.layer.featureCount())
def tr(self, string):
return QCoreApplication.translate("FeatureIterator", string)
return Features(layer, request)