@@ -438,6 +438,64 @@ QString QgsVectorFileWriter::errorMessage()
438438bool QgsVectorFileWriter::addFeature ( QgsFeature& feature, QgsFeatureRendererV2* renderer )
439439{
440440 // 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+ {
441499 OGRFeatureH poFeature = OGR_F_Create ( OGR_L_GetLayerDefn ( mLayer ) );
442500
443501 qint64 fid = FID_TO_NUMBER ( feature.id () );
@@ -568,62 +626,10 @@ bool QgsVectorFileWriter::addFeature( QgsFeature& feature, QgsFeatureRendererV2*
568626 OGR_F_SetGeometry ( poFeature, mGeom );
569627 }
570628 }
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;
624630}
625631
626- bool QgsVectorFileWriter::createFeature ( OGRLayerH layer, OGRFeatureH feature )
632+ bool QgsVectorFileWriter::writeFeature ( OGRLayerH layer, OGRFeatureH feature )
627633{
628634 if ( OGR_L_CreateFeature ( layer, feature ) != OGRERR_NONE )
629635 {
@@ -743,12 +749,24 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
743749 shallTransform = false ;
744750 }
745751
746- // create symbol table if neede
752+ // create symbol table if needed
747753 /* if( writer->symbologyExport() != NoSymbology )
748754 {
749755 writer->createSymbolLayerTable( layer, writer->mDS );
750756 }*/
751757
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+
752770 int n = 0 , errors = 0 ;
753771
754772 // write all features
@@ -1184,3 +1202,105 @@ void QgsVectorFileWriter::createSymbolLayerTable( QgsVectorLayer* vl, OGRDataSo
11841202 }
11851203 OGR_DS_SetStyleTableDirectly ( ds, ogrStyleTable );
11861204}
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