3535 QgsStringStatisticalSummary ,
3636 QgsDateTimeStatisticalSummary ,
3737 QgsFeatureRequest ,
38- QgsProcessingUtils )
38+ QgsProcessingUtils ,
39+ QgsProcessingParameterFeatureSource ,
40+ QgsProcessingParameterTableField ,
41+ QgsProcessingParameterFileOutput ,
42+ QgsProcessingOutputHtml ,
43+ QgsProcessingOutputNumber )
3944
4045from processing .algs .qgis .QgisAlgorithm import QgisAlgorithm
41- from processing .core .parameters import ParameterTable
42- from processing .core .parameters import ParameterTableField
43- from processing .core .outputs import OutputHTML
44- from processing .core .outputs import OutputNumber
4546
4647pluginPath = os .path .split (os .path .split (os .path .dirname (__file__ ))[0 ])[0 ]
4748
@@ -85,35 +86,37 @@ def group(self):
8586
8687 def __init__ (self ):
8788 super ().__init__ ()
88- self .addParameter (ParameterTable (self .INPUT_LAYER ,
89- self .tr ('Input table' )))
90- self .addParameter (ParameterTableField (self .FIELD_NAME ,
91- self .tr ('Field to calculate statistics on' ),
92- self .INPUT_LAYER ))
93-
94- self .addOutput (OutputHTML (self .OUTPUT_HTML_FILE ,
95- self .tr ('Statistics' )))
96-
97- self .addOutput (OutputNumber (self .COUNT , self .tr ('Count' )))
98- self .addOutput (OutputNumber (self .UNIQUE , self .tr ('Number of unique values' )))
99- self .addOutput (OutputNumber (self .EMPTY , self .tr ('Number of empty (null) values' )))
100- self .addOutput (OutputNumber (self .FILLED , self .tr ('Number of non-empty values' )))
101- self .addOutput (OutputNumber (self .MIN , self .tr ('Minimum value' )))
102- self .addOutput (OutputNumber (self .MAX , self .tr ('Maximum value' )))
103- self .addOutput (OutputNumber (self .MIN_LENGTH , self .tr ('Minimum length' )))
104- self .addOutput (OutputNumber (self .MAX_LENGTH , self .tr ('Maximum length' )))
105- self .addOutput (OutputNumber (self .MEAN_LENGTH , self .tr ('Mean length' )))
106- self .addOutput (OutputNumber (self .CV , self .tr ('Coefficient of Variation' )))
107- self .addOutput (OutputNumber (self .SUM , self .tr ('Sum' )))
108- self .addOutput (OutputNumber (self .MEAN , self .tr ('Mean value' )))
109- self .addOutput (OutputNumber (self .STD_DEV , self .tr ('Standard deviation' )))
110- self .addOutput (OutputNumber (self .RANGE , self .tr ('Range' )))
111- self .addOutput (OutputNumber (self .MEDIAN , self .tr ('Median' )))
112- self .addOutput (OutputNumber (self .MINORITY , self .tr ('Minority (rarest occurring value)' )))
113- self .addOutput (OutputNumber (self .MAJORITY , self .tr ('Majority (most frequently occurring value)' )))
114- self .addOutput (OutputNumber (self .FIRSTQUARTILE , self .tr ('First quartile' )))
115- self .addOutput (OutputNumber (self .THIRDQUARTILE , self .tr ('Third quartile' )))
116- self .addOutput (OutputNumber (self .IQR , self .tr ('Interquartile Range (IQR)' )))
89+
90+ self .addParameter (QgsProcessingParameterFeatureSource (self .INPUT_LAYER ,
91+ self .tr ('Input layer' )))
92+
93+ self .addParameter (QgsProcessingParameterTableField (self .FIELD_NAME ,
94+ self .tr ('Field to calculate statistics on' ),
95+ None , self .INPUT_LAYER , QgsProcessingParameterTableField .Any ))
96+
97+ self .addParameter (QgsProcessingParameterFileOutput (self .OUTPUT_HTML_FILE , self .tr ('Statistics' ), self .tr ('HTML files (*.html)' )))
98+ self .addOutput (QgsProcessingOutputHtml (self .OUTPUT_HTML_FILE , self .tr ('Statistics' )))
99+
100+ self .addOutput (QgsProcessingOutputNumber (self .COUNT , self .tr ('Count' )))
101+ self .addOutput (QgsProcessingOutputNumber (self .UNIQUE , self .tr ('Number of unique values' )))
102+ self .addOutput (QgsProcessingOutputNumber (self .EMPTY , self .tr ('Number of empty (null) values' )))
103+ self .addOutput (QgsProcessingOutputNumber (self .FILLED , self .tr ('Number of non-empty values' )))
104+ self .addOutput (QgsProcessingOutputNumber (self .MIN , self .tr ('Minimum value' )))
105+ self .addOutput (QgsProcessingOutputNumber (self .MAX , self .tr ('Maximum value' )))
106+ self .addOutput (QgsProcessingOutputNumber (self .MIN_LENGTH , self .tr ('Minimum length' )))
107+ self .addOutput (QgsProcessingOutputNumber (self .MAX_LENGTH , self .tr ('Maximum length' )))
108+ self .addOutput (QgsProcessingOutputNumber (self .MEAN_LENGTH , self .tr ('Mean length' )))
109+ self .addOutput (QgsProcessingOutputNumber (self .CV , self .tr ('Coefficient of Variation' )))
110+ self .addOutput (QgsProcessingOutputNumber (self .SUM , self .tr ('Sum' )))
111+ self .addOutput (QgsProcessingOutputNumber (self .MEAN , self .tr ('Mean value' )))
112+ self .addOutput (QgsProcessingOutputNumber (self .STD_DEV , self .tr ('Standard deviation' )))
113+ self .addOutput (QgsProcessingOutputNumber (self .RANGE , self .tr ('Range' )))
114+ self .addOutput (QgsProcessingOutputNumber (self .MEDIAN , self .tr ('Median' )))
115+ self .addOutput (QgsProcessingOutputNumber (self .MINORITY , self .tr ('Minority (rarest occurring value)' )))
116+ self .addOutput (QgsProcessingOutputNumber (self .MAJORITY , self .tr ('Majority (most frequently occurring value)' )))
117+ self .addOutput (QgsProcessingOutputNumber (self .FIRSTQUARTILE , self .tr ('First quartile' )))
118+ self .addOutput (QgsProcessingOutputNumber (self .THIRDQUARTILE , self .tr ('Third quartile' )))
119+ self .addOutput (QgsProcessingOutputNumber (self .IQR , self .tr ('Interquartile Range (IQR)' )))
117120
118121 def name (self ):
119122 return 'basicstatisticsforfields'
@@ -122,29 +125,35 @@ def displayName(self):
122125 return self .tr ('Basic statistics for fields' )
123126
124127 def processAlgorithm (self , parameters , context , feedback ):
125- layer = QgsProcessingUtils . mapLayerFromString ( self .getParameterValue ( self .INPUT_LAYER ) , context )
126- field_name = self .getParameterValue ( self .FIELD_NAME )
127- field = layer .fields ().at (layer .fields ().lookupField (field_name ))
128+ source = self .parameterAsSource ( parameters , self .INPUT_LAYER , context )
129+ field_name = self .parameterAsString ( parameters , self .FIELD_NAME , context )
130+ field = source .fields ().at (source .fields ().lookupField (field_name ))
128131
129- output_file = self .getOutputValue ( self .OUTPUT_HTML_FILE )
132+ output_file = self .parameterAsFileOutput ( parameters , self .OUTPUT_HTML_FILE , context )
130133
131- request = QgsFeatureRequest ().setFlags (QgsFeatureRequest .NoGeometry ).setSubsetOfAttributes ([field_name ], layer .fields ())
132- features = QgsProcessingUtils .getFeatures (layer , context , request )
133- count = QgsProcessingUtils .featureCount (layer , context )
134+ request = QgsFeatureRequest ().setFlags (QgsFeatureRequest .NoGeometry ).setSubsetOfAttributes ([field_name ], source .fields ())
135+ features = source .getFeatures (request )
136+ count = source .featureCount ()
134137
135138 data = []
136- data .append (self .tr ('Analyzed layer: {}' ).format (layer .name ()))
137139 data .append (self .tr ('Analyzed field: {}' ).format (field_name ))
140+ results = {}
138141
139142 if field .isNumeric ():
140- data .extend (self .calcNumericStats (features , feedback , field , count ))
143+ d , results = self .calcNumericStats (features , feedback , field , count )
144+ data .extend (d )
141145 elif field .type () in (QVariant .Date , QVariant .Time , QVariant .DateTime ):
142- data .extend (self .calcDateTimeStats (features , feedback , field , count ))
146+ d , results = self .calcDateTimeStats (features , feedback , field , count )
147+ data .extend (d )
143148 else :
144- data .extend (self .calcStringStats (features , feedback , field , count ))
149+ d , results = self .calcStringStats (features , feedback , field , count )
150+ data .extend (d )
145151
146152 self .createHTML (output_file , data )
147153
154+ results [self .OUTPUT_HTML_FILE ] = output_file
155+ return results
156+
148157 def calcNumericStats (self , features , feedback , field , count ):
149158 total = 100.0 / float (count )
150159 stat = QgsStatisticalSummary ()
@@ -155,23 +164,23 @@ def calcNumericStats(self, features, feedback, field, count):
155164
156165 cv = stat .stDev () / stat .mean () if stat .mean () != 0 else 0
157166
158- self .setOutputValue ( self . COUNT , stat .count ())
159- self .setOutputValue ( self . UNIQUE , stat .variety ())
160- self .setOutputValue ( self . EMPTY , stat .countMissing ())
161- self .setOutputValue ( self . FILLED , count - stat .countMissing ())
162- self .setOutputValue ( self . MIN , stat .min ())
163- self .setOutputValue ( self . MAX , stat .max ())
164- self .setOutputValue ( self . RANGE , stat .range ())
165- self .setOutputValue ( self . SUM , stat .sum ())
166- self .setOutputValue ( self . MEAN , stat .mean ())
167- self .setOutputValue ( self . MEDIAN , stat .median ())
168- self .setOutputValue ( self . STD_DEV , stat .stDev ())
169- self .setOutputValue ( self . CV , cv )
170- self .setOutputValue ( self . MINORITY , stat .minority ())
171- self .setOutputValue ( self . MAJORITY , stat .majority ())
172- self .setOutputValue ( self . FIRSTQUARTILE , stat .firstQuartile ())
173- self .setOutputValue ( self . THIRDQUARTILE , stat .thirdQuartile ())
174- self .setOutputValue ( self . IQR , stat .interQuartileRange ())
167+ results = { self .COUNT : stat .count (),
168+ self .UNIQUE : stat .variety (),
169+ self .EMPTY : stat .countMissing (),
170+ self .FILLED : count - stat .countMissing (),
171+ self .MIN : stat .min (),
172+ self .MAX : stat .max (),
173+ self .RANGE : stat .range (),
174+ self .SUM : stat .sum (),
175+ self .MEAN : stat .mean (),
176+ self .MEDIAN : stat .median (),
177+ self .STD_DEV : stat .stDev (),
178+ self .CV : cv ,
179+ self .MINORITY : stat .minority (),
180+ self .MAJORITY : stat .majority (),
181+ self .FIRSTQUARTILE : stat .firstQuartile (),
182+ self .THIRDQUARTILE : stat .thirdQuartile (),
183+ self .IQR : stat .interQuartileRange ()}
175184
176185 data = []
177186 data .append (self .tr ('Count: {}' ).format (stat .count ()))
@@ -190,7 +199,7 @@ def calcNumericStats(self, features, feedback, field, count):
190199 data .append (self .tr ('First quartile: {}' ).format (stat .firstQuartile ()))
191200 data .append (self .tr ('Third quartile: {}' ).format (stat .thirdQuartile ()))
192201 data .append (self .tr ('Interquartile Range (IQR): {}' ).format (stat .interQuartileRange ()))
193- return data
202+ return data , results
194203
195204 def calcStringStats (self , features , feedback , field , count ):
196205 total = 100.0 / float (count )
@@ -200,15 +209,15 @@ def calcStringStats(self, features, feedback, field, count):
200209 feedback .setProgress (int (current * total ))
201210 stat .finalize ()
202211
203- self .setOutputValue ( self . COUNT , stat .count ())
204- self .setOutputValue ( self . UNIQUE , stat .countDistinct ())
205- self .setOutputValue ( self . EMPTY , stat .countMissing ())
206- self .setOutputValue ( self . FILLED , stat .count () - stat .countMissing ())
207- self .setOutputValue ( self . MIN , stat .min ())
208- self .setOutputValue ( self . MAX , stat .max ())
209- self .setOutputValue ( self . MIN_LENGTH , stat .minLength ())
210- self .setOutputValue ( self . MAX_LENGTH , stat .maxLength ())
211- self .setOutputValue ( self . MEAN_LENGTH , stat .meanLength ())
212+ results = { self .COUNT : stat .count (),
213+ self .UNIQUE : stat .countDistinct (),
214+ self .EMPTY : stat .countMissing (),
215+ self .FILLED : stat .count () - stat .countMissing (),
216+ self .MIN : stat .min (),
217+ self .MAX : stat .max (),
218+ self .MIN_LENGTH : stat .minLength (),
219+ self .MAX_LENGTH : stat .maxLength (),
220+ self .MEAN_LENGTH : stat .meanLength ()}
212221
213222 data = []
214223 data .append (self .tr ('Count: {}' ).format (count ))
@@ -220,7 +229,7 @@ def calcStringStats(self, features, feedback, field, count):
220229 data .append (self .tr ('Maximum length: {}' ).format (stat .maxLength ()))
221230 data .append (self .tr ('Mean length: {}' ).format (stat .meanLength ()))
222231
223- return data
232+ return data , results
224233
225234 def calcDateTimeStats (self , features , feedback , field , count ):
226235 total = 100.0 / float (count )
@@ -230,12 +239,12 @@ def calcDateTimeStats(self, features, feedback, field, count):
230239 feedback .setProgress (int (current * total ))
231240 stat .finalize ()
232241
233- self .setOutputValue ( self . COUNT , stat .count ())
234- self .setOutputValue ( self . UNIQUE , stat .countDistinct ())
235- self .setOutputValue ( self . EMPTY , stat .countMissing ())
236- self .setOutputValue ( self . FILLED , stat .count () - stat .countMissing ())
237- self .setOutputValue ( self . MIN , stat .statistic (QgsDateTimeStatisticalSummary .Min ))
238- self .setOutputValue ( self . MAX , stat .statistic (QgsDateTimeStatisticalSummary .Max ))
242+ results = { self .COUNT : stat .count (),
243+ self .UNIQUE : stat .countDistinct (),
244+ self .EMPTY : stat .countMissing (),
245+ self .FILLED : stat .count () - stat .countMissing (),
246+ self .MIN : stat .statistic (QgsDateTimeStatisticalSummary .Min ),
247+ self .MAX : stat .statistic (QgsDateTimeStatisticalSummary .Max )}
239248
240249 data = []
241250 data .append (self .tr ('Count: {}' ).format (count ))
@@ -244,7 +253,7 @@ def calcDateTimeStats(self, features, feedback, field, count):
244253 data .append (self .tr ('Minimum value: {}' ).format (field .displayString (stat .statistic (QgsDateTimeStatisticalSummary .Min ))))
245254 data .append (self .tr ('Maximum value: {}' ).format (field .displayString (stat .statistic (QgsDateTimeStatisticalSummary .Max ))))
246255
247- return data
256+ return data , results
248257
249258 def createHTML (self , outputFile , algData ):
250259 with codecs .open (outputFile , 'w' , encoding = 'utf-8' ) as f :
0 commit comments