@@ -382,6 +382,8 @@ QgsPalLayerSettings &QgsPalLayerSettings::operator=( const QgsPalLayerSettings &
382
382
mFormat = s.mFormat ;
383
383
mDataDefinedProperties = s.mDataDefinedProperties ;
384
384
385
+ geometryGenerator = s.geometryGenerator ;
386
+
385
387
return *this ;
386
388
}
387
389
@@ -678,6 +680,8 @@ void QgsPalLayerSettings::readFromLayerCustomProperties( QgsVectorLayer *layer )
678
680
obstacleType = static_cast < ObstacleType >( layer->customProperty ( QStringLiteral ( " labeling/obstacleType" ), QVariant ( PolygonInterior ) ).toUInt () );
679
681
zIndex = layer->customProperty ( QStringLiteral ( " labeling/zIndex" ), QVariant ( 0.0 ) ).toDouble ();
680
682
683
+ geometryGenerator = layer->customProperty ( QStringLiteral ( " labeling/zIndex" ), QString ( " translate($geometry, 10, 10)" ) ).toString ();
684
+
681
685
mDataDefinedProperties .clear ();
682
686
if ( layer->customProperty ( QStringLiteral ( " labeling/ddProperties" ) ).isValid () )
683
687
{
@@ -891,6 +895,7 @@ void QgsPalLayerSettings::readXml( QDomElement &elem, const QgsReadWriteContext
891
895
obstacleFactor = renderingElem.attribute ( QStringLiteral ( " obstacleFactor" ), QStringLiteral ( " 1" ) ).toDouble ();
892
896
obstacleType = static_cast < ObstacleType >( renderingElem.attribute ( QStringLiteral ( " obstacleType" ), QString::number ( PolygonInterior ) ).toUInt () );
893
897
zIndex = renderingElem.attribute ( QStringLiteral ( " zIndex" ), QStringLiteral ( " 0.0" ) ).toDouble ();
898
+ geometryGenerator = renderingElem.attribute ( QStringLiteral ( " geometryGenerator" ), " translate($geometry, 10, 10)" );
894
899
895
900
QDomElement ddElem = elem.firstChildElement ( QStringLiteral ( " dd_properties" ) );
896
901
if ( !ddElem.isNull () )
@@ -941,6 +946,8 @@ void QgsPalLayerSettings::readXml( QDomElement &elem, const QgsReadWriteContext
941
946
mDataDefinedProperties .setProperty ( MinimumScale, mDataDefinedProperties .property ( MaxScale ) );
942
947
mDataDefinedProperties .setProperty ( MaxScale, QgsProperty () );
943
948
}
949
+
950
+
944
951
}
945
952
946
953
@@ -998,6 +1005,7 @@ QDomElement QgsPalLayerSettings::writeXml( QDomDocument &doc, const QgsReadWrite
998
1005
placementElem.setAttribute ( QStringLiteral ( " repeatDistance" ), repeatDistance );
999
1006
placementElem.setAttribute ( QStringLiteral ( " repeatDistanceUnits" ), QgsUnitTypes::encodeUnit ( repeatDistanceUnit ) );
1000
1007
placementElem.setAttribute ( QStringLiteral ( " repeatDistanceMapUnitScale" ), QgsSymbolLayerUtils::encodeMapUnitScale ( repeatDistanceMapUnitScale ) );
1008
+ placementElem.setAttribute ( QStringLiteral ( " geometryGenerator" ), geometryGenerator );
1001
1009
1002
1010
// rendering
1003
1011
QDomElement renderingElem = doc.createElement ( QStringLiteral ( " rendering" ) );
@@ -1186,11 +1194,23 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF *fm, const QSt
1186
1194
1187
1195
void QgsPalLayerSettings::registerFeature ( const QgsFeature &f, QgsRenderContext &context, QgsLabelFeature **labelFeature, QgsGeometry obstacleGeometry )
1188
1196
{
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
+
1189
1209
// either used in QgsPalLabeling (palLayer is set) or in QgsLabelingEngine (labelFeature is set)
1190
1210
Q_ASSERT ( labelFeature );
1191
1211
1192
1212
QVariant exprVal; // value() is repeatedly nulled on data defined evaluation and replaced when successful
1193
- mCurFeat = &f ;
1213
+ mCurFeat = &feature ;
1194
1214
1195
1215
// data defined is obstacle? calculate this first, to avoid wasting time working with obstacles we don't require
1196
1216
bool isObstacle = mDataDefinedProperties .valueAsBool ( QgsPalLayerSettings::IsObstacle, context.expressionContext (), obstacle ); // default to layer default
@@ -1199,7 +1219,7 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
1199
1219
{
1200
1220
if ( isObstacle )
1201
1221
{
1202
- registerObstacleFeature ( f , context, labelFeature, obstacleGeometry );
1222
+ registerObstacleFeature ( feature , context, labelFeature, obstacleGeometry );
1203
1223
}
1204
1224
return ;
1205
1225
}
@@ -1337,7 +1357,7 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
1337
1357
}
1338
1358
else
1339
1359
{
1340
- const QVariant &v = f .attribute ( fieldIndex );
1360
+ const QVariant &v = feature .attribute ( fieldIndex );
1341
1361
labelText = v.isNull () ? QString () : v.toString ();
1342
1362
}
1343
1363
@@ -1464,7 +1484,7 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
1464
1484
}
1465
1485
}
1466
1486
1467
- QgsGeometry geom = f .geometry ();
1487
+ QgsGeometry geom = feature .geometry ();
1468
1488
if ( geom.isNull () )
1469
1489
{
1470
1490
return ;
@@ -1849,7 +1869,7 @@ void QgsPalLayerSettings::registerFeature( const QgsFeature &f, QgsRenderContext
1849
1869
}
1850
1870
1851
1871
// 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 ) );
1853
1873
mFeatsRegPal ++;
1854
1874
1855
1875
*labelFeature = lf;
0 commit comments