algorithm_FindDuplicates.py

Source Code - Michael Kuerbs, 2018-10-08 09:49 AM

Download (5.94 KB)

 
1
# -*- coding: utf-8 -*-
2

    
3
"""
4
/***************************************************************************
5
 TlugProcessing
6
                                 Find duplicates
7
 TLUG Algorithms
8
                              -------------------
9
        begin                : 2017-10-25
10
        copyright            : (C) 2017 by Thüringer Landesanstalt für Umwelt und Geologie (TLUG)
11
        email                : [email protected]
12
 ***************************************************************************/
13

14
/***************************************************************************
15
 *                                                                         *
16
 *   This program is free software; you can redistribute it and/or modify  *
17
 *   it under the terms of the GNU General Public License as published by  *
18
 *   the Free Software Foundation; either version 2 of the License, or     *
19
 *   (at your option) any later version.                                   *
20
 *                                                                         *
21
 ***************************************************************************/
22
"""
23

    
24
__author__ = 'Michael Kürbs'
25
__date__ = '2018-07-31'
26
__copyright__ = '(C) 2017 Michael Kürbs by Thüringer Landesanstalt für Umwelt und Geologie (TLUG)'
27

    
28
# This will get replaced with a git SHA1 when you do a git archive
29

    
30
__revision__ = '$Format:%H$'
31

    
32
from qgis.core import (QgsExpression,
33
                       QgsProcessing,
34
                       QgsExpressionContext,
35
                       QgsExpressionContextScope,
36
                       QgsVectorLayer,
37
                       QgsProcessingAlgorithm,
38
                       QgsProcessingException,
39
                       QgsProcessingParameterVectorLayer,
40
                       QgsProcessingParameterExpression,
41
                       QgsProcessingParameterEnum,
42
                       QgsProcessingOutputVectorLayer)
43
from PyQt5.QtCore import QCoreApplication
44
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
45

    
46

    
47
class FindDuplicates(QgisAlgorithm):#QgsProcessingAlgorithm):
48
    """
49
    This is an algorithm that selects all duplicates in a table field.
50
    """
51

    
52
    INPUT = 'INPUT'
53
    EXPRESSION = 'EXPRESSION'
54
    OUTPUT = 'OUTPUT'
55

    
56
    def initAlgorithm(self, config):
57
        """
58
        Here we define the inputs and output of the algorithm, along
59
        with some other properties.
60
        """
61

    
62
        self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT, self.tr('Input layer'), types=[QgsProcessing.TypeVector]))
63

    
64
        self.addParameter(QgsProcessingParameterExpression(self.EXPRESSION,
65
                                                           self.tr('Expression'), parentLayerParameterName=self.INPUT))
66
        self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Selected (attribute)')))
67

    
68

    
69

    
70
    def processAlgorithm(self, parameters, context, feedback):
71
        """
72
        Here is where the processing itself takes place.
73
        """
74

    
75
        vectorLayer= self.parameterAsVectorLayer(parameters, self.INPUT, context)
76
        expression = self.parameterAsString(parameters, self.EXPRESSION, context)
77
        expr=QgsExpression(expression)
78
        if expr.hasParserError():
79
            raise QgsProcessingException(expr.parserErrorString())
80

    
81
        context = QgsExpressionContext()
82
        scope = QgsExpressionContextScope()
83

    
84
        count = vectorLayer.featureCount() if vectorLayer.featureCount() else 0
85
        total = 100.0 / count
86

    
87
        # And now we can process
88
        attributes=[]
89
        duplicates=[]
90
        index=0
91
        protokoll=[]
92
        #Iterating over Vector Layer
93
        iter = vectorLayer.getFeatures()
94
        for current, feature in enumerate(iter):
95
            try:
96
                #create value from Expression
97
                scope.setFeature(feature)
98
                context.appendScope(scope)
99
                
100
                value=expr.evaluate(context)
101
            except:
102
                msg="Error while run Expression" + str( expr.expression() ) + " on feature " + str( feature.attributes() ) 
103
                feedback.reportError(msg)
104
                raise QgsProcessingException(msg)
105
                
106
            try:
107
                #is the attribut in the list yet
108
                index=attributes.index(value)
109
                #index=attributes.index(feature[fidx])
110

    
111
            except ValueError: # value is not in the list
112
                index = -1
113
            except KeyError: # value is not in the list
114
                index = -1
115
            protokoll.append([str(value), "-->", str(index)])
116
            if index == -1: # add new attribute in the list
117
                attributes.append(value)
118
          
119
            else: # it is a duplicate
120
                duplicates.append(feature.id())
121
                feedback.pushInfo( str(feature.id()) + " added")
122

    
123
            # Update the progress bar
124
            proz=int( current+1 * total)
125
            feedback.pushInfo( str( value ) +  " Index: " + str( index ) + " " + str(proz) + "%")
126
            feedback.setProgress( proz )
127
        if len( duplicates ) > 0:
128
            vectorLayer.select(duplicates)
129
            
130
        for item in protokoll:
131
            feedback.pushInfo( str( item ) ) 
132

    
133
        return {self.OUTPUT: parameters[self.INPUT]}
134

    
135
    def name(self):
136

    
137
        return 'FinddDuplicates'
138

    
139
    def displayName(self):
140

    
141
        return self.tr('Find Duplicates')
142

    
143
    def group(self):
144
        return self.tr('Vector selection')
145

    
146
    def groupId(self):
147
        return 'vectorselection'
148

    
149
    def __init__(self):
150
        super().__init__()
151

    
152
    def flags(self):
153
        return super().flags() | QgsProcessingAlgorithm.FlagNoThreading
154

    
155
    def metadata(self):
156
        return self.tr('TLUG:Find Duplicates, Select duplicate values in a feature field.')
157

    
158
    def description(self):
159
        return self.tr('Processing', 'Select duplicate values in a feature field.')
160

    
161
    def tr(self, string):
162
        return QCoreApplication.translate('Processing', string)
163

    
164
    def createInstance(self):
165
        return FindDuplicates()
166