Skip to content

Commit

Permalink
Port extract specific nodes algorithm to new API
Browse files Browse the repository at this point in the history
Improvements:
- keep Z/M values if present in geometries
  • Loading branch information
nyalldawson committed Jul 28, 2017
1 parent ecaee1a commit becf690
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 57 deletions.
59 changes: 33 additions & 26 deletions python/plugins/processing/algs/qgis/ExtractSpecificNodes.py
Expand Up @@ -27,25 +27,23 @@

import math
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.core.parameters import ParameterVector, ParameterString
from processing.core.outputs import OutputVector
from processing.tools import dataobjects

from qgis.core import (QgsWkbTypes,
QgsFeature,
QgsFeatureSink,
QgsGeometry,
QgsField,
QgsApplication,
QgsProcessingUtils)
QgsProcessing,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterString,
QgsProcessingParameterFeatureSink,
QgsProcessingException)
from qgis.PyQt.QtCore import QVariant


class ExtractSpecificNodes(QgisAlgorithm):

INPUT_LAYER = 'INPUT_LAYER'
OUTPUT_LAYER = 'OUTPUT_LAYER'
INPUT = 'INPUT'
OUTPUT = 'OUTPUT'
NODES = 'NODES'

def group(self):
Expand All @@ -55,11 +53,12 @@ def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(ParameterVector(self.INPUT_LAYER,
self.tr('Input layer'), [dataobjects.TYPE_VECTOR_ANY]))
self.addParameter(ParameterString(self.NODES,
self.tr('Node indices'), default='0'))
self.addOutput(OutputVector(self.OUTPUT_LAYER, self.tr('Nodes'), datatype=[dataobjects.TYPE_VECTOR_POINT]))
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input layer'), [QgsProcessing.TypeVectorAny]))
self.addParameter(QgsProcessingParameterString(self.NODES,
self.tr('Node indices'), defaultValue='0'))

self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Nodes'), QgsProcessing.TypeVectorPoint))

def name(self):
return 'extractspecificnodes'
Expand All @@ -68,34 +67,42 @@ def displayName(self):
return self.tr('Extract specific nodes')

def processAlgorithm(self, parameters, context, feedback):
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)

fields = layer.fields()
source = self.parameterAsSource(parameters, self.INPUT, context)
fields = source.fields()
fields.append(QgsField('node_pos', QVariant.Int))
fields.append(QgsField('node_index', QVariant.Int))
fields.append(QgsField('distance', QVariant.Double))
fields.append(QgsField('angle', QVariant.Double))
fields.append(QgsField('NUM_FIELD', QVariant.Int))

wkb_type = QgsWkbTypes.Point
if QgsWkbTypes.hasM(source.wkbType()):
wkb_type = QgsWkbTypes.addM(wkb_type)
if QgsWkbTypes.hasZ(source.wkbType()):
wkb_type = QgsWkbTypes.addZ(wkb_type)

writer = self.getOutputFromName(
self.OUTPUT_LAYER).getVectorWriter(fields, QgsWkbTypes.Point, layer.crs(), context)
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
fields, wkb_type, source.sourceCrs())

node_indices_string = self.getParameterValue(self.NODES)
node_indices_string = self.parameterAsString(parameters, self.NODES, context)
indices = []
for node in node_indices_string.split(','):
try:
indices.append(int(node))
except:
raise GeoAlgorithmExecutionException(
raise QgsProcessingException(
self.tr('\'{}\' is not a valid node index').format(node))

features = QgsProcessingUtils.getFeatures(layer, context)
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
features = source.getFeatures()
total = 100.0 / source.featureCount() if source.featureCount() else 0

for current, f in enumerate(features):
if feedback.isCanceled():
break

input_geometry = f.geometry()
if not input_geometry:
writer.addFeature(f, QgsFeatureSink.FastInsert)
sink.addFeature(f, QgsFeatureSink.FastInsert)
else:
total_nodes = input_geometry.geometry().nCoordinates()

Expand All @@ -122,8 +129,8 @@ def processAlgorithm(self, parameters, context, feedback):
point = input_geometry.vertexAt(node_index)
output_feature.setGeometry(QgsGeometry(point))

writer.addFeature(output_feature, QgsFeatureSink.FastInsert)
sink.addFeature(output_feature, 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
Expand Up @@ -65,6 +65,7 @@
from .ExtendLines import ExtendLines
from .ExtentFromLayer import ExtentFromLayer
from .ExtractNodes import ExtractNodes
from .ExtractSpecificNodes import ExtractSpecificNodes
from .FixGeometry import FixGeometry
from .GeometryByExpression import GeometryByExpression
from .GridPolygon import GridPolygon
Expand Down Expand Up @@ -165,7 +166,6 @@
# from .Relief import Relief
# from .IdwInterpolation import IdwInterpolation
# from .TinInterpolation import TinInterpolation
# from .ExtractSpecificNodes import ExtractSpecificNodes
# from .RasterCalculator import RasterCalculator
# from .ExecuteSQL import ExecuteSQL
# from .FindProjection import FindProjection
Expand Down Expand Up @@ -211,7 +211,6 @@ def getAlgs(self):
# PointsAlongGeometry(),
# Relief(),
# IdwInterpolation(), TinInterpolation(),
# ExtractSpecificNodes(),
# RasterCalculator(),
# ExecuteSQL(), FindProjection(),
# TopoColor(), EliminateSelection()
Expand Down Expand Up @@ -241,6 +240,7 @@ def getAlgs(self):
ExtendLines(),
ExtentFromLayer(),
ExtractNodes(),
ExtractSpecificNodes(),
FixGeometry(),
GeometryByExpression(),
GridPolygon(),
Expand Down
58 changes: 29 additions & 29 deletions python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
Expand Up @@ -1412,35 +1412,35 @@ tests:
name: expected/extend_multilines.gml
type: vector

# - algorithm: qgis:extractspecificnodes
# name: Extract specific nodes lines
# params:
# INPUT_LAYER:
# name: lines.gml
# type: vector
# NODES: 0,-1,2,-2
# results:
# OUTPUT_LAYER:
# name: expected/extract_specific_nodes_lines.gml
# type: vector
# compare:
# fields:
# fid: skip
#
# - algorithm: qgis:extractspecificnodes
# name: Extract specific nodes polygons
# params:
# INPUT_LAYER:
# name: polys.gml
# type: vector
# NODES: 0,-1,5,-5
# results:
# OUTPUT_LAYER:
# name: expected/extract_specific_nodes_polys.gml
# type: vector
# compare:
# fields:
# fid: skip
- algorithm: qgis:extractspecificnodes
name: Extract specific nodes lines
params:
INPUT:
name: lines.gml
type: vector
NODES: 0,-1,2,-2
results:
OUTPUT:
name: expected/extract_specific_nodes_lines.gml
type: vector
compare:
fields:
fid: skip

- algorithm: qgis:extractspecificnodes
name: Extract specific nodes polygons
params:
INPUT:
name: polys.gml
type: vector
NODES: 0,-1,5,-5
results:
OUTPUT:
name: expected/extract_specific_nodes_polys.gml
type: vector
compare:
fields:
fid: skip

- algorithm: qgis:geometrybyexpression
name: Geometry by expression (point)
Expand Down

0 comments on commit becf690

Please sign in to comment.