Skip to content
Permalink
Browse files
[processing] Ensure algorithms which add attributes to features
always add a consistent amount of attributes regardless of the
code paths taken

Some algorithms were adding features to data providers with
different number of attributes vs the layer's fields - this is
not supported and depending on the data provider will have
different (bad) results.
  • Loading branch information
nyalldawson committed Feb 15, 2018
1 parent a811036 commit 12fcfac
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 1 deletion.
@@ -30,7 +30,8 @@
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtCore import QVariant

from qgis.core import (QgsCoordinateTransform,
from qgis.core import (NULL,
QgsCoordinateTransform,
QgsField,
QgsFields,
QgsWkbTypes,
@@ -148,6 +149,12 @@ def processAlgorithm(self, parameters, context, feedback):
else:
attrs.extend(self.line_attributes(inGeom))

# ensure consistent count of attributes - otherwise null
# geometry features will have incorrect attribute length
# and provider may reject them
if len(attrs) < len(fields):
attrs += [NULL] * (len(fields) - len(attrs))

outFeat.setAttributes(attrs)
sink.addFeature(outFeat, QgsFeatureSink.FastInsert)

@@ -270,6 +270,13 @@ def addField(original, stat, type):

if not f.hasGeometry():
if not discard_nomatch:
# ensure consistent count of attributes - otherwise non matching
# features will have incorrect attribute length
# and provider may reject them
attrs = f.attributes()
if len(attrs) < len(out_fields):
attrs += [NULL] * (len(out_fields) - len(attrs))
f.setAttributes(attrs)
sink.addFeature(f, QgsFeatureSink.FastInsert)
continue

@@ -302,6 +309,13 @@ def addField(original, stat, type):
if discard_nomatch:
continue
else:
# ensure consistent count of attributes - otherwise non matching
# features will have incorrect attribute length
# and provider may reject them
attrs = f.attributes()
if len(attrs) < len(out_fields):
attrs += [NULL] * (len(out_fields) - len(attrs))
f.setAttributes(attrs)
sink.addFeature(f, QgsFeatureSink.FastInsert)
else:
attrs = f.attributes()
@@ -86,6 +86,15 @@ QgsFeature QgsBoundingBoxAlgorithm::processFeature( const QgsFeature &feature, Q
<< bounds.perimeter();
f.setAttributes( attrs );
}
else
{
QgsAttributes attrs = f.attributes();
attrs << QVariant()
<< QVariant()
<< QVariant()
<< QVariant();
f.setAttributes( attrs );
}
return f;
}

@@ -85,6 +85,13 @@ QgsFeature QgsConvexHullAlgorithm::processFeature( const QgsFeature &feature, Qg
<< outputGeometry.constGet()->perimeter();
f.setAttributes( attrs );
}
else
{
QgsAttributes attrs = f.attributes();
attrs << QVariant()
<< QVariant();
f.setAttributes( attrs );
}
}
return f;
}
@@ -100,6 +100,13 @@ QgsFeature QgsMinimumEnclosingCircleAlgorithm::processFeature( const QgsFeature
<< M_PI *radius *radius;
f.setAttributes( attrs );
}
else
{
QgsAttributes attrs = f.attributes();
attrs << QVariant()
<< QVariant();
f.setAttributes( attrs );
}
return f;
}

@@ -96,6 +96,16 @@ QgsFeature QgsOrientedMinimumBoundingBoxAlgorithm::processFeature( const QgsFeat
<< 2 * width + 2 * height;
f.setAttributes( attrs );
}
else
{
QgsAttributes attrs = f.attributes();
attrs << QVariant()
<< QVariant()
<< QVariant()
<< QVariant()
<< QVariant();
f.setAttributes( attrs );
}
return f;
}

0 comments on commit 12fcfac

Please sign in to comment.