Created
June 15, 2017 06:26
-
-
Save MarcoDuiker/2035bd38ecddbab511c320633fc01a48 to your computer and use it in GitHub Desktop.
supersum
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
##clip_layer=optional vector | |
##filter_expression=optional string | |
##polygon=boolean True | |
##point=boolean True | |
##line=boolean True | |
##sum_expression=string | |
##selected_features_only=boolean True | |
##sum_total=output number | |
##sum_result_table=output table | |
from qgis._core import * | |
from qgis.utils import iface | |
from processing import * | |
import csv | |
# input validation | |
clip_lyr = None | |
if clip_layer: | |
clip_lyr = getObject(clip_layer) | |
if not clip_lyr.geometryType() == QGis.Polygon: | |
raise GeoAlgorithmExecutionException("Clip layer must be of type Polygon") | |
filter_exp = False | |
if filter_expression: | |
filter_exp = QgsExpression(filter_expression) | |
if filter_exp.hasParserError(): | |
raise GeoAlgorithmExecutionException(filter_exp.parserErrorString()) | |
sum_exp = QgsExpression(sum_expression) | |
if sum_exp.hasParserError(): | |
raise GeoAlgorithmExecutionException(sum_exp.parserErrorString()) | |
# where filter function | |
def where(layer, exp, selected_features_only): | |
if selected_features_only: | |
features = processing.features(layer) | |
else: | |
features = layer.getFeatures() | |
if exp: | |
exp.prepare(layer.pendingFields()) | |
for feature in features: | |
if exp: | |
value = exp.evaluate(feature) | |
if exp.hasEvalError(): | |
# raise GeoAlgorithmExecutionException(exp.evalErrorString()) | |
progress.setInfo('-->' + 'Warning: ' + exp.evalErrorString()) | |
if bool(value): | |
yield feature | |
else: | |
yield feature | |
# main | |
sum_result = {} | |
sum_total = 0 | |
#loop al selected layers and sum using the sum expression skipping features with the where filter. Optionally clip first | |
for layer in iface.legendInterface().selectedLayers(): | |
if (layer.geometryType() == 2 and polygon) or (layer.geometryType() == 1 and line) or (layer.geometryType() == 1 and point): | |
progress.setInfo('Processing layer: ' + layer.name() ) | |
sum_result[layer.name()] = 0 | |
if clip_lyr: | |
result = processing.runalg('qgis:clip', layer, clip_lyr, None) | |
layer_to_process = QgsVectorLayer(result["OUTPUT"],'layer_clipped',"ogr") | |
else: | |
layer_to_process = layer | |
sum_exp.prepare(layer_to_process.pendingFields()) | |
for feat in where(layer_to_process, filter_exp, selected_features_only): | |
value = sum_exp.evaluate(feat) | |
if sum_exp.hasEvalError(): | |
#raise GeoAlgorithmExecutionException(sum_exp.evalErrorString()) | |
progress.setInfo('-->' + 'Warning: ' + sum_exp.evalErrorString()) | |
elif value: | |
sum_total = sum_total + value | |
sum_result[layer.name()] = sum_result[layer.name()] + value | |
progress.setInfo('-->' + str(sum_result[layer.name()]) ) | |
sum_result['Total'] = sum_total | |
progress.setInfo('=============================+ ' ) | |
progress.setInfo('Total sum: ' + str(sum_total) ) | |
progress.setInfo(' ') | |
with open(sum_result_table, 'wt') as f: | |
writer = csv.writer(f) | |
writer.writerow( ('Layer', 'Sum') ) | |
for key, value in sum_result.items(): | |
writer.writerow((key,value)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"ALG_DESC": "Supersum sums an expression over all selected layers. \n\nOptionally the layers will first be clipped with a clip layer. Furthermore there is an option to filter the features by an expression or the type of the layer (point, line or polygon).\n\nExpressions are the usual QGIS expressions.", "sum_total": "The grand total of the sum expression over all selected layers.", "sum_expression": "A valid QGIS expression evaluating to a result which can be summed using the python + operator. Usually a float or an int will do.\n\nExample: $area\n\nTip: Use one of the selected layers and build an expression with the expression builder in the field calculator. Copy and paste the expression in the sum expression field.", "polygon": "When selected polygon layers will be summed.", "clip_layer": "An optional layer to clip the features of the selected layers which will be summed.\n\nOnly features within the clip layer will be summed.", "point": "When selected point layers will be summed.", "ALG_CREATOR": "Marco Duiker -- MD-kwadraat", "filter_expression": "A valid QGIS expression evaluating to True or False. Only records where the filter expression evaluates to True will be summed.\n\nExample: \"Field name\" = 'an interesting value'\n\nTip: Use one of the selected layers and build an expression with the expression builder in the field calculator. Copy and paste the expression in the filter expression field.\n", "ALG_VERSION": "0.3", "ALG_HELP_CREATOR": "Marco Duiker -- MD-kwadraat", "sum_result_table": "A table with layer names and the total of the sum expression for that layer.\n\nAlso a record with the grand total is included.", "line": "When selected line layers will be summed."} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Algorithm description
Supersum sums an expression over all selected layers.
Optionally the layers will first be clipped with a clip layer. Furthermore there is an option to filter the features by an expression or the type of the layer (point, line or polygon).
Expressions are the usual QGIS expressions.
Input parameters
clip layer
An optional layer to clip the features of the selected layers which will be summed.
Only features within the clip layer will be summed.
filter expression
A valid QGIS expression evaluating to True or False. Only records where the filter expression evaluates to True will be summed.
Example: "Field name" = 'an interesting value'
Tip: Use one of the selected layers and build an expression with the expression builder in the field calculator. Copy and paste the expression in the filter expression field.
polygon
When selected polygon layers will be summed.
point
When selected point layers will be summed.
line
When selected line layers will be summed.
sum expression
A valid QGIS expression evaluating to a result which can be summed using the python + operator. Usually a float or an int will do.
Example: $area
Tip: Use one of the selected layers and build an expression with the expression builder in the field calculator. Copy and paste the expression in the sum expression field.
selected features only
Outputs
sum total
The grand total of the sum expression over all selected layers.
sum result table
A table with layer names and the total of the sum expression for that layer.
Also a record with the grand total is included.