Skip to content

Commit 1b1dc7d

Browse files
committed
Port Extract Nodes to new API
Improvements: - Retain Z/M values from input geometries
1 parent bb344bc commit 1b1dc7d

File tree

3 files changed

+92
-75
lines changed

3 files changed

+92
-75
lines changed

python/plugins/processing/algs/qgis/ExtractNodes.py

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,16 @@
3131
from qgis.PyQt.QtGui import QIcon
3232
from qgis.PyQt.QtCore import QVariant
3333

34-
from qgis.core import QgsFeature, QgsGeometry, QgsWkbTypes, QgsField, QgsFeatureSink, QgsProcessingUtils
34+
from qgis.core import (QgsFeature,
35+
QgsGeometry,
36+
QgsWkbTypes,
37+
QgsField,
38+
QgsFeatureSink,
39+
QgsProcessing,
40+
QgsProcessingParameterFeatureSource,
41+
QgsProcessingParameterFeatureSink)
3542

3643
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
37-
from processing.core.parameters import ParameterVector
38-
from processing.core.outputs import OutputVector
39-
from processing.tools import dataobjects, vector
4044

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

@@ -56,12 +60,10 @@ def __init__(self):
5660
super().__init__()
5761

5862
def initAlgorithm(self, config=None):
59-
self.addParameter(ParameterVector(self.INPUT,
60-
self.tr('Input layer'),
61-
[dataobjects.TYPE_VECTOR_POLYGON,
62-
dataobjects.TYPE_VECTOR_LINE]))
63+
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
64+
self.tr('Input layer')))
6365

64-
self.addOutput(OutputVector(self.OUTPUT, self.tr('Nodes'), datatype=[dataobjects.TYPE_VECTOR_POINT]))
66+
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Nodes'), QgsProcessing.TypeVectorPoint))
6567

6668
def name(self):
6769
return 'extractnodes'
@@ -70,36 +72,51 @@ def displayName(self):
7072
return self.tr('Extract nodes')
7173

7274
def processAlgorithm(self, parameters, context, feedback):
73-
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
75+
source = self.parameterAsSource(parameters, self.INPUT, context)
7476

75-
fields = layer.fields()
77+
fields = source.fields()
7678
fields.append(QgsField('node_index', QVariant.Int))
7779
fields.append(QgsField('distance', QVariant.Double))
7880
fields.append(QgsField('angle', QVariant.Double))
7981

80-
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Point, layer.crs(), context)
82+
out_wkb = QgsWkbTypes.Point
83+
if QgsWkbTypes.hasM(source.wkbType()):
84+
out_wkb = QgsWkbTypes.addM(out_wkb)
85+
if QgsWkbTypes.hasZ(source.wkbType()):
86+
out_wkb = QgsWkbTypes.addZ(out_wkb)
8187

82-
features = QgsProcessingUtils.getFeatures(layer, context)
83-
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
88+
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
89+
fields, out_wkb, source.sourceCrs())
90+
91+
features = source.getFeatures()
92+
total = 100.0 / source.featureCount() if source.featureCount() else 0
8493
for current, f in enumerate(features):
94+
if feedback.isCanceled():
95+
break
96+
8597
input_geometry = f.geometry()
8698
if not input_geometry:
87-
writer.addFeature(f, QgsFeatureSink.FastInsert)
99+
sink.addFeature(f, QgsFeatureSink.FastInsert)
88100
else:
89-
points = vector.extractPoints(input_geometry)
90-
91-
for i, point in enumerate(points):
92-
distance = input_geometry.distanceToVertex(i)
93-
angle = math.degrees(input_geometry.angleAtVertex(i))
94-
attrs = f.attributes()
95-
attrs.append(i)
96-
attrs.append(distance)
97-
attrs.append(angle)
98-
output_feature = QgsFeature()
99-
output_feature.setAttributes(attrs)
100-
output_feature.setGeometry(QgsGeometry.fromPoint(point))
101-
writer.addFeature(output_feature, QgsFeatureSink.FastInsert)
101+
i = 0
102+
for part in input_geometry.geometry().coordinateSequence():
103+
for ring in part:
104+
if feedback.isCanceled():
105+
break
106+
107+
for point in ring:
108+
distance = input_geometry.distanceToVertex(i)
109+
angle = math.degrees(input_geometry.angleAtVertex(i))
110+
attrs = f.attributes()
111+
attrs.append(i)
112+
attrs.append(distance)
113+
attrs.append(angle)
114+
output_feature = QgsFeature()
115+
output_feature.setAttributes(attrs)
116+
output_feature.setGeometry(QgsGeometry(point.clone()))
117+
sink.addFeature(output_feature, QgsFeatureSink.FastInsert)
118+
i += 1
102119

103120
feedback.setProgress(int(current * total))
104121

105-
del writer
122+
return {self.OUTPUT: dest_id}

python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
from .Difference import Difference
5858
from .DropGeometry import DropGeometry
5959
from .ExtentFromLayer import ExtentFromLayer
60+
from .ExtractNodes import ExtractNodes
6061
from .FixGeometry import FixGeometry
6162
from .GridPolygon import GridPolygon
6263
from .Heatmap import Heatmap
@@ -97,7 +98,6 @@
9798
# from .ExtractByLocation import ExtractByLocation
9899
# from .ExportGeometryInfo import ExportGeometryInfo
99100
# from .SinglePartsToMultiparts import SinglePartsToMultiparts
100-
# from .ExtractNodes import ExtractNodes
101101
# from .ConvexHull import ConvexHull
102102
# from .FixedDistanceBuffer import FixedDistanceBuffer
103103
# from .VariableDistanceBuffer import VariableDistanceBuffer
@@ -187,7 +187,6 @@ def getAlgs(self):
187187
#
188188
# ExportGeometryInfo(),
189189
# SinglePartsToMultiparts(),
190-
# ExtractNodes(),
191190
# ConvexHull(), FixedDistanceBuffer(),
192191
# VariableDistanceBuffer(),
193192
# RandomSelection(), RandomSelectionWithinSubsets(),
@@ -251,6 +250,7 @@ def getAlgs(self):
251250
Difference(),
252251
DropGeometry(),
253252
ExtentFromLayer(),
253+
ExtractNodes(),
254254
FixGeometry(),
255255
GridPolygon(),
256256
Heatmap(),

python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -889,50 +889,50 @@ tests:
889889
# OUTPUT_LAYER:
890890
# name: expected/single_sided_buffer_multiline_bevel.gml
891891
# type: vector
892-
#
893-
# - algorithm: qgis:extractnodes
894-
# name: Test (qgis:extractnodes)
895-
# params:
896-
# INPUT:
897-
# name: multipolys.gml
898-
# type: vector
899-
# results:
900-
# OUTPUT:
901-
# name: expected/extract_nodes_multipolys.gml
902-
# type: vector
903-
#
904-
# - algorithm: qgis:extractnodes
905-
# name: Extract nodes from polygons
906-
# params:
907-
# INPUT:
908-
# name: polys.gml
909-
# type: vector
910-
# results:
911-
# OUTPUT:
912-
# name: expected/extract_nodes_polys.gml
913-
# type: vector
914-
#
915-
# - algorithm: qgis:extractnodes
916-
# name: Extract nodes from multilines
917-
# params:
918-
# INPUT:
919-
# name: multilines.gml
920-
# type: vector
921-
# results:
922-
# OUTPUT:
923-
# name: expected/extract_nodes_multilines.gml
924-
# type: vector
925-
#
926-
# - algorithm: qgis:extractnodes
927-
# name: Extract nodes from lines
928-
# params:
929-
# INPUT:
930-
# name: lines.gml
931-
# type: vector
932-
# results:
933-
# OUTPUT:
934-
# name: expected/extract_nodes_lines.gml
935-
# type: vector
892+
893+
- algorithm: qgis:extractnodes
894+
name: Test (qgis:extractnodes)
895+
params:
896+
INPUT:
897+
name: multipolys.gml
898+
type: vector
899+
results:
900+
OUTPUT:
901+
name: expected/extract_nodes_multipolys.gml
902+
type: vector
903+
904+
- algorithm: qgis:extractnodes
905+
name: Extract nodes from polygons
906+
params:
907+
INPUT:
908+
name: polys.gml
909+
type: vector
910+
results:
911+
OUTPUT:
912+
name: expected/extract_nodes_polys.gml
913+
type: vector
914+
915+
- algorithm: qgis:extractnodes
916+
name: Extract nodes from multilines
917+
params:
918+
INPUT:
919+
name: multilines.gml
920+
type: vector
921+
results:
922+
OUTPUT:
923+
name: expected/extract_nodes_multilines.gml
924+
type: vector
925+
926+
- algorithm: qgis:extractnodes
927+
name: Extract nodes from lines
928+
params:
929+
INPUT:
930+
name: lines.gml
931+
type: vector
932+
results:
933+
OUTPUT:
934+
name: expected/extract_nodes_lines.gml
935+
type: vector
936936

937937
- algorithm: qgis:simplifygeometries
938938
name: Simplify (lines)

0 commit comments

Comments
 (0)