@@ -382,6 +382,8 @@ QgsPalLayerSettings &QgsPalLayerSettings::operator=( const QgsPalLayerSettings &
382382 mFormat = s.mFormat ;
383383 mDataDefinedProperties = s.mDataDefinedProperties ;
384384
385+ geometryGenerator = s.geometryGenerator ;
386+
385387 return *this ;
386388}
387389
@@ -678,6 +680,8 @@ void QgsPalLayerSettings::readFromLayerCustomProperties( QgsVectorLayer *layer )
678680 obstacleType = static_cast < ObstacleType >( layer->customProperty ( QStringLiteral ( " labeling/obstacleType" ), QVariant ( PolygonInterior ) ).toUInt () );
679681 zIndex = layer->customProperty ( QStringLiteral ( " labeling/zIndex" ), QVariant ( 0.0 ) ).toDouble ();
680682
683+ geometryGenerator = layer->customProperty ( QStringLiteral ( " labeling/zIndex" ), QString ( " translate($geometry, 10, 10)" ) ).toString ();
684+
681685 mDataDefinedProperties .clear ();
682686 if ( layer->customProperty ( QStringLiteral ( " labeling/ddProperties" ) ).isValid () )
683687 {
@@ -891,6 +895,7 @@ void QgsPalLayerSettings::readXml( QDomElement &elem, const QgsReadWriteContext
891895 obstacleFactor = renderingElem.attribute ( QStringLiteral ( " obstacleFactor" ), QStringLiteral ( " 1" ) ).toDouble ();
892896 obstacleType = static_cast < ObstacleType >( renderingElem.attribute ( QStringLiteral ( " obstacleType" ), QString::number ( PolygonInterior ) ).toUInt () );
893897 zIndex = renderingElem.attribute ( QStringLiteral ( " zIndex" ), QStringLiteral ( " 0.0" ) ).toDouble ();
898+ geometryGenerator = renderingElem.attribute ( QStringLiteral ( " geometryGenerator" ), " translate($geometry, 10, 10)" );
894899
895900 QDomElement ddElem = elem.firstChildElement ( QStringLiteral ( " dd_properties" ) );
896901 if ( !ddElem.isNull () )
@@ -941,6 +946,8 @@ void QgsPalLayerSettings::readXml( QDomElement &elem, const QgsReadWriteContext
941946 mDataDefinedProperties .setProperty ( MinimumScale, mDataDefinedProperties .property ( MaxScale ) );
942947 mDataDefinedProperties .setProperty ( MaxScale, QgsProperty () );
943948 }
949+
950+
944951}
945952
946953
@@ -998,6 +1005,7 @@ QDomElement QgsPalLayerSettings::writeXml( QDomDocument &doc, const QgsReadWrite
9981005 placementElem.setAttribute ( QStringLiteral ( " repeatDistance" ), repeatDistance );
9991006 placementElem.setAttribute ( QStringLiteral ( " repeatDistanceUnits" ), QgsUnitTypes::encodeUnit ( repeatDistanceUnit ) );
10001007 placementElem.setAttribute ( QStringLiteral ( " repeatDistanceMapUnitScale" ), QgsSymbolLayerUtils::encodeMapUnitScale ( repeatDistanceMapUnitScale ) );
1008+ placementElem.setAttribute ( QStringLiteral ( " geometryGenerator" ), geometryGenerator );
10011009
10021010 // rendering
10031011 QDomElement renderingElem = doc.createElement ( QStringLiteral ( " rendering" ) );
@@ -1186,11 +1194,23 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF *fm, const QSt
11861194
11871195void QgsPalLayerSettings::registerFeature ( const QgsFeature &f, QgsRenderContext &context, QgsLabelFeature **labelFeature, QgsGeometry obstacleGeometry )
11881196{
1197+ QgsFeature feature = f;
1198+ if ( !geometryGenerator.isNull () )
1199+ {
1200+ QgsExpressionContext expContext = context.expressionContext ();
1201+ // TODO: cache and prepare
1202+ QgsExpression exp ( geometryGenerator );
1203+ exp.prepare ( &expContext );
1204+ expContext.setFeature ( feature );
1205+ QgsGeometry geometry = exp.evaluate ( &expContext ).value <QgsGeometry>();
1206+ feature.setGeometry ( geometry );
1207+ }
1208+
11891209 // either used in QgsPalLabeling (palLayer is set) or in QgsLabelingEngine (labelFeature is set)
11901210 Q_ASSERT ( labelFeature );
11911211
11921212 QVariant exprVal; // value() is repeatedly nulled on data defined evaluation and replaced when successful
1193- mCurFeat = &f ;
1213+ mCurFeat = &feature ;
11941214
11951215 // data defined is obstacle? calculate this first, to avoid wasting time working with obstacles we don't require
11961216 bool isObstacle = mDataDefinedProperties .valueAsBool ( QgsPalLayerSettings::IsObstacle, context.expressionContext (), obstacle ); // default to layer default
@@ -1199,7 +1219,7 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
11991219 {
12001220 if ( isObstacle )
12011221 {
1202- registerObstacleFeature ( f , context, labelFeature, obstacleGeometry );
1222+ registerObstacleFeature ( feature , context, labelFeature, obstacleGeometry );
12031223 }
12041224 return ;
12051225 }
@@ -1337,7 +1357,7 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
13371357 }
13381358 else
13391359 {
1340- const QVariant &v = f .attribute ( fieldIndex );
1360+ const QVariant &v = feature .attribute ( fieldIndex );
13411361 labelText = v.isNull () ? QString () : v.toString ();
13421362 }
13431363
@@ -1464,7 +1484,7 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
14641484 }
14651485 }
14661486
1467- QgsGeometry geom = f .geometry ();
1487+ QgsGeometry geom = feature .geometry ();
14681488 if ( geom.isNull () )
14691489 {
14701490 return ;
@@ -1849,7 +1869,7 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
18491869 }
18501870
18511871 // feature to the layer
1852- QgsTextLabelFeature *lf = new QgsTextLabelFeature ( f .id (), std::move ( geos_geom_clone ), QSizeF ( labelX, labelY ) );
1872+ QgsTextLabelFeature *lf = new QgsTextLabelFeature ( feature .id (), std::move ( geos_geom_clone ), QSizeF ( labelX, labelY ) );
18531873 mFeatsRegPal ++;
18541874
18551875 *labelFeature = lf;
0 commit comments