@@ -895,7 +895,9 @@ void QgsSimpleMarkerSymbolLayerV2::prepareExpressions( const QgsVectorLayer* vl
895
895
// ////////
896
896
897
897
898
- QgsSvgMarkerSymbolLayerV2::QgsSvgMarkerSymbolLayerV2 ( QString name, double size, double angle )
898
+ QgsSvgMarkerSymbolLayerV2::QgsSvgMarkerSymbolLayerV2 ( QString name, double size, double angle ): mSizeExpression( 0 ),
899
+ mOutlineWidthExpression( 0 ), mAngleExpression( 0 ), mOffsetExpression( 0 ), mNameExpression( 0 ), mFillExpression( 0 ),
900
+ mOutlineExpression( 0 )
899
901
{
900
902
mPath = QgsSymbolLayerV2Utils::symbolNameToPath ( name );
901
903
mSize = size;
@@ -958,6 +960,36 @@ QgsSymbolLayerV2* QgsSvgMarkerSymbolLayerV2::create( const QgsStringMap& props )
958
960
m->setOutlineWidth ( props[" outline-width" ].toDouble () );
959
961
if ( props.contains ( " outline_width_unit" ) )
960
962
m->setOutlineWidthUnit ( QgsSymbolLayerV2Utils::decodeOutputUnit ( props[" outline_width_unit" ] ) );
963
+
964
+ // data defined properties
965
+ if ( props.contains ( " size_expression" ) )
966
+ {
967
+ m->setDataDefinedProperty ( " size" , props[" size_expression" ] );
968
+ }
969
+ if ( props.contains ( " outline-width_expression" ) )
970
+ {
971
+ m->setDataDefinedProperty ( " outline-width" , props[" outline-width_expression" ] );
972
+ }
973
+ if ( props.contains ( " angle_expression" ) )
974
+ {
975
+ m->setDataDefinedProperty ( " angle" , props[" angle_expression" ] );
976
+ }
977
+ if ( props.contains ( " offset_expression" ) )
978
+ {
979
+ m->setDataDefinedProperty ( " offset" , props[" offset_expression" ] );
980
+ }
981
+ if ( props.contains ( " name_expression" ) )
982
+ {
983
+ m->setDataDefinedProperty ( " name" , props[" name_expression" ] );
984
+ }
985
+ if ( props.contains ( " fill_expression" ) )
986
+ {
987
+ m->setDataDefinedProperty ( " fill" , props[" fill_expression" ] );
988
+ }
989
+ if ( props.contains ( " outline_expression" ) )
990
+ {
991
+ m->setDataDefinedProperty ( " outline" , props[" outline_expression" ] );
992
+ }
961
993
return m;
962
994
}
963
995
@@ -992,6 +1024,7 @@ void QgsSvgMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
992
1024
{
993
1025
mOrigSize = mSize ; // save in case the size would be data defined
994
1026
Q_UNUSED ( context );
1027
+ prepareExpressions ( context.layer () );
995
1028
}
996
1029
997
1030
void QgsSvgMarkerSymbolLayerV2::stopRender ( QgsSymbolV2RenderContext& context )
@@ -1007,7 +1040,12 @@ void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Re
1007
1040
return ;
1008
1041
}
1009
1042
1010
- double size = mSize * QgsSymbolLayerV2Utils::lineWidthScaleFactor ( context.renderContext (), mSizeUnit );
1043
+ double size = mSize ;
1044
+ if ( mSizeExpression )
1045
+ {
1046
+ size = mSizeExpression ->evaluate ( const_cast <QgsFeature*>( context.feature () ) ).toDouble ();
1047
+ }
1048
+ size *= QgsSymbolLayerV2Utils::lineWidthScaleFactor ( context.renderContext (), mSizeUnit );
1011
1049
// don't render symbols with size below one or above 10,000 pixels
1012
1050
if (( int )size < 1 || 10000.0 < size )
1013
1051
{
@@ -1019,14 +1057,19 @@ void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Re
1019
1057
double offsetY = mOffset .y () * QgsSymbolLayerV2Utils::lineWidthScaleFactor ( context.renderContext (), mOffsetUnit );
1020
1058
QPointF outputOffset ( offsetX, offsetY );
1021
1059
1022
- if ( mAngle )
1023
- outputOffset = _rotatedOffset ( outputOffset, mAngle );
1060
+ double angle = mAngle ;
1061
+ if ( mAngleExpression )
1062
+ {
1063
+ angle = mAngleExpression ->evaluate ( const_cast <QgsFeature*>( context.feature () ) ).toDouble ();
1064
+ }
1065
+ if ( angle )
1066
+ outputOffset = _rotatedOffset ( outputOffset, angle );
1024
1067
p->translate ( point + outputOffset );
1025
1068
1026
- bool rotated = !doubleNear ( mAngle , 0 );
1069
+ bool rotated = !doubleNear ( angle , 0 );
1027
1070
bool drawOnScreen = doubleNear ( context.renderContext ().rasterScaleFactor (), 1.0 , 0.1 );
1028
1071
if ( rotated )
1029
- p->rotate ( mAngle );
1072
+ p->rotate ( angle );
1030
1073
1031
1074
bool fitsInCache = true ;
1032
1075
bool usePict = true ;
@@ -1102,6 +1145,36 @@ QgsStringMap QgsSvgMarkerSymbolLayerV2::properties() const
1102
1145
map[" outline" ] = mOutlineColor .name ();
1103
1146
map[" outline-width" ] = QString::number ( mOutlineWidth );
1104
1147
map[" outline_width_unit" ] = QgsSymbolLayerV2Utils::encodeOutputUnit ( mOutlineWidthUnit );
1148
+
1149
+ // data defined properties
1150
+ if ( mSizeExpression )
1151
+ {
1152
+ map[" size_expression" ] = mSizeExpression ->dump ();
1153
+ }
1154
+ if ( mOutlineWidthExpression )
1155
+ {
1156
+ map[" outline-width_expression" ] = mOutlineWidthExpression ->dump ();
1157
+ }
1158
+ if ( mAngleExpression )
1159
+ {
1160
+ map[" angle_expression" ] = mAngleExpression ->dump ();
1161
+ }
1162
+ if ( mOffsetExpression )
1163
+ {
1164
+ map[" offset_expression" ] = mOffsetExpression ->dump ();
1165
+ }
1166
+ if ( mNameExpression )
1167
+ {
1168
+ map[" name_expression" ] = mNameExpression ->dump ();
1169
+ }
1170
+ if ( mFillExpression )
1171
+ {
1172
+ map[" fill_expression" ] = mFillExpression ->dump ();
1173
+ }
1174
+ if ( mOutlineExpression )
1175
+ {
1176
+ map[" outline_expression" ] = mOutlineExpression ->dump ();
1177
+ }
1105
1178
return map;
1106
1179
}
1107
1180
@@ -1115,9 +1188,205 @@ QgsSymbolLayerV2* QgsSvgMarkerSymbolLayerV2::clone() const
1115
1188
m->setOffset ( mOffset );
1116
1189
m->setOffsetUnit ( mOffsetUnit );
1117
1190
m->setSizeUnit ( mSizeUnit );
1191
+
1192
+ // data defined properties
1193
+ if ( mSizeExpression )
1194
+ {
1195
+ m->setDataDefinedProperty ( " size" , mSizeExpression ->dump () );
1196
+ }
1197
+ if ( mOutlineWidthExpression )
1198
+ {
1199
+ m->setDataDefinedProperty ( " outline-width" , mOutlineWidthExpression ->dump () );
1200
+ }
1201
+ if ( mAngleExpression )
1202
+ {
1203
+ m->setDataDefinedProperty ( " angle" , mAngleExpression ->dump () );
1204
+ }
1205
+ if ( mOffsetExpression )
1206
+ {
1207
+ m->setDataDefinedProperty ( " offset" , mOffsetExpression ->dump () );
1208
+ }
1209
+ if ( mNameExpression )
1210
+ {
1211
+ m->setDataDefinedProperty ( " name" , mNameExpression ->dump () );
1212
+ }
1213
+ if ( mFillExpression )
1214
+ {
1215
+ m->setDataDefinedProperty ( " fill" , mFillExpression ->dump () );
1216
+ }
1217
+ if ( mOutlineExpression )
1218
+ {
1219
+ m->setDataDefinedProperty ( " outline" , mOutlineExpression ->dump () );
1220
+ }
1221
+
1118
1222
return m;
1119
1223
}
1120
1224
1225
+ const QgsExpression* QgsSvgMarkerSymbolLayerV2::dataDefinedProperty ( const QString& property ) const
1226
+ {
1227
+ if ( property == " size" )
1228
+ {
1229
+ return mSizeExpression ;
1230
+ }
1231
+ else if ( property == " outline-width" )
1232
+ {
1233
+ return mOutlineWidthExpression ;
1234
+ }
1235
+ else if ( property == " angle" )
1236
+ {
1237
+ return mAngleExpression ;
1238
+ }
1239
+ else if ( property == " offset" )
1240
+ {
1241
+ return mOffsetExpression ;
1242
+ }
1243
+ else if ( property == " name" )
1244
+ {
1245
+ return mNameExpression ;
1246
+ }
1247
+ else if ( property == " fill" )
1248
+ {
1249
+ return mFillExpression ;
1250
+ }
1251
+ else if ( property == " outline" )
1252
+ {
1253
+ return mOutlineExpression ;
1254
+ }
1255
+ return 0 ;
1256
+ }
1257
+
1258
+ QString QgsSvgMarkerSymbolLayerV2::dataDefinedPropertyString ( const QString& property ) const
1259
+ {
1260
+ const QgsExpression* ex = dataDefinedProperty ( property );
1261
+ return ( ex ? ex->dump () : QString () );
1262
+ }
1263
+
1264
+ void QgsSvgMarkerSymbolLayerV2::setDataDefinedProperty ( const QString& property, const QString& expressionString )
1265
+ {
1266
+ if ( property == " size" )
1267
+ {
1268
+ delete mSizeExpression ; mSizeExpression = new QgsExpression ( expressionString );
1269
+ }
1270
+ else if ( property == " outline-width" )
1271
+ {
1272
+ delete mOutlineWidthExpression ; mOutlineWidthExpression = new QgsExpression ( expressionString );
1273
+ }
1274
+ else if ( property == " angle" )
1275
+ {
1276
+ delete mAngleExpression ; mAngleExpression = new QgsExpression ( expressionString );
1277
+ }
1278
+ else if ( property == " offset" )
1279
+ {
1280
+ delete mOffsetExpression ; mOffsetExpression = new QgsExpression ( expressionString );
1281
+ }
1282
+ else if ( property == " name" )
1283
+ {
1284
+ delete mNameExpression ; mNameExpression = new QgsExpression ( expressionString );
1285
+ }
1286
+ else if ( property == " fill" )
1287
+ {
1288
+ delete mFillExpression ; mFillExpression = new QgsExpression ( expressionString );
1289
+ }
1290
+ else if ( property == " outline" )
1291
+ {
1292
+ delete mOutlineExpression ; mOutlineExpression = new QgsExpression ( expressionString );
1293
+ }
1294
+ }
1295
+
1296
+ void QgsSvgMarkerSymbolLayerV2::removeDataDefinedProperty ( const QString& property )
1297
+ {
1298
+ if ( property == " size" )
1299
+ {
1300
+ delete mSizeExpression ; mSizeExpression = 0 ;
1301
+ }
1302
+ else if ( property == " outline-width" )
1303
+ {
1304
+ delete mOutlineWidthExpression ; mOutlineWidthExpression = 0 ;
1305
+ }
1306
+ else if ( property == " angle" )
1307
+ {
1308
+ delete mAngleExpression ; mAngleExpression = 0 ;
1309
+ }
1310
+ else if ( property == " offset" )
1311
+ {
1312
+ delete mOffsetExpression ; mOffsetExpression = 0 ;
1313
+ }
1314
+ else if ( property == " name" )
1315
+ {
1316
+ delete mNameExpression ; mNameExpression = 0 ;
1317
+ }
1318
+ else if ( property == " fill" )
1319
+ {
1320
+ delete mFillExpression ; mFillExpression = 0 ;
1321
+ }
1322
+ else if ( property == " outline" )
1323
+ {
1324
+ delete mOutlineExpression ; mOutlineExpression = 0 ;
1325
+ }
1326
+ }
1327
+
1328
+ void QgsSvgMarkerSymbolLayerV2::removeDataDefinedProperties ()
1329
+ {
1330
+ delete mSizeExpression ; mSizeExpression = 0 ;
1331
+ delete mOutlineWidthExpression ; mOutlineWidthExpression = 0 ;
1332
+ delete mAngleExpression ; mAngleExpression = 0 ;
1333
+ delete mOffsetExpression ; mOffsetExpression = 0 ;
1334
+ delete mNameExpression ; mNameExpression = 0 ;
1335
+ delete mFillExpression ; mFillExpression = 0 ;
1336
+ delete mOutlineExpression ; mOutlineExpression = 0 ;
1337
+ }
1338
+
1339
+ QSet<QString> QgsSvgMarkerSymbolLayerV2::usedAttributes () const
1340
+ {
1341
+ QSet<QString> attributes;
1342
+
1343
+ // add data defined attributes
1344
+ QStringList columns;
1345
+ if ( mSizeExpression )
1346
+ columns.append ( mSizeExpression ->referencedColumns () );
1347
+ if ( mOutlineWidthExpression )
1348
+ columns.append ( mOutlineWidthExpression ->referencedColumns () );
1349
+ if ( mAngleExpression )
1350
+ columns.append ( mAngleExpression ->referencedColumns () );
1351
+ if ( mOffsetExpression )
1352
+ columns.append ( mOffsetExpression ->referencedColumns () );
1353
+ if ( mNameExpression )
1354
+ columns.append ( mNameExpression ->referencedColumns () );
1355
+ if ( mFillExpression )
1356
+ columns.append ( mFillExpression ->referencedColumns () );
1357
+ if ( mOutlineExpression )
1358
+ columns.append ( mOutlineExpression ->referencedColumns () );
1359
+
1360
+ QStringList::const_iterator it = columns.constBegin ();
1361
+ for ( ; it != columns.constEnd (); ++it )
1362
+ {
1363
+ attributes.insert ( *it );
1364
+ }
1365
+ return attributes;
1366
+ }
1367
+
1368
+ void QgsSvgMarkerSymbolLayerV2::prepareExpressions ( const QgsVectorLayer* vl )
1369
+ {
1370
+ if ( !vl )
1371
+ {
1372
+ return ;
1373
+ }
1374
+
1375
+ const QgsFields& fields = vl->pendingFields ();
1376
+ if ( mSizeExpression )
1377
+ mSizeExpression ->prepare ( fields );
1378
+ if ( mOutlineWidthExpression )
1379
+ mOutlineWidthExpression ->prepare ( fields );
1380
+ if ( mAngleExpression )
1381
+ mAngleExpression ->prepare ( fields );
1382
+ if ( mOffsetExpression )
1383
+ mOffsetExpression ->prepare ( fields );
1384
+ if ( mNameExpression )
1385
+ mNameExpression ->prepare ( fields );
1386
+ if ( mFillExpression )
1387
+ mFillExpression ->prepare ( fields );
1388
+ }
1389
+
1121
1390
void QgsSvgMarkerSymbolLayerV2::setOutputUnit ( QgsSymbolV2::OutputUnit unit )
1122
1391
{
1123
1392
mSizeUnit = unit;
0 commit comments