[FEATURE][processing] New extract by expression algorithm

Filters an input layer by expression
This commit is contained in:
Nyall Dawson 2016-10-29 08:05:26 +10:00
parent a042c9decc
commit 74e64645e4
6 changed files with 151 additions and 5 deletions

View File

@ -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.
@ -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: >

View File

@ -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

View File

@ -56,6 +56,7 @@ from .VectorGridPolygons import VectorGridPolygons
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
@ -231,7 +232,7 @@ class QGISAlgorithmProvider(AlgorithmProvider):
ReliefAuto(), ZonalStatisticsQgis(),
IdwInterpolationZValue(), IdwInterpolationAttribute(),
TinInterpolationZValue(), TinInterpolationAttribute(),
RemoveNullGeometry()
RemoveNullGeometry(), ExtractByExpression()
]
if hasMatplotlib:

View File

@ -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>

View File

@ -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>

View File

@ -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