Skip to content
Permalink
Browse files
[FEATURE] New $atlasfeature expression function for returning the cur…
…rent atlas feature. Also clean up the expression groups and move some unrelated functions out of the 'Record' group.
  • Loading branch information
nyalldawson committed Jul 10, 2014
1 parent 1e39db6 commit 9abeeb6
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 7 deletions.
@@ -0,0 +1,13 @@
<h3>$atlasfeature function</h3>
In atlas generation, returns the current feature that is iterated over on the coverage layer. This can be used with the 'attribute' function
to return attribute values from the current atlas feature.

<h4>Syntax</h4>
<pre>$atlasfeature</pre>

<h4>Arguments</h4>
None

<h4>Example</h4>
<pre>attribute( $atlasfeature, 'name' ) &rarr; returns value stored in 'name' attribute for the current atlas feature</pre>

@@ -3491,6 +3491,7 @@ void QgsComposer::setAtlasFeature( QgsMapLayer* layer, QgsFeature * feat )
{
//update expression variables
QgsExpression::setSpecialColumn( "$atlasfeatureid", feat->id() );
QgsExpression::setSpecialColumn( "$atlasfeature", QVariant::fromValue( *feat ) );
QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *( feat->geometry() ) ) );

emit atlasPreviewFeatureChanged();
@@ -45,6 +45,7 @@ QgsAtlasComposition::QgsAtlasComposition( QgsComposition* composition ) :
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )1 ) );
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )0 ) );
QgsExpression::setSpecialColumn( "$atlasfeatureid", QVariant(( int )0 ) );
QgsExpression::setSpecialColumn( "$atlasfeature", QVariant::fromValue( QgsFeature() ) );
QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( QgsGeometry() ) );
}

@@ -73,6 +74,7 @@ void QgsAtlasComposition::setCoverageLayer( QgsVectorLayer* layer )
layer->getFeatures().nextFeature( fet );
QgsExpression::setSpecialColumn( "$atlasfeatureid", fet.id() );
QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *fet.geometry() ) );
QgsExpression::setSpecialColumn( "$atlasfeature", QVariant::fromValue( fet ) );
}

emit coverageLayerChanged( layer );
@@ -357,6 +359,7 @@ bool QgsAtlasComposition::prepareForFeature( int featureI )

QgsExpression::setSpecialColumn( "$atlasfeatureid", mCurrentFeature.id() );
QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *mCurrentFeature.geometry() ) );
QgsExpression::setSpecialColumn( "$atlasfeature", QVariant::fromValue( mCurrentFeature ) );
QgsExpression::setSpecialColumn( "$feature", QVariant(( int )featureI + 1 ) );

// generate filename for current feature
@@ -1680,14 +1680,14 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
<< new StaticFunction( "geomToWKT", 1, fcnGeomToWKT, "Geometry" )
<< new StaticFunction( "$rownum", 0, fcnRowNumber, "Record" )
<< new StaticFunction( "$id", 0, fcnFeatureId, "Record" )
<< new StaticFunction( "$currentfeature", 0, fcnFeature, "Features" )
<< new StaticFunction( "$currentfeature", 0, fcnFeature, "Record" )
<< new StaticFunction( "$scale", 0, fcnScale, "Record" )
<< new StaticFunction( "$uuid", 0, fcnUuid, "Record" )

//return all attributes string for referencedColumns - this is caught by
// QgsFeatureRequest::setSubsetOfAttributes and causes all attributes to be fetched by the
// feature request
<< new StaticFunction( "attribute", 2, fcnAttribute, "Features", QString(), false, QStringList( QgsFeatureRequest::AllAttributes ) )
<< new StaticFunction( "attribute", 2, fcnAttribute, "Record", QString(), false, QStringList( QgsFeatureRequest::AllAttributes ) )

<< new StaticFunction( "_specialcol_", 1, fcnSpecialColumn, "Special" )
;
@@ -1696,6 +1696,7 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
}

QMap<QString, QVariant> QgsExpression::gmSpecialColumns;
QMap<QString, QString> QgsExpression::gmSpecialColumnGroups;

void QgsExpression::setSpecialColumn( const QString& name, QVariant variant )
{
@@ -1742,10 +1743,23 @@ bool QgsExpression::hasSpecialColumn( const QString& name )
// This is really sub-optimal, we should get rid of the special columns and instead have contexts in which some values
// are defined and some are not ($rownum makes sense only in field calculator, $scale only when rendering, $page only for composer etc.)

QStringList lst;
lst << "$page" << "$feature" << "$numpages" << "$numfeatures" << "$atlasfeatureid" << "$atlasgeometry" << "$map";
foreach ( QString c, lst )
setSpecialColumn( c, QVariant() );
//pairs of column name to group name
QList< QPair<QString, QString> > lst;
lst << qMakePair( QString( "$page" ), QString( "Composer" ) );
lst << qMakePair( QString( "$feature" ), QString( "Atlas" ) );
lst << qMakePair( QString( "$numpages" ), QString( "Composer" ) );
lst << qMakePair( QString( "$numfeatures" ), QString( "Atlas" ) );
lst << qMakePair( QString( "$atlasfeatureid" ), QString( "Atlas" ) );
lst << qMakePair( QString( "$atlasgeometry" ), QString( "Atlas" ) );
lst << qMakePair( QString( "$atlasfeature" ), QString( "Atlas" ) );
lst << qMakePair( QString( "$map" ), QString( "Composer" ) );

QList< QPair<QString, QString> >::const_iterator it = lst.constBegin();
for ( ; it != lst.constEnd(); ++it )
{
setSpecialColumn(( *it ).first, QVariant() );
gmSpecialColumnGroups[( *it ).first ] = ( *it ).second;
}

initialized = true;
}
@@ -1768,7 +1782,9 @@ QList<QgsExpression::Function*> QgsExpression::specialColumns()
QList<Function*> defs;
for ( QMap<QString, QVariant>::const_iterator it = gmSpecialColumns.begin(); it != gmSpecialColumns.end(); ++it )
{
defs << new StaticFunction( it.key(), 0, 0, "Record" );
//check for special column group name
QString group = gmSpecialColumnGroups.value( it.key(), "Record" );
defs << new StaticFunction( it.key(), 0, 0, group );
}
return defs;
}
@@ -629,6 +629,8 @@ class CORE_EXPORT QgsExpression
QString mExp;

static QMap<QString, QVariant> gmSpecialColumns;
static QMap<QString, QString> gmSpecialColumnGroups;

QgsDistanceArea *mCalc;

friend class QgsOgcUtils;

0 comments on commit 9abeeb6

Please sign in to comment.