Skip to content

Commit

Permalink
Port Join Attributes alg to new API
Browse files Browse the repository at this point in the history
Improvements:
- don't fetch unused geometry for joined table
  • Loading branch information
nyalldawson committed Aug 5, 2017
1 parent 572dada commit adda744
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 56 deletions.
81 changes: 42 additions & 39 deletions python/plugins/processing/algs/qgis/JoinAttributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,25 @@

from qgis.core import (QgsFeature,
QgsFeatureSink,
QgsApplication,
QgsProcessingUtils)
QgsFeatureRequest,
QgsProcessingParameterFeatureSource,
QgsProcessingUtils,
QgsProcessingParameterField,
QgsProcessingParameterFeatureSink)

from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterTable
from processing.core.parameters import ParameterTableField
from processing.core.outputs import OutputVector
from processing.tools import vector

pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]


class JoinAttributes(QgisAlgorithm):

OUTPUT_LAYER = 'OUTPUT_LAYER'
INPUT_LAYER = 'INPUT_LAYER'
INPUT_LAYER_2 = 'INPUT_LAYER_2'
TABLE_FIELD = 'TABLE_FIELD'
TABLE_FIELD_2 = 'TABLE_FIELD_2'
OUTPUT = 'OUTPUT'
INPUT = 'INPUT'
INPUT_2 = 'INPUT_2'
FIELD = 'FIELD'
FIELD_2 = 'FIELD_2'

def group(self):
return self.tr('Vector general tools')
Expand All @@ -58,16 +57,15 @@ def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(ParameterVector(self.INPUT_LAYER,
self.tr('Input layer')))
self.addParameter(ParameterTable(self.INPUT_LAYER_2,
self.tr('Input layer 2'), False))
self.addParameter(ParameterTableField(self.TABLE_FIELD,
self.tr('Table field'), self.INPUT_LAYER))
self.addParameter(ParameterTableField(self.TABLE_FIELD_2,
self.tr('Table field 2'), self.INPUT_LAYER_2))
self.addOutput(OutputVector(self.OUTPUT_LAYER,
self.tr('Joined layer')))
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input layer')))
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT_2,
self.tr('Input layer 2')))
self.addParameter(QgsProcessingParameterField(self.FIELD,
self.tr('Table field'), parentLayerParameterName=self.INPUT))
self.addParameter(QgsProcessingParameterField(self.FIELD_2,
self.tr('Table field 2'), parentLayerParameterName=self.INPUT_2))
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Joined layer')))

def name(self):
return 'joinattributestable'
Expand All @@ -76,26 +74,27 @@ def displayName(self):
return self.tr('Join attributes table')

def processAlgorithm(self, parameters, context, feedback):
input = self.getParameterValue(self.INPUT_LAYER)
input2 = self.getParameterValue(self.INPUT_LAYER_2)
output = self.getOutputFromName(self.OUTPUT_LAYER)
field = self.getParameterValue(self.TABLE_FIELD)
field2 = self.getParameterValue(self.TABLE_FIELD_2)
input = self.parameterAsSource(parameters, self.INPUT, context)
input2 = self.parameterAsSource(parameters, self.INPUT_2, context)
field = self.parameterAsString(parameters, self.FIELD, context)
field2 = self.parameterAsString(parameters, self.FIELD_2, context)

layer = QgsProcessingUtils.mapLayerFromString(input, context)
joinField1Index = layer.fields().lookupField(field)
joinField1Index = input.fields().lookupField(field)
joinField2Index = input2.fields().lookupField(field2)

layer2 = QgsProcessingUtils.mapLayerFromString(input2, context)
joinField2Index = layer2.fields().lookupField(field2)
outFields = vector.combineFields(input.fields(), input2.fields())

outFields = vector.combineVectorFields(layer, layer2)
writer = output.getVectorWriter(outFields, layer.wkbType(), layer.crs(), context)
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
outFields, input.wkbType(), input.sourceCrs())

# Cache attributes of Layer 2
# Cache attributes of input2
cache = {}
features = QgsProcessingUtils.getFeatures(layer2, context)
total = 100.0 / layer2.featureCount() if layer2.featureCount() else 0
features = input2.getFeatures(QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry))
total = 100.0 / input2.featureCount() if input2.featureCount() else 0
for current, feat in enumerate(features):
if feedback.isCanceled():
break

attrs = feat.attributes()
joinValue2 = str(attrs[joinField2Index])
if joinValue2 not in cache:
Expand All @@ -104,14 +103,18 @@ def processAlgorithm(self, parameters, context, feedback):

# Create output vector layer with additional attribute
outFeat = QgsFeature()
features = QgsProcessingUtils.getFeatures(layer, context)
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
features = input.getFeatures()
total = 100.0 / input.featureCount() if input.featureCount() else 0
for current, feat in enumerate(features):
if feedback.isCanceled():
break

outFeat.setGeometry(feat.geometry())
attrs = feat.attributes()
joinValue1 = str(attrs[joinField1Index])
attrs.extend(cache.get(joinValue1, []))
outFeat.setAttributes(attrs)
writer.addFeature(outFeat, QgsFeatureSink.FastInsert)
sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
feedback.setProgress(int(current * total))
del writer

return {self.OUTPUT: dest_id}
4 changes: 2 additions & 2 deletions python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
from .ImportIntoPostGIS import ImportIntoPostGIS
from .ImportIntoSpatialite import ImportIntoSpatialite
from .Intersection import Intersection
from .JoinAttributes import JoinAttributes
from .LinesIntersection import LinesIntersection
from .LinesToPolygons import LinesToPolygons
from .MeanCoords import MeanCoords
Expand Down Expand Up @@ -151,7 +152,6 @@
# from .StatisticsByCategories import StatisticsByCategories
# from .FieldsCalculator import FieldsCalculator
# from .FieldPyculator import FieldsPyculator
# from .JoinAttributes import JoinAttributes
# from .PointsDisplacement import PointsDisplacement
# from .PointsFromPolygons import PointsFromPolygons
# from .PointsFromLines import PointsFromLines
Expand Down Expand Up @@ -189,7 +189,6 @@ def getAlgs(self):
# ExtractByLocation(),
# SpatialJoin(),
# GeometryConvert(), FieldsCalculator(),
# JoinAttributes(),
# FieldsPyculator(),
# StatisticsByCategories(),
# RasterLayerStatistics(), PointsDisplacement(),
Expand Down Expand Up @@ -249,6 +248,7 @@ def getAlgs(self):
ImportIntoPostGIS(),
ImportIntoSpatialite(),
Intersection(),
JoinAttributes(),
LinesIntersection(),
LinesToPolygons(),
MeanCoords(),
Expand Down
30 changes: 15 additions & 15 deletions python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2265,21 +2265,21 @@ tests:
- expected/points_to_path_grouped2.gml
type: vector

# - algorithm: qgis:joinattributestable
# name: join the attribute table by common field
# params:
# INPUT_LAYER:
# name: points.gml
# type: vector
# INPUT_LAYER_2:
# name: table.dbf
# type: table
# TABLE_FIELD: id
# TABLE_FIELD_2: ID
# results:
# OUTPUT_LAYER:
# name: expected/join_attribute_table.gml
# type: vector
- algorithm: qgis:joinattributestable
name: join the attribute table by common field
params:
INPUT:
name: points.gml
type: vector
INPUT_2:
name: table.dbf
type: table
FIELD: id
FIELD_2: ID
results:
OUTPUT:
name: expected/join_attribute_table.gml
type: vector

- algorithm: qgis:convexhull
name: Simple convex hull
Expand Down

0 comments on commit adda744

Please sign in to comment.