QGIS/python/plugins/processing/algs/qgis/CheckValidity.py

187 lines
6.3 KiB
Python
Raw Normal View History

2015-05-22 13:18:00 +02:00
# -*- coding: utf-8 -*-
"""
***************************************************************************
CheckValidity.py
---------------------
Date : May 2015
Copyright : (C) 2015 by Arnaud Morvan
Email : arnaud dot morvan at camptocamp dot com
***************************************************************************
* *
* 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. *
* *
***************************************************************************
"""
__author__ = 'Arnaud Morvan'
__date__ = 'May 2015'
__copyright__ = '(C) 2015, Arnaud Morvan'
# This will get replaced with a git SHA1 when you do a git archive323
__revision__ = '$Format:%H$'
import os
2016-04-22 10:38:48 +02:00
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtCore import QVariant
from qgis.core import QgsSettings, QgsGeometry, QgsFeature, QgsField, QgsWkbTypes
2015-05-22 13:18:00 +02:00
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterSelection
from processing.core.outputs import OutputVector
from processing.tools import dataobjects, vector
settings_method_key = "/qgis/digitizing/validate_geometries"
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
2015-05-22 13:18:00 +02:00
class CheckValidity(GeoAlgorithm):
INPUT_LAYER = 'INPUT_LAYER'
METHOD = 'METHOD'
VALID_OUTPUT = 'VALID_OUTPUT'
INVALID_OUTPUT = 'INVALID_OUTPUT'
ERROR_OUTPUT = 'ERROR_OUTPUT'
def getIcon(self):
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'check_geometry.png'))
2015-05-22 13:18:00 +02:00
def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Check validity')
self.group, self.i18n_group = self.trAlgorithm('Vector geometry tools')
2015-05-22 13:18:00 +02:00
self.methods = [self.tr('The one selected in digitizing settings'),
'QGIS',
'GEOS']
2015-05-22 13:18:00 +02:00
self.addParameter(ParameterVector(
self.INPUT_LAYER,
self.tr('Input layer')))
2015-05-22 13:18:00 +02:00
self.addParameter(ParameterSelection(
self.METHOD,
self.tr('Method'),
self.methods))
2015-05-22 13:18:00 +02:00
self.addOutput(OutputVector(
self.VALID_OUTPUT,
self.tr('Valid output')))
self.addOutput(OutputVector(
self.INVALID_OUTPUT,
self.tr('Invalid output')))
self.addOutput(OutputVector(
self.ERROR_OUTPUT,
self.tr('Error output')))
def processAlgorithm(self, feedback):
settings = QgsSettings()
2015-05-22 13:18:00 +02:00
initial_method_setting = settings.value(settings_method_key, 1)
method = self.getParameterValue(self.METHOD)
if method != 0:
settings.setValue(settings_method_key, method)
try:
self.doCheck(feedback)
2015-05-22 13:18:00 +02:00
finally:
settings.setValue(settings_method_key, initial_method_setting)
def doCheck(self, feedback):
2015-05-22 13:18:00 +02:00
layer = dataobjects.getObjectFromUri(
self.getParameterValue(self.INPUT_LAYER))
settings = QgsSettings()
2015-05-22 13:18:00 +02:00
method = int(settings.value(settings_method_key, 1))
2017-01-20 08:03:06 +01:00
valid_output = self.getOutputFromName(self.VALID_OUTPUT)
valid_fields = layer.fields()
2017-01-20 08:03:06 +01:00
valid_writer = valid_output.getVectorWriter(
2015-05-22 13:18:00 +02:00
valid_fields,
layer.wkbType(),
2015-05-22 13:18:00 +02:00
layer.crs())
valid_count = 0
2017-01-20 08:03:06 +01:00
invalid_output = self.getOutputFromName(self.INVALID_OUTPUT)
invalid_fields = layer.fields().toList() + [
2015-05-22 13:18:00 +02:00
QgsField(name='_errors',
type=QVariant.String,
2015-05-22 13:18:00 +02:00
len=255)]
2017-01-20 08:03:06 +01:00
invalid_writer = invalid_output.getVectorWriter(
2015-05-22 13:18:00 +02:00
invalid_fields,
layer.wkbType(),
2015-05-22 13:18:00 +02:00
layer.crs())
invalid_count = 0
2017-01-20 08:03:06 +01:00
error_output = self.getOutputFromName(self.ERROR_OUTPUT)
2015-05-22 13:18:00 +02:00
error_fields = [
QgsField(name='message',
type=QVariant.String,
2015-05-22 13:18:00 +02:00
len=255)]
2017-01-20 08:03:06 +01:00
error_writer = error_output.getVectorWriter(
2015-05-22 13:18:00 +02:00
error_fields,
QgsWkbTypes.Point,
2015-05-22 13:18:00 +02:00
layer.crs())
error_count = 0
features = vector.features(layer)
total = 100.0 / len(features)
2015-05-22 13:18:00 +02:00
for current, inFeat in enumerate(features):
geom = inFeat.geometry()
2015-05-22 13:18:00 +02:00
attrs = inFeat.attributes()
valid = True
if not geom.isNull() and not geom.isEmpty():
2015-05-22 13:18:00 +02:00
errors = list(geom.validateGeometry())
if errors:
# QGIS method return a summary at the end
if method == 1:
errors.pop()
valid = False
reasons = []
for error in errors:
errFeat = QgsFeature()
error_geom = QgsGeometry.fromPoint(error.where())
errFeat.setGeometry(error_geom)
errFeat.setAttributes([error.what()])
error_writer.addFeature(errFeat)
error_count += 1
reasons.append(error.what())
reason = "\n".join(reasons)
if len(reason) > 255:
reason = reason[:252] + '...'
attrs.append(reason)
outFeat = QgsFeature()
outFeat.setGeometry(geom)
outFeat.setAttributes(attrs)
if valid:
valid_writer.addFeature(outFeat)
valid_count += 1
else:
invalid_writer.addFeature(outFeat)
invalid_count += 1
feedback.setProgress(int(current * total))
2015-05-22 13:18:00 +02:00
del valid_writer
del invalid_writer
del error_writer
if valid_count == 0:
2017-01-20 08:03:06 +01:00
valid_output.open = False
2015-05-22 13:18:00 +02:00
if invalid_count == 0:
2017-01-20 08:03:06 +01:00
invalid_output.open = False
2015-05-22 13:18:00 +02:00
if error_count == 0:
2017-01-20 08:03:06 +01:00
error_output.open = False