Skip to content

Commit

Permalink
[FEATURE][processing] New extract by expression algorithm
Browse files Browse the repository at this point in the history
Filters an input layer by expression
  • Loading branch information
nyalldawson committed Oct 28, 2016
1 parent a042c9d commit 74e6464
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 5 deletions.
11 changes: 8 additions & 3 deletions python/plugins/processing/algs/help/qgis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,15 @@ qgis:exportaddgeometrycolumns: >
Depending on the geometry type of the vector layer, the attributes added to the table will be different.

qgis:extractbyattribute: >
This algorithms creates new vector layer that only contain certain features from an input layer. The criteria for adding features to the resulting layer is defined based on the values of an attribute from the input layer.
This algorithms creates a new vector layer that only contains matching features from an input layer. The criteria for adding features to the resulting layer is defined based on the values of an attribute from the input layer.

qgis:extractbyexpression: >
This algorithms creates a new vector layer that only contains matching features from an input layer. The criteria for adding features to the resulting layer is based on a QGIS expression.

For more information about expressions see the <a href ="{qgisdocs}/user_manual/working_with_vector/expression.html">user manual</a>

qgis:extractbylocation: >
This algorithms creates new vector layer that only contain certain features from an input layer. The criteria for adding features to the resulting layer is defined based on the spatial relationship between each feature and the features in an additional layer.
This algorithms creates a new vector layer that only contains matching features from an input layer. The criteria for adding features to the resulting layer is defined based on the spatial relationship between each feature and the features in an additional layer.

qgis:extractnodes: >
This algorithm takes a line or polygon layer and generates a point layer with points representing the nodes in the input lines or polygons. The attributes associated to each point are the same ones associated to the line or polygon that the point belongs to.
Expand Down Expand Up @@ -419,7 +424,7 @@ qgis:selectbyattributesum:
qgis:selectbyexpression: >
This algorithms creates a selection in a vector layer. The criteria for selecting features is based on a QGIS expression.

For more information about expressions see the<a href ="{qgisdocs}/user_manual/working_with_vector/expression.html">user manual</a>
For more information about expressions see the <a href ="{qgisdocs}/user_manual/working_with_vector/expression.html">user manual</a>


qgis:selectbylocation: >
Expand Down
67 changes: 67 additions & 0 deletions python/plugins/processing/algs/qgis/ExtractByExpression.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-

"""
***************************************************************************
ExtractByExpression.py
---------------------
Date : October 2016
Copyright : (C) 2016 by Nyall Dawson
***************************************************************************
* *
* 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__ = 'Nyall Dawson'
__date__ = 'October 2016'
__copyright__ = '(C) 2016, Nyall Dawson'

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

__revision__ = '$Format:%H$'

import processing
from qgis.core import QgsExpression, QgsVectorLayer, QgsFeatureRequest
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.core.parameters import ParameterVector
from processing.core.outputs import OutputVector
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.parameters import ParameterString
from processing.tools import dataobjects


class ExtractByExpression(GeoAlgorithm):

INPUT = 'INPUT'
EXPRESSION = 'EXPRESSION'
OUTPUT = 'OUTPUT'

def defineCharacteristics(self):
self.name, self.i18n_name = self.trAlgorithm('Extract by expression')
self.group, self.i18n_group = self.trAlgorithm('Vector selection tools')

self.addParameter(ParameterVector(self.INPUT,
self.tr('Input Layer')))
self.addParameter(ParameterString(self.EXPRESSION,
self.tr("Expression")))
self.addOutput(OutputVector(self.OUTPUT, self.tr('Extracted (expression)')))

def processAlgorithm(self, progress):
layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
expression_string = self.getParameterValue(self.EXPRESSION)
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs())

expression = QgsExpression(expression_string)
if not expression.hasParserError():
req = QgsFeatureRequest().setFilterExpression(expression_string)
else:
raise GeoAlgorithmExecutionException(expression.parserErrorString())

for f in layer.getFeatures(req):
writer.addFeature(f)

del writer
3 changes: 2 additions & 1 deletion python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
from .RandomExtract import RandomExtract
from .RandomExtractWithinSubsets import RandomExtractWithinSubsets
from .ExtractByLocation import ExtractByLocation
from .ExtractByExpression import ExtractByExpression
from .PointsInPolygon import PointsInPolygon
from .PointsInPolygonUnique import PointsInPolygonUnique
from .PointsInPolygonWeighted import PointsInPolygonWeighted
Expand Down Expand Up @@ -231,7 +232,7 @@ def __init__(self):
ReliefAuto(), ZonalStatisticsQgis(),
IdwInterpolationZValue(), IdwInterpolationAttribute(),
TinInterpolationZValue(), TinInterpolationAttribute(),
RemoveNullGeometry()
RemoveNullGeometry(), ExtractByExpression()
]

if hasMatplotlib:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>extract_expression</Name>
<ElementPath>extract_expression</ElementPath>
<!--POLYGON-->
<GeometryType>3</GeometryType>
<SRSName>EPSG:4326</SRSName>
<DatasetSpecificInfo>
<FeatureCount>2</FeatureCount>
<ExtentXMin>4.00000</ExtentXMin>
<ExtentXMax>10.00000</ExtentXMax>
<ExtentYMin>-3.00000</ExtentYMin>
<ExtentYMax>5.00000</ExtentYMax>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>name</Name>
<ElementPath>name</ElementPath>
<Type>String</Type>
<Width>5</Width>
</PropertyDefn>
<PropertyDefn>
<Name>intval</Name>
<ElementPath>intval</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>floatval</Name>
<ElementPath>floatval</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>4</gml:X><gml:Y>-3</gml:Y></gml:coord>
<gml:coord><gml:X>10</gml:X><gml:Y>5</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:extract_expression fid="polys.1">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>5,5 6,4 4,4 5,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>Aaaaa</ogr:name>
<ogr:intval>-33</ogr:intval>
<ogr:floatval>0</ogr:floatval>
</ogr:extract_expression>
</gml:featureMember>
<gml:featureMember>
<ogr:extract_expression fid="polys.3">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>6,1 10,1 10,-3 6,-3 6,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>7,0 7,-2 9,-2 9,0 7,0</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>ASDF</ogr:name>
<ogr:intval>0</ogr:intval>
</ogr:extract_expression>
</gml:featureMember>
</ogr:FeatureCollection>
Original file line number Diff line number Diff line change
Expand Up @@ -1212,4 +1212,16 @@ tests:
results:
OUTPUT_LAYER:
name: expected/remove_null_polys.gml
type: vector
type: vector

- algorithm: qgis:extractbyexpression
name: Extract by Expression
params:
EXPRESSION: left( "Name",1)='A'
INPUT:
name: polys.gml
type: vector
results:
OUTPUT:
name: expected/extract_expression.gml
type: vector

0 comments on commit 74e6464

Please sign in to comment.