@@ -438,6 +438,64 @@ QString QgsVectorFileWriter::errorMessage()
438
438
bool QgsVectorFileWriter::addFeature ( QgsFeature& feature, QgsFeatureRendererV2* renderer )
439
439
{
440
440
// create the feature
441
+ OGRFeatureH poFeature = createFeature ( feature );
442
+
443
+ // add OGR feature style type
444
+ if ( mSymbologyExport != NoSymbology && renderer )
445
+ {
446
+ // SymbolLayerSymbology: concatenate ogr styles of all symbollayers
447
+ QgsSymbolV2List symbols = renderer->symbolsForFeature ( feature );
448
+ QString styleString;
449
+ QString currentStyle;
450
+
451
+ QgsSymbolV2List::const_iterator symbolIt = symbols.constBegin ();
452
+ for ( ; symbolIt != symbols.constEnd (); ++symbolIt )
453
+ {
454
+ int nSymbolLayers = ( *symbolIt )->symbolLayerCount ();
455
+ for ( int i = 0 ; i < nSymbolLayers; ++i )
456
+ {
457
+ /* QMap< QgsSymbolLayerV2*, QString >::const_iterator it = mSymbolLayerTable.find( (*symbolIt)->symbolLayer( i ) );
458
+ if( it == mSymbolLayerTable.constEnd() )
459
+ {
460
+ continue;
461
+ }*/
462
+ currentStyle = ( *symbolIt )->symbolLayer ( i )->ogrFeatureStyle ();// "@" + it.value();
463
+
464
+ if ( mSymbologyExport == FeatureSymbology )
465
+ {
466
+ if ( symbolIt != symbols.constBegin () || i != 0 )
467
+ {
468
+ styleString.append ( " ;" );
469
+ }
470
+ styleString.append ( currentStyle );
471
+ }
472
+ else if ( mSymbologyExport == SymbolLayerSymbology )
473
+ {
474
+ OGR_F_SetStyleString ( poFeature, currentStyle.toLocal8Bit ().data () );
475
+ if ( !writeFeature ( mLayer , poFeature ) )
476
+ {
477
+ return false ;
478
+ }
479
+ }
480
+ }
481
+ }
482
+ OGR_F_SetStyleString ( poFeature, styleString.toLocal8Bit ().data () );
483
+ }
484
+
485
+ if ( mSymbologyExport == NoSymbology || mSymbologyExport == FeatureSymbology )
486
+ {
487
+ if ( !writeFeature ( mLayer , poFeature ) )
488
+ {
489
+ return false ;
490
+ }
491
+ }
492
+
493
+ OGR_F_Destroy ( poFeature );
494
+ return true ;
495
+ }
496
+
497
+ OGRFeatureH QgsVectorFileWriter::createFeature ( QgsFeature& feature )
498
+ {
441
499
OGRFeatureH poFeature = OGR_F_Create ( OGR_L_GetLayerDefn ( mLayer ) );
442
500
443
501
qint64 fid = FID_TO_NUMBER ( feature.id () );
@@ -568,62 +626,10 @@ bool QgsVectorFileWriter::addFeature( QgsFeature& feature, QgsFeatureRendererV2*
568
626
OGR_F_SetGeometry ( poFeature, mGeom );
569
627
}
570
628
}
571
-
572
- // add OGR feature style type
573
- if ( mSymbologyExport != NoSymbology && renderer )
574
- {
575
- // SymbolLayerSymbology: concatenate ogr styles of all symbollayers
576
- QgsSymbolV2List symbols = renderer->symbolsForFeature ( feature );
577
- QString styleString;
578
- QString currentStyle;
579
-
580
- QgsSymbolV2List::const_iterator symbolIt = symbols.constBegin ();
581
- for ( ; symbolIt != symbols.constEnd (); ++symbolIt )
582
- {
583
- int nSymbolLayers = ( *symbolIt )->symbolLayerCount ();
584
- for ( int i = 0 ; i < nSymbolLayers; ++i )
585
- {
586
- /* QMap< QgsSymbolLayerV2*, QString >::const_iterator it = mSymbolLayerTable.find( (*symbolIt)->symbolLayer( i ) );
587
- if( it == mSymbolLayerTable.constEnd() )
588
- {
589
- continue;
590
- }*/
591
- currentStyle = ( *symbolIt )->symbolLayer ( i )->ogrFeatureStyle ();// "@" + it.value();
592
-
593
- if ( mSymbologyExport == FeatureSymbology )
594
- {
595
- if ( symbolIt != symbols.constBegin () || i != 0 )
596
- {
597
- styleString.append ( " ;" );
598
- }
599
- styleString.append ( currentStyle );
600
- }
601
- else if ( mSymbologyExport == SymbolLayerSymbology )
602
- {
603
- OGR_F_SetStyleString ( poFeature, currentStyle.toLocal8Bit ().data () );
604
- if ( !createFeature ( mLayer , poFeature ) )
605
- {
606
- return false ;
607
- }
608
- }
609
- }
610
- }
611
- OGR_F_SetStyleString ( poFeature, styleString.toLocal8Bit ().data () );
612
- }
613
-
614
- if ( mSymbologyExport == NoSymbology || mSymbologyExport == FeatureSymbology )
615
- {
616
- if ( !createFeature ( mLayer , poFeature ) )
617
- {
618
- return false ;
619
- }
620
- }
621
-
622
- OGR_F_Destroy ( poFeature );
623
- return true ;
629
+ return poFeature;
624
630
}
625
631
626
- bool QgsVectorFileWriter::createFeature ( OGRLayerH layer, OGRFeatureH feature )
632
+ bool QgsVectorFileWriter::writeFeature ( OGRLayerH layer, OGRFeatureH feature )
627
633
{
628
634
if ( OGR_L_CreateFeature ( layer, feature ) != OGRERR_NONE )
629
635
{
@@ -743,12 +749,24 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
743
749
shallTransform = false ;
744
750
}
745
751
746
- // create symbol table if neede
752
+ // create symbol table if needed
747
753
/* if( writer->symbologyExport() != NoSymbology )
748
754
{
749
755
writer->createSymbolLayerTable( layer, writer->mDS );
750
756
}*/
751
757
758
+ if ( writer->symbologyExport () == SymbolLayerSymbology && layer->isUsingRendererV2 () )
759
+ {
760
+ QgsFeatureRendererV2* r = layer->rendererV2 ();
761
+ if ( r->capabilities () & QgsFeatureRendererV2::SymbolLevels
762
+ && r->usingSymbolLevels () )
763
+ {
764
+ QgsVectorFileWriter::WriterError error = writer->exportFeaturesSymbolLevels ( layer, ct, errorMessage );
765
+ delete writer;
766
+ return ( error == NoError ) ? NoError : ErrFeatureWriteFailed;
767
+ }
768
+ }
769
+
752
770
int n = 0 , errors = 0 ;
753
771
754
772
// write all features
@@ -1184,3 +1202,105 @@ void QgsVectorFileWriter::createSymbolLayerTable( QgsVectorLayer* vl, OGRDataSo
1184
1202
}
1185
1203
OGR_DS_SetStyleTableDirectly ( ds, ogrStyleTable );
1186
1204
}
1205
+
1206
+ QgsVectorFileWriter::WriterError QgsVectorFileWriter::exportFeaturesSymbolLevels ( QgsVectorLayer* layer, const QgsCoordinateTransform* ct, QString* errorMessage )
1207
+ {
1208
+ if ( !layer || !layer->isUsingRendererV2 () )
1209
+ {
1210
+ // return error
1211
+ }
1212
+ QgsFeatureRendererV2* renderer = layer->rendererV2 ();
1213
+ if ( !renderer )
1214
+ {
1215
+ // return error
1216
+ }
1217
+ QHash< QgsSymbolV2*, QList<QgsFeature> > features;
1218
+
1219
+ // fetch features
1220
+ QgsFeature fet;
1221
+ QgsSymbolV2* featureSymbol = 0 ;
1222
+ while ( layer->nextFeature ( fet ) )
1223
+ {
1224
+ featureSymbol = renderer->symbolForFeature ( fet );
1225
+ if ( !featureSymbol )
1226
+ {
1227
+ continue ;
1228
+ }
1229
+
1230
+ QHash< QgsSymbolV2*, QList<QgsFeature> >::iterator it = features.find ( featureSymbol );
1231
+ if ( it == features.end () )
1232
+ {
1233
+ it = features.insert ( featureSymbol, QList<QgsFeature>() );
1234
+ }
1235
+ it.value ().append ( fet );
1236
+ }
1237
+
1238
+ // find out order
1239
+ QgsSymbolV2LevelOrder levels;
1240
+ QgsSymbolV2List symbols = renderer->symbols ();
1241
+ for ( int i = 0 ; i < symbols.count (); i++ )
1242
+ {
1243
+ QgsSymbolV2* sym = symbols[i];
1244
+ for ( int j = 0 ; j < sym->symbolLayerCount (); j++ )
1245
+ {
1246
+ int level = sym->symbolLayer ( j )->renderingPass ();
1247
+ if ( level < 0 || level >= 1000 ) // ignore invalid levels
1248
+ continue ;
1249
+ QgsSymbolV2LevelItem item ( sym, j );
1250
+ while ( level >= levels.count () ) // append new empty levels
1251
+ levels.append ( QgsSymbolV2Level () );
1252
+ levels[level].append ( item );
1253
+ }
1254
+ }
1255
+
1256
+ int nErrors = 0 ;
1257
+ int nTotalFeatures = 0 ;
1258
+
1259
+ // export symbol layers and symbology
1260
+ for ( int l = 0 ; l < levels.count (); l++ )
1261
+ {
1262
+ QgsSymbolV2Level& level = levels[l];
1263
+ for ( int i = 0 ; i < level.count (); i++ )
1264
+ {
1265
+ QgsSymbolV2LevelItem& item = level[i];
1266
+ QHash< QgsSymbolV2*, QList<QgsFeature> >::iterator levelIt = features.find ( item.symbol () );
1267
+ if ( levelIt == features.end () )
1268
+ {
1269
+ ++nErrors;
1270
+ continue ;
1271
+ }
1272
+
1273
+ int llayer = item.layer ();
1274
+ QList<QgsFeature>& featureList = levelIt.value ();
1275
+ QList<QgsFeature>::iterator featureIt = featureList.begin ();
1276
+ for ( ; featureIt != featureList.end (); ++featureIt )
1277
+ {
1278
+ ++nTotalFeatures;
1279
+ OGRFeatureH ogrFeature = createFeature ( *featureIt );
1280
+ if ( !ogrFeature )
1281
+ {
1282
+ ++nErrors;
1283
+ continue ;
1284
+ }
1285
+
1286
+ QString styleString = levelIt.key ()->symbolLayer ( llayer )->ogrFeatureStyle ();
1287
+ if ( !styleString.isEmpty () )
1288
+ {
1289
+ OGR_F_SetStyleString ( ogrFeature, styleString.toLocal8Bit ().data () );
1290
+ if ( ! writeFeature ( mLayer , ogrFeature ) )
1291
+ {
1292
+ ++nErrors;
1293
+ }
1294
+ }
1295
+ OGR_F_Destroy ( ogrFeature );
1296
+ }
1297
+ }
1298
+ }
1299
+
1300
+ if ( nErrors > 0 && errorMessage )
1301
+ {
1302
+ *errorMessage += QObject::tr ( " \n Only %1 of %2 features written." ).arg ( nTotalFeatures - nErrors ).arg ( nTotalFeatures );
1303
+ }
1304
+
1305
+ return ( nErrors > 0 ) ? QgsVectorFileWriter::ErrFeatureWriteFailed : QgsVectorFileWriter::NoError;
1306
+ }
0 commit comments