Skip to content

Commit 64e02c8

Browse files
committed
Better error handling
1 parent 9120e02 commit 64e02c8

File tree

2 files changed

+180
-56
lines changed

2 files changed

+180
-56
lines changed

src/core/qgsvectorfilewriter.cpp

+175-55
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,64 @@ QString QgsVectorFileWriter::errorMessage()
438438
bool 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( "\nOnly %1 of %2 features written." ).arg( nTotalFeatures - nErrors ).arg( nTotalFeatures );
1303+
}
1304+
1305+
return ( nErrors > 0 ) ? QgsVectorFileWriter::ErrFeatureWriteFailed : QgsVectorFileWriter::NoError;
1306+
}

src/core/qgsvectorfilewriter.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,11 @@ class CORE_EXPORT QgsVectorFileWriter
190190
private:
191191
static bool driverMetadata( QString driverName, QString &longName, QString &trLongName, QString &glob, QString &ext );
192192
void createSymbolLayerTable( QgsVectorLayer* vl, OGRDataSourceH ds );
193-
bool createFeature( OGRLayerH layer, OGRFeatureH feature );
193+
OGRFeatureH createFeature( QgsFeature& feature );
194+
bool writeFeature( OGRLayerH layer, OGRFeatureH feature );
195+
196+
/**Writes features considering symbol level order*/
197+
WriterError exportFeaturesSymbolLevels( QgsVectorLayer* layer, const QgsCoordinateTransform* ct, QString* errorMessage = 0 );
194198
};
195199

196200
#endif

0 commit comments

Comments
 (0)