Skip to content

Commit aec6a79

Browse files
authoredJul 16, 2017
Merge pull request #4863 from nyalldawson/nn
Port 2 more processing algorithms
2 parents 99a9e24 + 1b1dc7d commit aec6a79

File tree

13 files changed

+1132
-259
lines changed

13 files changed

+1132
-259
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/MeanCoords.py

Lines changed: 70 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,28 @@
3131
from qgis.PyQt.QtGui import QIcon
3232
from qgis.PyQt.QtCore import QVariant
3333

34-
from qgis.core import QgsField, QgsFeature, QgsGeometry, QgsPointXY, QgsWkbTypes, QgsProcessingUtils, QgsFeatureSink, QgsFields
34+
from qgis.core import (QgsField,
35+
QgsFeature,
36+
QgsGeometry,
37+
QgsPointXY,
38+
QgsWkbTypes,
39+
QgsFeatureRequest,
40+
QgsFeatureSink,
41+
QgsFields,
42+
QgsProcessing,
43+
QgsProcessingParameterFeatureSink,
44+
QgsProcessingParameterField,
45+
QgsProcessingParameterFeatureSource,
46+
QgsProcessingException)
3547

3648
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
37-
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
38-
from processing.core.parameters import ParameterTableField
39-
from processing.core.parameters import ParameterVector
40-
from processing.core.outputs import OutputVector
41-
from processing.tools import dataobjects, vector
49+
from processing.tools import vector
4250

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

4553

4654
class MeanCoords(QgisAlgorithm):
47-
48-
POINTS = 'POINTS'
55+
INPUT = 'INPUT'
4956
WEIGHT = 'WEIGHT'
5057
OUTPUT = 'OUTPUT'
5158
UID = 'UID'
@@ -61,19 +68,19 @@ def __init__(self):
6168
super().__init__()
6269

6370
def initAlgorithm(self, config=None):
64-
self.addParameter(ParameterVector(self.POINTS,
65-
self.tr('Input layer')))
66-
self.addParameter(ParameterTableField(self.WEIGHT,
67-
self.tr('Weight field'),
68-
MeanCoords.POINTS,
69-
ParameterTableField.DATA_TYPE_NUMBER,
70-
optional=True))
71-
self.addParameter(ParameterTableField(self.UID,
72-
self.tr('Unique ID field'),
73-
MeanCoords.POINTS,
74-
optional=True))
75-
76-
self.addOutput(OutputVector(MeanCoords.OUTPUT, self.tr('Mean coordinates'), datatype=[dataobjects.TYPE_VECTOR_POINT]))
71+
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
72+
self.tr('Input layer')))
73+
self.addParameter(QgsProcessingParameterField(self.WEIGHT, self.tr('Weight field'),
74+
parentLayerParameterName=MeanCoords.INPUT,
75+
type=QgsProcessingParameterField.Numeric,
76+
optional=True))
77+
self.addParameter(QgsProcessingParameterField(self.UID,
78+
self.tr('Unique ID field'),
79+
parentLayerParameterName=MeanCoords.INPUT,
80+
optional=True))
81+
82+
self.addParameter(QgsProcessingParameterFeatureSink(MeanCoords.OUTPUT, self.tr('Mean coordinates'),
83+
QgsProcessing.TypeVectorPoint))
7784

7885
def name(self):
7986
return 'meancoordinates'
@@ -82,46 +89,58 @@ def displayName(self):
8289
return self.tr('Mean coordinate(s)')
8390

8491
def processAlgorithm(self, parameters, context, feedback):
85-
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.POINTS), context)
86-
weightField = self.getParameterValue(self.WEIGHT)
87-
uniqueField = self.getParameterValue(self.UID)
92+
source = self.parameterAsSource(parameters, self.INPUT, context)
93+
94+
weight_field = self.parameterAsString(parameters, self.WEIGHT, context)
95+
unique_field = self.parameterAsString(parameters, self.UID, context)
8896

89-
if weightField is None:
90-
weightIndex = -1
97+
attributes = []
98+
if not weight_field:
99+
weight_index = -1
91100
else:
92-
weightIndex = layer.fields().lookupField(weightField)
101+
weight_index = source.fields().lookupField(weight_field)
102+
if weight_index >= 0:
103+
attributes.append(weight_index)
93104

94-
if uniqueField is None:
95-
uniqueIndex = -1
105+
if not unique_field:
106+
unique_index = -1
96107
else:
97-
uniqueIndex = layer.fields().lookupField(uniqueField)
108+
unique_index = source.fields().lookupField(unique_field)
109+
if unique_index >= 0:
110+
attributes.append(unique_index)
98111

99-
fieldList = QgsFields()
100-
fieldList.append(QgsField('MEAN_X', QVariant.Double, '', 24, 15))
101-
fieldList.append(QgsField('MEAN_Y', QVariant.Double, '', 24, 15))
102-
fieldList.append(QgsField('UID', QVariant.String, '', 255))
112+
field_list = QgsFields()
113+
field_list.append(QgsField('MEAN_X', QVariant.Double, '', 24, 15))
114+
field_list.append(QgsField('MEAN_Y', QVariant.Double, '', 24, 15))
115+
if unique_index >= 0:
116+
field_list.append(QgsField('UID', QVariant.String, '', 255))
103117

104-
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fieldList, QgsWkbTypes.Point, layer.crs(), context)
118+
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
119+
field_list, QgsWkbTypes.Point, source.sourceCrs())
105120

106-
features = QgsProcessingUtils.getFeatures(layer, context)
107-
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
121+
features = source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(attributes))
122+
total = 100.0 / source.featureCount() if source.featureCount() else 0
108123
means = {}
109124
for current, feat in enumerate(features):
125+
if feedback.isCanceled():
126+
break
127+
110128
feedback.setProgress(int(current * total))
111-
if uniqueIndex == -1:
129+
if unique_index == -1:
112130
clazz = "Single class"
113131
else:
114-
clazz = str(feat.attributes()[uniqueIndex]).strip()
115-
if weightIndex == -1:
132+
clazz = str(feat.attributes()[unique_index]).strip()
133+
if weight_index == -1:
116134
weight = 1.00
117135
else:
118136
try:
119-
weight = float(feat.attributes()[weightIndex])
137+
weight = float(feat.attributes()[weight_index])
120138
except:
121139
weight = 1.00
122140

123141
if weight < 0:
124-
raise GeoAlgorithmExecutionException(self.tr('Negative weight value found. Please fix your data and try again.'))
142+
raise QgsProcessingException(
143+
self.tr('Negative weight value found. Please fix your data and try again.'))
125144

126145
if clazz not in means:
127146
means[clazz] = (0, 0, 0)
@@ -138,15 +157,21 @@ def processAlgorithm(self, parameters, context, feedback):
138157
current = 0
139158
total = 100.0 / len(means) if means else 1
140159
for (clazz, values) in list(means.items()):
160+
if feedback.isCanceled():
161+
break
162+
141163
outFeat = QgsFeature()
142164
cx = values[0] / values[2]
143165
cy = values[1] / values[2]
144166
meanPoint = QgsPointXY(cx, cy)
145167

146168
outFeat.setGeometry(QgsGeometry.fromPoint(meanPoint))
147-
outFeat.setAttributes([cx, cy, clazz])
148-
writer.addFeature(outFeat, QgsFeatureSink.FastInsert)
169+
attributes = [cx, cy]
170+
if unique_index >= 0:
171+
attributes.append(clazz)
172+
outFeat.setAttributes(attributes)
173+
sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
149174
current += 1
150175
feedback.setProgress(int(current * total))
151176

152-
del writer
177+
return {self.OUTPUT: dest_id}

0 commit comments

Comments
 (0)
Please sign in to comment.