40
40
#include < ogr_api.h>
41
41
#include < ogr_srs_api.h>
42
42
#include < cpl_error.h>
43
+ #include < cpl_conv.h>
43
44
44
45
45
46
QgsVectorFileWriter::QgsVectorFileWriter (
@@ -48,7 +49,10 @@ QgsVectorFileWriter::QgsVectorFileWriter(
48
49
const QgsFieldMap& fields,
49
50
QGis::WkbType geometryType,
50
51
const QgsCoordinateReferenceSystem* srs,
51
- const QString& driverName )
52
+ const QString& driverName,
53
+ const QStringList &datasourceOptions,
54
+ const QStringList &layerOptions
55
+ )
52
56
: mDS( NULL )
53
57
, mLayer( NULL )
54
58
, mGeom( NULL )
@@ -116,8 +120,26 @@ QgsVectorFileWriter::QgsVectorFileWriter(
116
120
QFile::remove ( vectorFileName );
117
121
}
118
122
123
+ char **options = NULL ;
124
+ if ( !datasourceOptions.isEmpty () )
125
+ {
126
+ options = new char *[ datasourceOptions.size ()+1 ];
127
+ for ( int i = 0 ; i < datasourceOptions.size (); i++ )
128
+ {
129
+ options[i] = CPLStrdup ( datasourceOptions[i].toLocal8Bit ().data () );
130
+ }
131
+ options[ datasourceOptions.size ()] = NULL ;
132
+ }
133
+
119
134
// create the data source
120
- mDS = OGR_Dr_CreateDataSource ( poDriver, vectorFileName.toLocal8Bit ().data (), NULL );
135
+ mDS = OGR_Dr_CreateDataSource ( poDriver, vectorFileName.toLocal8Bit ().data (), options );
136
+
137
+ if ( options )
138
+ {
139
+ for ( int i = 0 ; i < datasourceOptions.size (); i++ )
140
+ CPLFree ( options[i] );
141
+ }
142
+
121
143
if ( mDS == NULL )
122
144
{
123
145
mError = ErrCreateDataSource;
@@ -155,7 +177,24 @@ QgsVectorFileWriter::QgsVectorFileWriter(
155
177
// datasource created, now create the output layer
156
178
QString layerName = QFileInfo ( vectorFileName ).baseName ();
157
179
OGRwkbGeometryType wkbType = static_cast <OGRwkbGeometryType>( geometryType );
158
- mLayer = OGR_DS_CreateLayer ( mDS , QFile::encodeName ( layerName ).data (), ogrRef, wkbType, NULL );
180
+
181
+ if ( !layerOptions.isEmpty () )
182
+ {
183
+ options = new char *[ layerOptions.size ()+1 ];
184
+ for ( int i = 0 ; i < layerOptions.size (); i++ )
185
+ {
186
+ options[i] = CPLStrdup ( layerOptions[i].toLocal8Bit ().data () );
187
+ }
188
+ options[ layerOptions.size ()] = NULL ;
189
+ }
190
+
191
+ mLayer = OGR_DS_CreateLayer ( mDS , QFile::encodeName ( layerName ).data (), ogrRef, wkbType, options );
192
+
193
+ if ( options )
194
+ {
195
+ for ( int i = 0 ; i < layerOptions.size (); i++ )
196
+ CPLFree ( options[i] );
197
+ }
159
198
160
199
if ( srs )
161
200
{
@@ -302,9 +341,6 @@ QString QgsVectorFileWriter::errorMessage()
302
341
303
342
bool QgsVectorFileWriter::addFeature ( QgsFeature& feature )
304
343
{
305
- if ( hasError () != NoError )
306
- return false ;
307
-
308
344
QgsAttributeMap::const_iterator it;
309
345
310
346
// create the feature
@@ -342,10 +378,13 @@ bool QgsVectorFileWriter::addFeature( QgsFeature& feature )
342
378
OGR_F_SetFieldString ( poFeature, ogrField, mCodec ->fromUnicode ( attrValue.toString () ).data () );
343
379
break ;
344
380
default :
345
- QgsDebugMsg ( " Invalid variant type for field " + QString ( fldIt.value ().name () ) + " "
346
- + QString::number ( ogrField ) + " : Received Type " + QMetaType::typeName ( attrValue.type () )
347
- + " : With Value : " + attrValue.toString ()
348
- );
381
+ mErrorMessage = QObject::tr ( " Invalid variant type for field %1[%2]: received %3 with type %4" )
382
+ .arg ( fldIt.value ().name () )
383
+ .arg ( ogrField )
384
+ .arg ( QMetaType::typeName ( attrValue.type () ) )
385
+ .arg ( attrValue.toString () );
386
+ QgsDebugMsg ( mErrorMessage );
387
+ mError = ErrFeatureWriteFailed;
349
388
return false ;
350
389
}
351
390
}
@@ -355,6 +394,8 @@ bool QgsVectorFileWriter::addFeature( QgsFeature& feature )
355
394
if ( !geom )
356
395
{
357
396
QgsDebugMsg ( " invalid geometry" );
397
+ mErrorMessage = QObject::tr ( " Invalid feature geometry" );
398
+ mError = ErrFeatureWriteFailed;
358
399
OGR_F_Destroy ( poFeature );
359
400
return false ;
360
401
}
@@ -375,7 +416,10 @@ bool QgsVectorFileWriter::addFeature( QgsFeature& feature )
375
416
OGRErr err = OGR_G_ImportFromWkb ( mGeom2 , geom->asWkb (), geom->wkbSize () );
376
417
if ( err != OGRERR_NONE )
377
418
{
378
- QgsDebugMsg ( " Failed to import geometry from WKB: " + QString::number ( err ) );
419
+ QgsDebugMsg ( QString ( " Failed to import geometry from WKB: %1 (OGR error: %2)" ).arg ( err ).arg ( CPLGetLastErrorMsg () ) );
420
+ mErrorMessage = QObject::tr ( " Feature geometry not imported (OGR error: %1)" )
421
+ .arg ( QString::fromUtf8 ( CPLGetLastErrorMsg () ) );
422
+ mError = ErrFeatureWriteFailed;
379
423
OGR_F_Destroy ( poFeature );
380
424
return false ;
381
425
}
@@ -388,7 +432,10 @@ bool QgsVectorFileWriter::addFeature( QgsFeature& feature )
388
432
OGRErr err = OGR_G_ImportFromWkb ( mGeom , geom->asWkb (), geom->wkbSize () );
389
433
if ( err != OGRERR_NONE )
390
434
{
391
- QgsDebugMsg ( " Failed to import geometry from WKB: " + QString::number ( err ) );
435
+ QgsDebugMsg ( QString ( " Failed to import geometry from WKB: %1 (OGR error: %2)" ).arg ( err ).arg ( CPLGetLastErrorMsg () ) );
436
+ mErrorMessage = QObject::tr ( " Feature geometry not imported (OGR error: %1)" )
437
+ .arg ( QString::fromUtf8 ( CPLGetLastErrorMsg () ) );
438
+ mError = ErrFeatureWriteFailed;
392
439
OGR_F_Destroy ( poFeature );
393
440
return false ;
394
441
}
@@ -400,7 +447,10 @@ bool QgsVectorFileWriter::addFeature( QgsFeature& feature )
400
447
// put the created feature to layer
401
448
if ( OGR_L_CreateFeature ( mLayer , poFeature ) != OGRERR_NONE )
402
449
{
403
- QgsDebugMsg ( " Failed to create feature in shapefile" );
450
+ mErrorMessage = QObject::tr ( " Feature creation error (OGR error: %1)" ).arg ( QString::fromUtf8 ( CPLGetLastErrorMsg () ) );
451
+ mError = ErrFeatureWriteFailed;
452
+
453
+ QgsDebugMsg ( mErrorMessage );
404
454
OGR_F_Destroy ( poFeature );
405
455
return false ;
406
456
}
@@ -432,9 +482,11 @@ QgsVectorFileWriter::writeAsShapefile( QgsVectorLayer* layer,
432
482
const QString& fileEncoding,
433
483
const QgsCoordinateReferenceSystem* destCRS,
434
484
bool onlySelected,
435
- QString *errorMessage )
485
+ QString *errorMessage,
486
+ const QStringList &datasourceOptions,
487
+ const QStringList &layerOptions )
436
488
{
437
- return writeAsVectorFormat ( layer, shapefileName, fileEncoding, destCRS, " ESRI Shapefile" , onlySelected, errorMessage );
489
+ return writeAsVectorFormat ( layer, shapefileName, fileEncoding, destCRS, " ESRI Shapefile" , onlySelected, errorMessage, datasourceOptions, layerOptions );
438
490
}
439
491
440
492
QgsVectorFileWriter::WriterError
@@ -444,7 +496,9 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
444
496
const QgsCoordinateReferenceSystem *destCRS,
445
497
const QString& driverName,
446
498
bool onlySelected,
447
- QString *errorMessage )
499
+ QString *errorMessage,
500
+ const QStringList &datasourceOptions,
501
+ const QStringList &layerOptions )
448
502
{
449
503
const QgsCoordinateReferenceSystem* outputCRS;
450
504
QgsCoordinateTransform* ct = 0 ;
@@ -462,7 +516,7 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
462
516
outputCRS = &layer->srs ();
463
517
}
464
518
QgsVectorFileWriter* writer =
465
- new QgsVectorFileWriter ( fileName, fileEncoding, layer->pendingFields (), layer->wkbType (), outputCRS, driverName );
519
+ new QgsVectorFileWriter ( fileName, fileEncoding, layer->pendingFields (), layer->wkbType (), outputCRS, driverName, datasourceOptions, layerOptions );
466
520
467
521
// check whether file creation was successful
468
522
WriterError err = writer->hasError ();
@@ -474,6 +528,11 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
474
528
return err;
475
529
}
476
530
531
+ if ( errorMessage )
532
+ {
533
+ errorMessage->clear ();
534
+ }
535
+
477
536
QgsAttributeList allAttr = layer->pendingAllAttributesList ();
478
537
QgsFeature fet;
479
538
@@ -493,6 +552,8 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
493
552
shallTransform = false ;
494
553
}
495
554
555
+ int n = 0 , errors = 0 ;
556
+
496
557
// write all features
497
558
while ( layer->nextFeature ( fet ) )
498
559
{
@@ -519,7 +580,31 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
519
580
return ErrProjection;
520
581
}
521
582
}
522
- writer->addFeature ( fet );
583
+ if ( !writer->addFeature ( fet ) )
584
+ {
585
+ WriterError err = writer->hasError ();
586
+ if ( err != NoError && errorMessage )
587
+ {
588
+ if ( errorMessage->isEmpty () )
589
+ {
590
+ *errorMessage = QObject::tr ( " Feature write errors:" );
591
+ }
592
+ *errorMessage += " \n " + writer->errorMessage ();
593
+ }
594
+ errors++;
595
+
596
+ if ( errors > 1000 )
597
+ {
598
+ if ( errorMessage )
599
+ {
600
+ *errorMessage += QObject::tr ( " Stopping after %1 errors" ).arg ( errors );
601
+ }
602
+
603
+ n = -1 ;
604
+ break ;
605
+ }
606
+ }
607
+ n++;
523
608
}
524
609
525
610
delete writer;
@@ -529,7 +614,12 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
529
614
delete ct;
530
615
}
531
616
532
- return NoError;
617
+ if ( errors > 0 && errorMessage && n > 0 )
618
+ {
619
+ *errorMessage += QObject::tr ( " \n Only %1 of %2 features written." ).arg ( n - errors ).arg ( n );
620
+ }
621
+
622
+ return errors == 0 ? NoError : ErrFeatureWriteFailed;
533
623
}
534
624
535
625
0 commit comments