Skip to content
Permalink
Browse files

[FEATURE][processing] Add sort order option to Add Incremental Field alg

This allows users to optionally set a sort order to use when
assigning values in the Add Incremental Field algorithm.

Previously values were always added using the original feature
order. With this change users can control the order in which
features are assigned values.
  • Loading branch information
nyalldawson committed Apr 18, 2018
1 parent eab76e8 commit 0e0e133c7d9032b0843a8df76b57bfba6c16131d
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ autoincrement_sort.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>0</gml:X><gml:Y>-5</gml:Y></gml:coord>
<gml:coord><gml:X>8</gml:X><gml:Y>3</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:autoincrement_sort fid="points.8">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>0,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>9</ogr:id>
<ogr:id2>0</ogr:id2>
<ogr:AUTO>0</ogr:AUTO>
</ogr:autoincrement_sort>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_sort fid="points.7">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>7,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>8</ogr:id>
<ogr:id2>0</ogr:id2>
<ogr:AUTO>1</ogr:AUTO>
</ogr:autoincrement_sort>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_sort fid="points.6">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>8,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>7</ogr:id>
<ogr:id2>0</ogr:id2>
<ogr:AUTO>2</ogr:AUTO>
</ogr:autoincrement_sort>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_sort fid="points.5">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>0,-5</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>6</ogr:id>
<ogr:id2>0</ogr:id2>
<ogr:AUTO>3</ogr:AUTO>
</ogr:autoincrement_sort>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_sort fid="points.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>4,1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>5</ogr:id>
<ogr:id2>1</ogr:id2>
<ogr:AUTO>4</ogr:AUTO>
</ogr:autoincrement_sort>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_sort fid="points.3">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5,2</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>4</ogr:id>
<ogr:id2>2</ogr:id2>
<ogr:AUTO>5</ogr:AUTO>
</ogr:autoincrement_sort>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_sort fid="points.2">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>2,2</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>3</ogr:id>
<ogr:id2>0</ogr:id2>
<ogr:AUTO>6</ogr:AUTO>
</ogr:autoincrement_sort>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_sort fid="points.1">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3,3</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>2</ogr:id>
<ogr:id2>1</ogr:id2>
<ogr:AUTO>7</ogr:AUTO>
</ogr:autoincrement_sort>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_sort fid="points.0">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>1,1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>1</ogr:id>
<ogr:id2>2</ogr:id2>
<ogr:AUTO>8</ogr:AUTO>
</ogr:autoincrement_sort>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureCollectionType">
<xs:attribute name="lockId" type="xs:string" use="optional"/>
<xs:attribute name="scope" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="autoincrement_sort" type="ogr:autoincrement_sort_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="autoincrement_sort_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:PointPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
<xs:element name="id" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:totalDigits value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="id2" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:totalDigits value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="AUTO" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:long">
<xs:totalDigits value="20"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
@@ -501,6 +501,22 @@ tests:
name: expected/autoincrement_grouped.gml
type: vector

- algorithm: native:addautoincrementalfield
name: Add incremental field (with sorting)
params:
FIELD_NAME: AUTO
INPUT:
name: points.gml
type: vector
SORT_ASCENDING: true
SORT_EXPRESSION: 99-id
SORT_NULLS_FIRST: false
START: 0
results:
OUTPUT:
name: expected/autoincrement_sort.gml
type: vector

- algorithm: native:dissolve
name: Dissolve using field
params:
@@ -5191,4 +5207,5 @@ tests:
name: expected/filter_points_big.gml
type: vector


# See ../README.md for a description of the file format
@@ -16,6 +16,7 @@
***************************************************************************/

#include "qgsalgorithmaddincrementalfield.h"
#include "qgsfeaturerequest.h"

///@cond PRIVATE

@@ -36,7 +37,9 @@ QString QgsAddIncrementalFieldAlgorithm::shortHelpString() const
"is not added to the input layer but a new layer is generated instead.\n\n"
"The initial starting value for the incremental series can be specified.\n\n"
"Optionally, grouping fields can be specified. If group fields are present, then the field value will "
"be reset for each combination of these group field values." );
"be reset for each combination of these group field values.\n\n"
"The sort order for features may be specified, if so, then the incremental field will respect "
"this sort order." );
}

QStringList QgsAddIncrementalFieldAlgorithm::tags() const
@@ -81,6 +84,17 @@ void QgsAddIncrementalFieldAlgorithm::initParameters( const QVariantMap & )
QgsProcessingParameterNumber::Integer, 0, true ) );
addParameter( new QgsProcessingParameterField( QStringLiteral( "GROUP_FIELDS" ), QObject::tr( "Group values by" ), QVariant(),
QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, true, true ) );

// sort params
std::unique_ptr< QgsProcessingParameterExpression > sortExp = qgis::make_unique< QgsProcessingParameterExpression >( QStringLiteral( "SORT_EXPRESSION" ), QObject::tr( "Sort expression" ), QVariant(), QStringLiteral( "INPUT" ), true );
sortExp->setFlags( sortExp->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
addParameter( sortExp.release() );
std::unique_ptr< QgsProcessingParameterBoolean > sortAscending = qgis::make_unique< QgsProcessingParameterBoolean >( QStringLiteral( "SORT_ASCENDING" ), QObject::tr( "Sort ascending" ), true, true );
sortAscending->setFlags( sortAscending->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
addParameter( sortAscending.release() );
std::unique_ptr< QgsProcessingParameterBoolean > sortNullsFirst = qgis::make_unique< QgsProcessingParameterBoolean >( QStringLiteral( "SORT_NULLS_FIRST" ), QObject::tr( "Sort nulls first" ), false, true );
sortNullsFirst->setFlags( sortNullsFirst->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
addParameter( sortNullsFirst.release() );
}

QgsFields QgsAddIncrementalFieldAlgorithm::outputFields( const QgsFields &inputFields ) const
@@ -97,9 +111,22 @@ bool QgsAddIncrementalFieldAlgorithm::prepareAlgorithm( const QVariantMap &param
mValue = mStartValue;
mFieldName = parameterAsString( parameters, QStringLiteral( "FIELD_NAME" ), context );
mGroupedFieldNames = parameterAsFields( parameters, QStringLiteral( "GROUP_FIELDS" ), context );

mSortExpressionString = parameterAsExpression( parameters, QStringLiteral( "SORT_EXPRESSION" ), context );
mSortAscending = parameterAsBool( parameters, QStringLiteral( "SORT_ASCENDING" ), context );
mSortNullsFirst = parameterAsBool( parameters, QStringLiteral( "SORT_NULLS_FIRST" ), context );

return true;
}

QgsFeatureRequest QgsAddIncrementalFieldAlgorithm::request() const
{
if ( mSortExpressionString.isEmpty() )
return QgsFeatureRequest();

return QgsFeatureRequest().setOrderBy( QgsFeatureRequest::OrderBy() << QgsFeatureRequest::OrderByClause( mSortExpressionString, mSortAscending, mSortNullsFirst ) );
}

QgsFeatureList QgsAddIncrementalFieldAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * )
{
if ( !mGroupedFieldNames.empty() && mGroupedFields.empty() )
@@ -51,6 +51,7 @@ class QgsAddIncrementalFieldAlgorithm : public QgsProcessingFeatureBasedAlgorith
QgsProcessingFeatureSource::Flag sourceFlags() const override;

bool prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
QgsFeatureRequest request() const override;
QgsFeatureList processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;

private:
@@ -62,6 +63,12 @@ class QgsAddIncrementalFieldAlgorithm : public QgsProcessingFeatureBasedAlgorith
mutable QgsFields mFields;
QStringList mGroupedFieldNames;
QgsAttributeList mGroupedFields;

QString mSortExpressionString;
bool mSortAscending = true;
bool mSortNullsFirst = false;


};

///@endcond PRIVATE
@@ -732,7 +732,7 @@ QVariantMap QgsProcessingFeatureBasedAlgorithm::processAlgorithm( const QVariant
long count = mSource->featureCount();

QgsFeature f;
QgsFeatureIterator it = mSource->getFeatures( QgsFeatureRequest(), sourceFlags() );
QgsFeatureIterator it = mSource->getFeatures( request(), sourceFlags() );

double step = count > 0 ? 100.0 / count : 1;
int current = 0;

0 comments on commit 0e0e133

Please sign in to comment.
You can’t perform that action at this time.