Skip to content

Commit

Permalink
Fix processing algs crash when no source features exist
Browse files Browse the repository at this point in the history
Instead we output an empty layer - this may be critical for
multi-step models where there is validly no features present
in a source layer
  • Loading branch information
nyalldawson committed Jun 23, 2017
1 parent 24eb6fd commit 99cfb8f
Show file tree
Hide file tree
Showing 92 changed files with 105 additions and 105 deletions.
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/AddTableField.py
Expand Up @@ -100,7 +100,7 @@ def processAlgorithm(self, parameters, context, feedback):
fields, source.wkbType(), source.sourceCrs())

features = source.getFeatures()
total = 100.0 / source.featureCount()
total = 100.0 / source.featureCount() if source.featureCount() else 0

for current, input_feature in enumerate(features):
if feedback.isCanceled():
Expand Down
Expand Up @@ -74,7 +74,7 @@ def processAlgorithm(self, parameters, context, feedback):
fields, source.wkbType(), source.sourceCrs())

features = source.getFeatures()
total = 100.0 / source.featureCount()
total = total = 100.0 / source.featureCount() if source.featureCount() else 0

This comment has been minimized.

Copy link
@m-kuhn

m-kuhn Jun 23, 2017

Member

total = total =? ;)

This comment has been minimized.

Copy link
@nyalldawson

nyalldawson Jun 23, 2017

Author Collaborator

total = total = copy + paste is evil

for current, input_feature in enumerate(features):
if feedback.isCanceled():
break
Expand Down
6 changes: 3 additions & 3 deletions python/plugins/processing/algs/qgis/BasicStatistics.py
Expand Up @@ -156,7 +156,7 @@ def processAlgorithm(self, parameters, context, feedback):
return results

def calcNumericStats(self, features, feedback, field, count):
total = 100.0 / float(count)
total = 100.0 / count if count else 0
stat = QgsStatisticalSummary()
for current, ft in enumerate(features):
if feedback.isCanceled():
Expand Down Expand Up @@ -205,7 +205,7 @@ def calcNumericStats(self, features, feedback, field, count):
return data, results

def calcStringStats(self, features, feedback, field, count):
total = 100.0 / float(count)
total = 100.0 / count if count else 1
stat = QgsStringStatisticalSummary()
for current, ft in enumerate(features):
if feedback.isCanceled():
Expand Down Expand Up @@ -237,7 +237,7 @@ def calcStringStats(self, features, feedback, field, count):
return data, results

def calcDateTimeStats(self, features, feedback, field, count):
total = 100.0 / float(count)
total = 100.0 / count if count else 1
stat = QgsDateTimeStatisticalSummary()
for current, ft in enumerate(features):
if feedback.isCanceled():
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/Boundary.py
Expand Up @@ -86,7 +86,7 @@ def processAlgorithm(self, parameters, context, feedback):
source.fields(), output_wkb, source.sourceCrs())

features = source.getFeatures()
total = 100.0 / source.featureCount()
total = 100.0 / source.featureCount() if source.featureCount() else 0

for current, input_feature in enumerate(features):
if feedback.isCanceled():
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/BoundingBox.py
Expand Up @@ -78,7 +78,7 @@ def processAlgorithm(self, parameters, context, feedback):
source.fields(), QgsWkbTypes.Polygon, source.sourceCrs())

features = source.getFeatures()
total = 100.0 / source.featureCount()
total = 100.0 / source.featureCount() if source.featureCount() else 0

for current, input_feature in enumerate(features):
if feedback.isCanceled():
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/Buffer.py
Expand Up @@ -38,7 +38,7 @@ def buffering(feedback, context, writer, distance, field, useField, layer, disso

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

# With dissolve
if dissolve:
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/CheckValidity.py
Expand Up @@ -129,7 +129,7 @@ def doCheck(self, method, parameters, context, feedback):
error_count = 0

features = source.getFeatures()
total = 100.0 / source.featureCount()
total = 100.0 / source.featureCount() if source.featureCount() else 0
for current, inFeat in enumerate(features):
if feedback.isCanceled():
break
Expand Down
4 changes: 2 additions & 2 deletions python/plugins/processing/algs/qgis/ConvexHull.py
Expand Up @@ -120,7 +120,7 @@ def processAlgorithm(self, parameters, context, feedback):
if useField:
unique = layer.uniqueValues(index)
current = 0
total = 100.0 / (QgsProcessingUtils.featureCount(layer, context) * len(unique))
total = 100.0 / (layer.featureCount() * len(unique)) if layer.featureCount() else 1
for i in unique:
first = True
hull = []
Expand Down Expand Up @@ -152,7 +152,7 @@ def processAlgorithm(self, parameters, context, feedback):
fid += 1
else:
hull = []
total = 100.0 / layer.featureCount()
total = 100.0 / layer.featureCount() if layer.featureCount() else 1
features = QgsProcessingUtils.getFeatures(layer, context)
for current, f in enumerate(features):
inGeom = f.geometry()
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/Datasources2Vrt.py
Expand Up @@ -110,7 +110,7 @@ def mergeDataSources2Vrt(self, dataSources, outFile, union=False, relative=False
if union:
vrt += '<OGRVRTUnionLayer name="UnionedLayer">'

total = 100.0 / len(dataSources)
total = 100.0 / len(dataSources) if dataSources else 1
for current, inFile in enumerate(dataSources):
feedback.setProgress(int(current * total))

Expand Down
4 changes: 2 additions & 2 deletions python/plugins/processing/algs/qgis/Delaunay.py
Expand Up @@ -92,7 +92,7 @@ def processAlgorithm(self, parameters, context, feedback):
ptNdx = -1
c = voronoi.Context()
features = QgsProcessingUtils.getFeatures(layer, context)
total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
for current, inFeat in enumerate(features):
geom = QgsGeometry(inFeat.geometry())
if geom.isNull():
Expand Down Expand Up @@ -122,7 +122,7 @@ def processAlgorithm(self, parameters, context, feedback):
triangles = c.triangles
feat = QgsFeature()

total = 100.0 / len(triangles)
total = 100.0 / len(triangles) if triangles else 1
for current, triangle in enumerate(triangles):
indices = list(triangle)
indices.append(indices[0])
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/DeleteColumn.py
Expand Up @@ -91,7 +91,7 @@ def processAlgorithm(self, parameters, context, feedback):
fields, source.wkbType(), source.sourceCrs())

features = source.getFeatures()
total = 100.0 / source.featureCount()
total = 100.0 / source.featureCount() if source.featureCount() else 0

for current, f in enumerate(features):
if feedback.isCanceled():
Expand Down
Expand Up @@ -68,7 +68,7 @@ def processAlgorithm(self, parameters, context, feedback):

features = QgsProcessingUtils.getFeatures(layer, context)

total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
geoms = dict()
for current, f in enumerate(features):
geoms[f.id()] = f.geometry()
Expand All @@ -83,7 +83,7 @@ def processAlgorithm(self, parameters, context, feedback):
if g.isGeosEqual(cleaned[j]):
del cleaned[j]

total = 100.0 / len(cleaned)
total = 100.0 / len(cleaned) if cleaned else 1
request = QgsFeatureRequest().setFilterFids(list(cleaned.keys()))
for current, f in enumerate(layer.getFeatures(request)):
writer.addFeature(f)
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/DeleteHoles.py
Expand Up @@ -79,7 +79,7 @@ def processAlgorithm(self, parameters, context, feedback):
source.fields(), source.wkbType(), source.sourceCrs())

features = source.getFeatures()
total = 100.0 / source.featureCount()
total = 100.0 / source.featureCount() if source.featureCount() else 0

for current, f in enumerate(features):
if feedback.isCanceled():
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/DensifyGeometries.py
Expand Up @@ -82,7 +82,7 @@ def processAlgorithm(self, parameters, context, feedback):
source.fields(), source.wkbType(), source.sourceCrs())

features = source.getFeatures()
total = 100.0 / source.featureCount()
total = 100.0 / source.featureCount() if source.featureCount() else 0

for current, f in enumerate(features):
if feedback.isCanceled():
Expand Down
Expand Up @@ -80,7 +80,7 @@ def processAlgorithm(self, parameters, context, feedback):
source.fields(), source.wkbType(), source.sourceCrs())

features = source.getFeatures()
total = 100.0 / source.featureCount()
total = 100.0 / source.featureCount() if source.featureCount() else 0
for current, f in enumerate(features):
if feedback.isCanceled():
break
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/Difference.py
Expand Up @@ -80,7 +80,7 @@ def processAlgorithm(self, parameters, context, feedback):
outFeat = QgsFeature()
index = QgsProcessingUtils.createSpatialIndex(layerB, context)
selectionA = QgsProcessingUtils.getFeatures(layerA, context)
total = 100.0 / QgsProcessingUtils.featureCount(layerA, context)
total = 100.0 / layerA.featureCount() if layerA.featureCount() else 0
for current, inFeatA in enumerate(selectionA):
geom = inFeatA.geometry()
diff_geom = QgsGeometry(geom)
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/DropGeometry.py
Expand Up @@ -73,7 +73,7 @@ def processAlgorithm(self, parameters, context, feedback):

request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry)
features = source.getFeatures(request)
total = 100.0 / source.featureCount()
total = 100.0 / source.featureCount() if source.featureCount() else 0

for current, input_feature in enumerate(features):
if feedback.isCanceled():
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/EquivalentNumField.py
Expand Up @@ -77,7 +77,7 @@ def processAlgorithm(self, parameters, context, feedback):
classes = {}

features = QgsProcessingUtils.getFeatures(vlayer, context)
total = 100.0 / QgsProcessingUtils.featureCount(vlayer, context)
total = 100.0 / vlayer.featureCount() if vlayer.featureCount() else 0
for current, feature in enumerate(features):
feedback.setProgress(int(current * total))
inGeom = feature.geometry()
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/ExecuteSQL.py
Expand Up @@ -151,7 +151,7 @@ def processAlgorithm(self, parameters, context, feedback):
vLayer.crs(), context)

features = QgsProcessingUtils.getFeatures(vLayer, context)
total = 100.0 / QgsProcessingUtils.featureCount(vLayer, context)
total = 100.0 / vLayer.featureCount() if vLayer.featureCount() else 0
outFeat = QgsFeature()
for current, inFeat in enumerate(features):
outFeat.setAttributes(inFeat.attributes())
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/Explode.py
Expand Up @@ -71,7 +71,7 @@ def processAlgorithm(self, parameters, context, feedback):
writer = output.getVectorWriter(fields, QgsWkbTypes.LineString, vlayer.crs(), context)
outFeat = QgsFeature()
features = QgsProcessingUtils.getFeatures(vlayer, context)
total = 100.0 / QgsProcessingUtils.featureCount(vlayer, context)
total = 100.0 / vlayer.featureCount() if vlayer.featureCount() else 0
for current, feature in enumerate(features):
feedback.setProgress(int(current * total))
inGeom = feature.geometry()
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/ExportGeometryInfo.py
Expand Up @@ -133,7 +133,7 @@ def processAlgorithm(self, parameters, context, feedback):
outFeat.setFields(fields)

features = QgsProcessingUtils.getFeatures(layer, context)
total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
for current, f in enumerate(features):
inGeom = f.geometry()

Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/ExtendLines.py
Expand Up @@ -77,7 +77,7 @@ def processAlgorithm(self, parameters, context, feedback):
end_distance = self.getParameterValue(self.END_DISTANCE)

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

for current, input_feature in enumerate(features):
output_feature = input_feature
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/ExtentFromLayer.py
Expand Up @@ -143,7 +143,7 @@ def layerExtent(self, source, sink, feedback):

def featureExtent(self, source, context, sink, feedback):
features = source.getFeatures()
total = 100.0 / source.featureCount()
total = 100.0 / source.featureCount() if source.featureCount() else 0
feat = QgsFeature()
for current, f in enumerate(features):
if feedback.isCanceled():
Expand Down
4 changes: 2 additions & 2 deletions python/plugins/processing/algs/qgis/ExtractByLocation.py
Expand Up @@ -107,7 +107,7 @@ def processAlgorithm(self, parameters, context, feedback):

selectedSet = []
features = QgsProcessingUtils.getFeatures(selectLayer, context)
total = 100.0 / QgsProcessingUtils.featureCount(selectLayer, context)
total = 100.0 / selectLayer.featureCount() if selectLayer.featureCount() else 0
for current, f in enumerate(features):
geom = vector.snapToPrecision(f.geometry(), precision)
bbox = geom.boundingBox()
Expand Down Expand Up @@ -136,7 +136,7 @@ def processAlgorithm(self, parameters, context, feedback):
selectedSet = selectedSet + disjoinSet

features = QgsProcessingUtils.getFeatures(layer, context)
total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
for current, f in enumerate(features):
if f.id() in selectedSet:
writer.addFeature(f)
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/ExtractNodes.py
Expand Up @@ -78,7 +78,7 @@ def processAlgorithm(self, parameters, context, feedback):
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Point, layer.crs(), context)

features = QgsProcessingUtils.getFeatures(layer, context)
total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
for current, f in enumerate(features):
input_geometry = f.geometry()
if not input_geometry:
Expand Down
Expand Up @@ -92,7 +92,7 @@ def processAlgorithm(self, parameters, context, feedback):
self.tr('\'{}\' is not a valid node index').format(node))

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

for current, f in enumerate(features):

Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/FieldPyculator.py
Expand Up @@ -144,7 +144,7 @@ def processAlgorithm(self, parameters, context, feedback):

# Run
features = QgsProcessingUtils.getFeatures(layer, context)
total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
for current, feat in enumerate(features):
feedback.setProgress(int(current * total))
attrs = feat.attributes()
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/FieldsCalculator.py
Expand Up @@ -137,7 +137,7 @@ def processAlgorithm(self, parameters, context, feedback):
calculationSuccess = True

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

rownum = 1
for current, f in enumerate(features):
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/FixGeometry.py
Expand Up @@ -79,7 +79,7 @@ def processAlgorithm(self, parameters, context, feedback):
if QgsProcessingUtils.featureCount(layer, context) == 0:
raise GeoAlgorithmExecutionException(self.tr('There are no features in the input layer'))

total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
for current, inputFeature in enumerate(features):
outputFeature = inputFeature
if inputFeature.geometry():
Expand Down
Expand Up @@ -115,7 +115,7 @@ def processAlgorithm(self, parameters, context, feedback):
self.tr('Evaluation error: {0}').format(expression.evalErrorString()))

features = QgsProcessingUtils.getFeatures(layer, context)
total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
for current, input_feature in enumerate(features):
output_feature = input_feature

Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/GeometryConvert.py
Expand Up @@ -94,7 +94,7 @@ def processAlgorithm(self, parameters, context, feedback):
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), newType, layer.crs(), context)

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

for current, f in enumerate(features):
geom = f.geometry()
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/Gridify.py
Expand Up @@ -84,7 +84,7 @@ def processAlgorithm(self, parameters, context, feedback):
context)

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

for current, f in enumerate(features):
geom = f.geometry()
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/Heatmap.py
Expand Up @@ -174,7 +174,7 @@ def processAlgorithm(self, parameters, context, feedback):
request = QgsFeatureRequest()
request.setSubsetOfAttributes(attrs)
features = QgsProcessingUtils.getFeatures(layer, context, request)
total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
total = 100.0 / layer.featureCount() if layer.featureCount() else 0
for current, f in enumerate(features):
if kde.addFeature(f) != QgsKernelDensityEstimation.Success:
QgsMessageLog.logMessage(self.tr('Error adding feature with ID {} to heatmap').format(f.id()), self.tr('Processing'), QgsMessageLog.CRITICAL)
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/HubDistanceLines.py
Expand Up @@ -122,7 +122,7 @@ def processAlgorithm(self, parameters, context, feedback):

# Scan source points, find nearest hub, and write to output file
features = QgsProcessingUtils.getFeatures(layerPoints, context)
total = 100.0 / QgsProcessingUtils.featureCount(layerPoints, context)
total = 100.0 / layerPoints.featureCount() if layerPoints.featureCount() else 0
for current, f in enumerate(features):
src = f.geometry().boundingBox().center()

Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/HubDistancePoints.py
Expand Up @@ -122,7 +122,7 @@ def processAlgorithm(self, parameters, context, feedback):

# Scan source points, find nearest hub, and write to output file
features = QgsProcessingUtils.getFeatures(layerPoints, context)
total = 100.0 / QgsProcessingUtils.featureCount(layerPoints, context)
total = 100.0 / layerPoints.featureCount() if layerPoints.featureCount() else 0
for current, f in enumerate(features):
src = f.geometry().boundingBox().center()

Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/HubLines.py
Expand Up @@ -92,7 +92,7 @@ def processAlgorithm(self, parameters, context, feedback):

spokes = QgsProcessingUtils.getFeatures(layerSpoke, context)
hubs = QgsProcessingUtils.getFeatures(layerHub, context)
total = 100.0 / QgsProcessingUtils.featureCount(layerSpoke, context)
total = 100.0 / layerSpoke.featureCount() if layerSpoke.featureCount() else 0

for current, spokepoint in enumerate(spokes):
p = spokepoint.geometry().boundingBox().center()
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/HypsometricCurves.py
Expand Up @@ -114,7 +114,7 @@ def processAlgorithm(self, parameters, context, feedback):
memRasterDriver = gdal.GetDriverByName('MEM')

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

for current, f in enumerate(features):
geom = f.geometry()
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/qgis/ImportIntoPostGIS.py
Expand Up @@ -180,7 +180,7 @@ def processAlgorithm(self, parameters, context, feedback):
self.tr('Error importing to PostGIS\n{0}').format(exporter.errorMessage()))

features = source.getFeatures()
total = 100.0 / source.featureCount()
total = 100.0 / source.featureCount() if source.featureCount() else 0
for current, f in enumerate(features):
if feedback.isCanceled():
break
Expand Down

0 comments on commit 99cfb8f

Please sign in to comment.