Skip to content

Commit

Permalink
[processing] group option for autoincrement field algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Dec 1, 2017
1 parent 62ff88a commit 8026008
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 6 deletions.
@@ -0,0 +1,97 @@
<?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_grouped.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>-1</gml:X><gml:Y>-3</gml:Y></gml:coord>
<gml:coord><gml:X>9.162955854126682</gml:X><gml:Y>6.088675623800385</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:autoincrement_grouped fid="polys.0">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>aa</ogr:name>
<ogr:intval>1</ogr:intval>
<ogr:floatval>44.123456</ogr:floatval>
<ogr:AUTO>6</ogr:AUTO>
</ogr:autoincrement_grouped>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_grouped fid="polys.1">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>6.24145873320538,-0.054510556621882 7.24145873320538,-1.05451055662188 5.24145873320538,-1.05451055662188 6.24145873320538,-0.054510556621882</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>dd</ogr:name>
<ogr:floatval>0</ogr:floatval>
<ogr:AUTO>6</ogr:AUTO>
</ogr:autoincrement_grouped>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_grouped fid="polys.2">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,5 2,6 3,6 3,5 2,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>bb</ogr:name>
<ogr:intval>1</ogr:intval>
<ogr:floatval>0.123</ogr:floatval>
<ogr:AUTO>6</ogr:AUTO>
</ogr:autoincrement_grouped>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_grouped fid="polys.3">
<ogr:intval>120</ogr:intval>
<ogr:floatval>-100291.43213</ogr:floatval>
<ogr:AUTO>6</ogr:AUTO>
</ogr:autoincrement_grouped>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_grouped fid="polys.4">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>3,2 6,1 6,-3 2,-1 2,2 3,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>aa</ogr:name>
<ogr:intval>1</ogr:intval>
<ogr:floatval>3.33</ogr:floatval>
<ogr:AUTO>7</ogr:AUTO>
</ogr:autoincrement_grouped>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_grouped fid="polys.5">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2.44337811900192,4.42360844529751 2.44337811900192,5.42360844529751 3.44337811900192,5.42360844529751 3.44337811900192,4.42360844529751 2.44337811900192,4.42360844529751</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>bb</ogr:name>
<ogr:intval>1</ogr:intval>
<ogr:floatval>0.123</ogr:floatval>
<ogr:AUTO>7</ogr:AUTO>
</ogr:autoincrement_grouped>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_grouped fid="polys.6">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>4.17255278310941,4.82264875239923 4.17255278310941,5.82264875239923 5.17255278310941,5.82264875239923 5.17255278310941,4.82264875239923 4.17255278310941,4.82264875239923</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>bb</ogr:name>
<ogr:intval>1</ogr:intval>
<ogr:floatval>0.123</ogr:floatval>
<ogr:AUTO>8</ogr:AUTO>
</ogr:autoincrement_grouped>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_grouped fid="polys.7">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>8.16295585412668,2.73877159309021 8.16295585412668,3.73877159309021 9.16295585412668,3.73877159309021 9.16295585412668,2.73877159309021 8.16295585412668,2.73877159309021</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>cc</ogr:name>
<ogr:floatval>0.123</ogr:floatval>
<ogr:AUTO>6</ogr:AUTO>
</ogr:autoincrement_grouped>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_grouped fid="polys.9">
<ogr:name>dd</ogr:name>
<ogr:AUTO>7</ogr:AUTO>
</ogr:autoincrement_grouped>
</gml:featureMember>
<gml:featureMember>
<ogr:autoincrement_grouped fid="polys.8">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2.62072936660269,5.08867562380038 2.62072936660269,6.08867562380038 3.62072936660269,6.08867562380038 3.62072936660269,5.08867562380038 2.62072936660269,5.08867562380038</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>bb</ogr:name>
<ogr:intval>2</ogr:intval>
<ogr:floatval>0.123</ogr:floatval>
<ogr:AUTO>6</ogr:AUTO>
</ogr:autoincrement_grouped>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -0,0 +1,50 @@
<?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_grouped" type="ogr:autoincrement_grouped_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="autoincrement_grouped_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:PolygonPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
<xs:element name="name" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="2"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="intval" 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="floatval" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:decimal">
</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>
15 changes: 15 additions & 0 deletions python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
Expand Up @@ -451,6 +451,21 @@ tests:
name: expected/autoincrement_field_field_name.gml
type: vector

- algorithm: native:addautoincrementalfield
name: Add incremental field (grouped)
params:
FIELD_NAME: AUTO
GROUP_FIELDS:
- intval
- name
INPUT:
name: dissolve_polys.gml
type: vector
START: 6
results:
OUTPUT:
name: expected/autoincrement_grouped.gml
type: vector

- algorithm: native:dissolve
name: Dissolve using field
Expand Down
42 changes: 37 additions & 5 deletions src/analysis/processing/qgsalgorithmaddincrementalfield.cpp
Expand Up @@ -34,12 +34,14 @@ QString QgsAddIncrementalFieldAlgorithm::shortHelpString() const
return QObject::tr( "This algorithm adds a new integer field to a vector layer, with a sequential value for each feature.\n\n"
"This field can be used as a unique ID for features in the layer. The new attribute "
"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." );
"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." );
}

QStringList QgsAddIncrementalFieldAlgorithm::tags() const
{
return QObject::tr( "add,create,serial,primary,key,unique,field" ).split( ',' );
return QObject::tr( "add,create,serial,primary,key,unique,fields" ).split( ',' );
}

QString QgsAddIncrementalFieldAlgorithm::group() const
Expand Down Expand Up @@ -67,28 +69,58 @@ void QgsAddIncrementalFieldAlgorithm::initParameters( const QVariantMap & )
addParameter( new QgsProcessingParameterString( QStringLiteral( "FIELD_NAME" ), QObject::tr( "Field name" ), QStringLiteral( "AUTO" ) ) );
addParameter( new QgsProcessingParameterNumber( QStringLiteral( "START" ), QObject::tr( "Start values at" ),
QgsProcessingParameterNumber::Integer, 0, true ) );
addParameter( new QgsProcessingParameterField( QStringLiteral( "GROUP_FIELDS" ), QObject::tr( "Group values by" ), QVariant(),
QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, true, true ) );
}

QgsFields QgsAddIncrementalFieldAlgorithm::outputFields( const QgsFields &inputFields ) const
{
QgsFields outFields = inputFields;
outFields.append( QgsField( mFieldName, QVariant::LongLong ) );
mFields = outFields;
return outFields;
}

bool QgsAddIncrementalFieldAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
{
mValue = parameterAsInt( parameters, QStringLiteral( "START" ), context );
mStartValue = parameterAsInt( parameters, QStringLiteral( "START" ), context );
mValue = mStartValue;
mFieldName = parameterAsString( parameters, QStringLiteral( "FIELD_NAME" ), context );
mGroupedFieldNames = parameterAsFields( parameters, QStringLiteral( "GROUP_FIELDS" ), context );
return true;
}

QgsFeature QgsAddIncrementalFieldAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingFeedback * )
{
if ( !mGroupedFieldNames.empty() && mGroupedFields.empty() )
{
for ( const QString &field : mGroupedFieldNames )
{
int idx = mFields.lookupField( field );
if ( idx >= 0 )
mGroupedFields << idx;
}
}

QgsFeature f = feature;
QgsAttributes attributes = f.attributes();
attributes.append( mValue );
mValue++;
if ( mGroupedFields.empty() )
{
attributes.append( mValue );
mValue++;
}
else
{
QgsAttributes groupAttributes;
for ( int index : qgis::as_const( mGroupedFields ) )
{
groupAttributes << f.attribute( index );
}
long long value = mGroupedValues.value( groupAttributes, mStartValue );
attributes.append( value );
value++;
mGroupedValues[ groupAttributes ] = value;
}
f.setAttributes( attributes );
return f;
}
Expand Down
6 changes: 5 additions & 1 deletion src/analysis/processing/qgsalgorithmaddincrementalfield.h
Expand Up @@ -53,9 +53,13 @@ class QgsAddIncrementalFieldAlgorithm : public QgsProcessingFeatureBasedAlgorith

private:

long long mStartValue = 0;
long long mValue = 0;
QString mFieldName;

QHash< QgsAttributes, long long > mGroupedValues;
mutable QgsFields mFields;
QStringList mGroupedFieldNames;
QgsAttributeList mGroupedFields;
};

///@endcond PRIVATE
Expand Down

0 comments on commit 8026008

Please sign in to comment.