00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "qgsapplication.h"
00021 #include "qgsfield.h"
00022 #include "qgsfeature.h"
00023 #include "qgsgeometry.h"
00024 #include "qgslogger.h"
00025 #include "qgscoordinatereferencesystem.h"
00026 #include "qgsvectorfilewriter.h"
00027
00028 #include <QFile>
00029 #include <QSettings>
00030 #include <QFileInfo>
00031 #include <QDir>
00032 #include <QTextCodec>
00033 #include <QTextStream>
00034 #include <QSet>
00035 #include <QMetaType>
00036
00037 #include <cassert>
00038 #include <cstdlib>
00039
00040 #include <ogr_api.h>
00041 #include <ogr_srs_api.h>
00042 #include <cpl_error.h>
00043 #include <cpl_conv.h>
00044
00045
00046 QgsVectorFileWriter::QgsVectorFileWriter(
00047 const QString &theVectorFileName,
00048 const QString &theFileEncoding,
00049 const QgsFieldMap& fields,
00050 QGis::WkbType geometryType,
00051 const QgsCoordinateReferenceSystem* srs,
00052 const QString& driverName,
00053 const QStringList &datasourceOptions,
00054 const QStringList &layerOptions
00055 )
00056 : mDS( NULL )
00057 , mLayer( NULL )
00058 , mGeom( NULL )
00059 , mError( NoError )
00060 {
00061 QString vectorFileName = theVectorFileName;
00062 QString fileEncoding = theFileEncoding;
00063
00064
00065 OGRSFDriverH poDriver;
00066 QgsApplication::registerOgrDrivers();
00067 poDriver = OGRGetDriverByName( driverName.toLocal8Bit().data() );
00068
00069 if ( poDriver == NULL )
00070 {
00071 mErrorMessage = QObject::tr( "OGR driver for '%1' not found (OGR error: %2)" )
00072 .arg( driverName )
00073 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
00074 mError = ErrDriverNotFound;
00075 return;
00076 }
00077
00078 if ( driverName == "ESRI Shapefile" )
00079 {
00080 if ( !vectorFileName.endsWith( ".shp", Qt::CaseInsensitive ) )
00081 {
00082 vectorFileName += ".shp";
00083 }
00084
00085
00086 QSet<QString> fieldNames;
00087 QgsFieldMap::const_iterator fldIt;
00088 for ( fldIt = fields.begin(); fldIt != fields.end(); ++fldIt )
00089 {
00090 QString name = fldIt.value().name().left( 10 );
00091 if ( fieldNames.contains( name ) )
00092 {
00093 mErrorMessage = QObject::tr( "trimming attribute name '%1' to ten significant characters produces duplicate column name." )
00094 .arg( fldIt.value().name() );
00095 mError = ErrAttributeCreationFailed;
00096 return;
00097 }
00098 fieldNames << name;
00099 }
00100
00101 deleteShapeFile( vectorFileName );
00102 }
00103 else if ( driverName == "KML" )
00104 {
00105 if ( !vectorFileName.endsWith( ".kml", Qt::CaseInsensitive ) )
00106 {
00107 vectorFileName += ".kml";
00108 }
00109
00110 if ( fileEncoding.compare( "UTF-8", Qt::CaseInsensitive ) != 0 )
00111 {
00112 QgsDebugMsg( "forced UTF-8 encoding for KML" );
00113 fileEncoding = "UTF-8";
00114 }
00115
00116 QFile::remove( vectorFileName );
00117 }
00118 else
00119 {
00120 QFile::remove( vectorFileName );
00121 }
00122
00123 char **options = NULL;
00124 if ( !datasourceOptions.isEmpty() )
00125 {
00126 options = new char *[ datasourceOptions.size()+1 ];
00127 for ( int i = 0; i < datasourceOptions.size(); i++ )
00128 {
00129 options[i] = CPLStrdup( datasourceOptions[i].toLocal8Bit().data() );
00130 }
00131 options[ datasourceOptions.size()] = NULL;
00132 }
00133
00134
00135 mDS = OGR_Dr_CreateDataSource( poDriver, vectorFileName.toLocal8Bit().data(), options );
00136
00137 if ( options )
00138 {
00139 for ( int i = 0; i < datasourceOptions.size(); i++ )
00140 CPLFree( options[i] );
00141 delete [] options;
00142 options = NULL;
00143 }
00144
00145 if ( mDS == NULL )
00146 {
00147 mError = ErrCreateDataSource;
00148 mErrorMessage = QObject::tr( "creation of data source failed (OGR error:%1)" )
00149 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
00150 return;
00151 }
00152
00153 QgsDebugMsg( "Created data source" );
00154
00155
00156 mCodec = QTextCodec::codecForName( fileEncoding.toLocal8Bit().data() );
00157 if ( !mCodec )
00158 {
00159 QSettings settings;
00160 QString enc = settings.value( "/UI/encoding", QString( "System" ) ).toString();
00161 QgsDebugMsg( "error finding QTextCodec for " + fileEncoding );
00162 mCodec = QTextCodec::codecForName( enc.toLocal8Bit().data() );
00163 if ( !mCodec )
00164 {
00165 QgsDebugMsg( "error finding QTextCodec for " + enc );
00166 mCodec = QTextCodec::codecForLocale();
00167 }
00168 }
00169
00170
00171 OGRSpatialReferenceH ogrRef = NULL;
00172 if ( srs )
00173 {
00174 QString srsWkt = srs->toWkt();
00175 QgsDebugMsg( "WKT to save as is " + srsWkt );
00176 ogrRef = OSRNewSpatialReference( srsWkt.toLocal8Bit().data() );
00177 }
00178
00179
00180 QString layerName = QFileInfo( vectorFileName ).baseName();
00181 OGRwkbGeometryType wkbType = static_cast<OGRwkbGeometryType>( geometryType );
00182
00183 if ( !layerOptions.isEmpty() )
00184 {
00185 options = new char *[ layerOptions.size()+1 ];
00186 for ( int i = 0; i < layerOptions.size(); i++ )
00187 {
00188 options[i] = CPLStrdup( layerOptions[i].toLocal8Bit().data() );
00189 }
00190 options[ layerOptions.size()] = NULL;
00191 }
00192
00193 mLayer = OGR_DS_CreateLayer( mDS, QFile::encodeName( layerName ).data(), ogrRef, wkbType, options );
00194
00195 if ( options )
00196 {
00197 for ( int i = 0; i < layerOptions.size(); i++ )
00198 CPLFree( options[i] );
00199 delete [] options;
00200 options = NULL;
00201 }
00202
00203 if ( srs )
00204 {
00205 if ( driverName == "ESRI Shapefile" )
00206 {
00207 QString layerName = vectorFileName.left( vectorFileName.indexOf( ".shp", Qt::CaseInsensitive ) );
00208 QFile prjFile( layerName + ".qpj" );
00209 if ( prjFile.open( QIODevice::WriteOnly ) )
00210 {
00211 QTextStream prjStream( &prjFile );
00212 prjStream << srs->toWkt().toLocal8Bit().data() << endl;
00213 prjFile.close();
00214 }
00215 else
00216 {
00217 QgsDebugMsg( "Couldn't open file " + layerName + ".qpj" );
00218 }
00219 }
00220
00221 OSRDestroySpatialReference( ogrRef );
00222 }
00223
00224 if ( mLayer == NULL )
00225 {
00226 mErrorMessage = QObject::tr( "creation of layer failed (OGR error:%1)" )
00227 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
00228 mError = ErrCreateLayer;
00229 return;
00230 }
00231
00232 OGRFeatureDefnH defn = OGR_L_GetLayerDefn( mLayer );
00233
00234 QgsDebugMsg( "created layer" );
00235
00236
00237 QgsDebugMsg( "creating " + QString::number( fields.size() ) + " fields" );
00238
00239 mFields = fields;
00240 mAttrIdxToOgrIdx.clear();
00241
00242 QgsFieldMap::const_iterator fldIt;
00243 for ( fldIt = fields.begin(); fldIt != fields.end(); ++fldIt )
00244 {
00245 const QgsField& attrField = fldIt.value();
00246
00247 OGRFieldType ogrType = OFTString;
00248 int ogrWidth = fldIt->length();
00249 int ogrPrecision = fldIt->precision();
00250 switch ( attrField.type() )
00251 {
00252 case QVariant::LongLong:
00253 ogrType = OFTString;
00254 ogrWidth = ogrWidth > 0 && ogrWidth <= 21 ? ogrWidth : 21;
00255 ogrPrecision = -1;
00256 break;
00257
00258 case QVariant::String:
00259 ogrType = OFTString;
00260 if ( ogrWidth < 0 || ogrWidth > 255 )
00261 ogrWidth = 255;
00262 break;
00263
00264 case QVariant::Int:
00265 ogrType = OFTInteger;
00266 ogrWidth = ogrWidth > 0 && ogrWidth <= 10 ? ogrWidth : 10;
00267 ogrPrecision = 0;
00268 break;
00269
00270 case QVariant::Double:
00271 ogrType = OFTReal;
00272 break;
00273
00274 default:
00275
00276 mErrorMessage = QObject::tr( "unsupported type for field %1" )
00277 .arg( attrField.name() );
00278 mError = ErrAttributeTypeUnsupported;
00279 return;
00280 }
00281
00282
00283 OGRFieldDefnH fld = OGR_Fld_Create( mCodec->fromUnicode( attrField.name() ), ogrType );
00284 if ( ogrWidth > 0 )
00285 {
00286 OGR_Fld_SetWidth( fld, ogrWidth );
00287 }
00288
00289 if ( ogrPrecision >= 0 )
00290 {
00291 OGR_Fld_SetPrecision( fld, ogrPrecision );
00292 }
00293
00294
00295 QgsDebugMsg( "creating field " + attrField.name() +
00296 " type " + QString( QVariant::typeToName( attrField.type() ) ) +
00297 " width " + QString::number( ogrWidth ) +
00298 " precision " + QString::number( ogrPrecision ) );
00299 if ( OGR_L_CreateField( mLayer, fld, true ) != OGRERR_NONE )
00300 {
00301 QgsDebugMsg( "error creating field " + attrField.name() );
00302 mErrorMessage = QObject::tr( "creation of field %1 failed (OGR error: %2)" )
00303 .arg( attrField.name() )
00304 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
00305 mError = ErrAttributeCreationFailed;
00306 return;
00307 }
00308
00309 int ogrIdx = OGR_FD_GetFieldIndex( defn, mCodec->fromUnicode( attrField.name() ) );
00310 if ( ogrIdx < 0 )
00311 {
00312
00313
00314 int fieldCount = OGR_FD_GetFieldCount( defn );
00315
00316 OGRFieldDefnH fdefn = OGR_FD_GetFieldDefn( defn, fieldCount - 1 );
00317 if ( fdefn )
00318 {
00319 const char *fieldName = OGR_Fld_GetNameRef( fdefn );
00320
00321 if ( attrField.name().left( strlen( fieldName ) ) == fieldName )
00322 {
00323 ogrIdx = fieldCount - 1;
00324 }
00325 }
00326
00327 if ( ogrIdx < 0 )
00328 {
00329 QgsDebugMsg( "error creating field " + attrField.name() );
00330 mErrorMessage = QObject::tr( "created field %1 not found (OGR error: %2)" )
00331 .arg( attrField.name() )
00332 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
00333 mError = ErrAttributeCreationFailed;
00334 return;
00335 }
00336 }
00337
00338 mAttrIdxToOgrIdx.insert( fldIt.key(), ogrIdx );
00339 }
00340
00341 QgsDebugMsg( "Done creating fields" );
00342
00343 mWkbType = geometryType;
00344
00345 mGeom = createEmptyGeometry( mWkbType );
00346 }
00347
00348 OGRGeometryH QgsVectorFileWriter::createEmptyGeometry( QGis::WkbType wkbType )
00349 {
00350 return OGR_G_CreateGeometry(( OGRwkbGeometryType ) wkbType );
00351 }
00352
00353
00354 QgsVectorFileWriter::WriterError QgsVectorFileWriter::hasError()
00355 {
00356 return mError;
00357 }
00358
00359 QString QgsVectorFileWriter::errorMessage()
00360 {
00361 return mErrorMessage;
00362 }
00363
00364 bool QgsVectorFileWriter::addFeature( QgsFeature& feature )
00365 {
00366 QgsAttributeMap::const_iterator it;
00367
00368
00369 OGRFeatureH poFeature = OGR_F_Create( OGR_L_GetLayerDefn( mLayer ) );
00370
00371
00372 QgsFieldMap::const_iterator fldIt;
00373 for ( fldIt = mFields.begin(); fldIt != mFields.end(); ++fldIt )
00374 {
00375 if ( !feature.attributeMap().contains( fldIt.key() ) )
00376 {
00377 QgsDebugMsg( QString( "no attribute for field %1" ).arg( fldIt.key() ) );
00378 continue;
00379 }
00380
00381 if ( !mAttrIdxToOgrIdx.contains( fldIt.key() ) )
00382 {
00383 QgsDebugMsg( QString( "no ogr field for field %1" ).arg( fldIt.key() ) );
00384 continue;
00385 }
00386
00387 const QVariant& attrValue = feature.attributeMap()[ fldIt.key()];
00388 int ogrField = mAttrIdxToOgrIdx[ fldIt.key()];
00389
00390 switch ( attrValue.type() )
00391 {
00392 case QVariant::Int:
00393 OGR_F_SetFieldInteger( poFeature, ogrField, attrValue.toInt() );
00394 break;
00395 case QVariant::Double:
00396 OGR_F_SetFieldDouble( poFeature, ogrField, attrValue.toDouble() );
00397 break;
00398 case QVariant::LongLong:
00399 case QVariant::String:
00400 OGR_F_SetFieldString( poFeature, ogrField, mCodec->fromUnicode( attrValue.toString() ).data() );
00401 break;
00402 default:
00403 mErrorMessage = QObject::tr( "Invalid variant type for field %1[%2]: received %3 with type %4" )
00404 .arg( fldIt.value().name() )
00405 .arg( ogrField )
00406 .arg( QMetaType::typeName( attrValue.type() ) )
00407 .arg( attrValue.toString() );
00408 QgsDebugMsg( mErrorMessage );
00409 mError = ErrFeatureWriteFailed;
00410 return false;
00411 }
00412 }
00413
00414
00415 QgsGeometry *geom = feature.geometry();
00416 if ( !geom )
00417 {
00418 QgsDebugMsg( "invalid geometry" );
00419 mErrorMessage = QObject::tr( "Invalid feature geometry" );
00420 mError = ErrFeatureWriteFailed;
00421 OGR_F_Destroy( poFeature );
00422 return false;
00423 }
00424
00425 if ( geom->wkbType() != mWkbType )
00426 {
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 OGRGeometryH mGeom2 = createEmptyGeometry( geom->wkbType() );
00437
00438 if ( !mGeom2 )
00439 {
00440 QgsDebugMsg( QString( "Failed to create empty geometry for type %1 (OGR error: %2)" ).arg( geom->wkbType() ).arg( CPLGetLastErrorMsg() ) );
00441 mErrorMessage = QObject::tr( "Feature geometry not imported (OGR error: %1)" )
00442 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
00443 mError = ErrFeatureWriteFailed;
00444 OGR_F_Destroy( poFeature );
00445 return false;
00446 }
00447
00448 OGRErr err = OGR_G_ImportFromWkb( mGeom2, geom->asWkb(), geom->wkbSize() );
00449 if ( err != OGRERR_NONE )
00450 {
00451 QgsDebugMsg( QString( "Failed to import geometry from WKB: %1 (OGR error: %2)" ).arg( err ).arg( CPLGetLastErrorMsg() ) );
00452 mErrorMessage = QObject::tr( "Feature geometry not imported (OGR error: %1)" )
00453 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
00454 mError = ErrFeatureWriteFailed;
00455 OGR_F_Destroy( poFeature );
00456 return false;
00457 }
00458
00459
00460 OGR_F_SetGeometryDirectly( poFeature, mGeom2 );
00461 }
00462 else
00463 {
00464 OGRErr err = OGR_G_ImportFromWkb( mGeom, geom->asWkb(), geom->wkbSize() );
00465 if ( err != OGRERR_NONE )
00466 {
00467 QgsDebugMsg( QString( "Failed to import geometry from WKB: %1 (OGR error: %2)" ).arg( err ).arg( CPLGetLastErrorMsg() ) );
00468 mErrorMessage = QObject::tr( "Feature geometry not imported (OGR error: %1)" )
00469 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
00470 mError = ErrFeatureWriteFailed;
00471 OGR_F_Destroy( poFeature );
00472 return false;
00473 }
00474
00475
00476 OGR_F_SetGeometry( poFeature, mGeom );
00477 }
00478
00479
00480 if ( OGR_L_CreateFeature( mLayer, poFeature ) != OGRERR_NONE )
00481 {
00482 mErrorMessage = QObject::tr( "Feature creation error (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
00483 mError = ErrFeatureWriteFailed;
00484
00485 QgsDebugMsg( mErrorMessage );
00486 OGR_F_Destroy( poFeature );
00487 return false;
00488 }
00489
00490 OGR_F_Destroy( poFeature );
00491
00492 return true;
00493 }
00494
00495 QgsVectorFileWriter::~QgsVectorFileWriter()
00496 {
00497 if ( mGeom )
00498 {
00499 OGR_G_DestroyGeometry( mGeom );
00500 }
00501
00502 if ( mDS )
00503 {
00504 OGR_DS_Destroy( mDS );
00505 }
00506 }
00507
00508
00509
00510
00511 QgsVectorFileWriter::WriterError
00512 QgsVectorFileWriter::writeAsShapefile( QgsVectorLayer* layer,
00513 const QString& shapefileName,
00514 const QString& fileEncoding,
00515 const QgsCoordinateReferenceSystem* destCRS,
00516 bool onlySelected,
00517 QString *errorMessage,
00518 const QStringList &datasourceOptions,
00519 const QStringList &layerOptions )
00520 {
00521 return writeAsVectorFormat( layer, shapefileName, fileEncoding, destCRS, "ESRI Shapefile", onlySelected, errorMessage, datasourceOptions, layerOptions );
00522 }
00523
00524 QgsVectorFileWriter::WriterError
00525 QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
00526 const QString& fileName,
00527 const QString& fileEncoding,
00528 const QgsCoordinateReferenceSystem *destCRS,
00529 const QString& driverName,
00530 bool onlySelected,
00531 QString *errorMessage,
00532 const QStringList &datasourceOptions,
00533 const QStringList &layerOptions )
00534 {
00535 const QgsCoordinateReferenceSystem* outputCRS;
00536 QgsCoordinateTransform* ct = 0;
00537 int shallTransform = false;
00538
00539 if ( destCRS && destCRS->isValid() )
00540 {
00541
00542 outputCRS = destCRS;
00543 shallTransform = true;
00544 }
00545 else
00546 {
00547
00548 outputCRS = &layer->srs();
00549 }
00550 QgsVectorFileWriter* writer =
00551 new QgsVectorFileWriter( fileName, fileEncoding, layer->pendingFields(), layer->wkbType(), outputCRS, driverName, datasourceOptions, layerOptions );
00552
00553
00554 WriterError err = writer->hasError();
00555 if ( err != NoError )
00556 {
00557 if ( errorMessage )
00558 *errorMessage = writer->errorMessage();
00559 delete writer;
00560 return err;
00561 }
00562
00563 if ( errorMessage )
00564 {
00565 errorMessage->clear();
00566 }
00567
00568 QgsAttributeList allAttr = layer->pendingAllAttributesList();
00569 QgsFeature fet;
00570
00571 layer->select( allAttr, QgsRectangle(), true );
00572
00573 const QgsFeatureIds& ids = layer->selectedFeaturesIds();
00574
00575
00576 if ( destCRS )
00577 {
00578 ct = new QgsCoordinateTransform( layer->srs(), *destCRS );
00579 }
00580
00581
00582 if ( ct == NULL )
00583 {
00584 shallTransform = false;
00585 }
00586
00587 int n = 0, errors = 0;
00588
00589
00590 while ( layer->nextFeature( fet ) )
00591 {
00592 if ( onlySelected && !ids.contains( fet.id() ) )
00593 continue;
00594
00595 if ( shallTransform )
00596 {
00597 try
00598 {
00599 if ( fet.geometry() )
00600 {
00601 fet.geometry()->transform( *ct );
00602 }
00603 }
00604 catch ( QgsCsException &e )
00605 {
00606 delete ct;
00607 delete writer;
00608
00609 QString msg = QObject::tr( "Failed to transform a point while drawing a feature of type '%1'. Writing stopped. (Exception: %2)" )
00610 .arg( fet.typeName() ).arg( e.what() );
00611 QgsLogger::warning( msg );
00612 if ( errorMessage )
00613 *errorMessage = msg;
00614
00615 return ErrProjection;
00616 }
00617 }
00618 if ( !writer->addFeature( fet ) )
00619 {
00620 WriterError err = writer->hasError();
00621 if ( err != NoError && errorMessage )
00622 {
00623 if ( errorMessage->isEmpty() )
00624 {
00625 *errorMessage = QObject::tr( "Feature write errors:" );
00626 }
00627 *errorMessage += "\n" + writer->errorMessage();
00628 }
00629 errors++;
00630
00631 if ( errors > 1000 )
00632 {
00633 if ( errorMessage )
00634 {
00635 *errorMessage += QObject::tr( "Stopping after %1 errors" ).arg( errors );
00636 }
00637
00638 n = -1;
00639 break;
00640 }
00641 }
00642 n++;
00643 }
00644
00645 delete writer;
00646
00647 if ( shallTransform )
00648 {
00649 delete ct;
00650 }
00651
00652 if ( errors > 0 && errorMessage && n > 0 )
00653 {
00654 *errorMessage += QObject::tr( "\nOnly %1 of %2 features written." ).arg( n - errors ).arg( n );
00655 }
00656
00657 return errors == 0 ? NoError : ErrFeatureWriteFailed;
00658 }
00659
00660
00661 bool QgsVectorFileWriter::deleteShapeFile( QString theFileName )
00662 {
00663 QFileInfo fi( theFileName );
00664 QDir dir = fi.dir();
00665
00666 QStringList filter;
00667 const char *suffixes[] = { ".shp", ".shx", ".dbf", ".prj", ".qix", ".qpj" };
00668 for ( std::size_t i = 0; i < sizeof( suffixes ) / sizeof( *suffixes ); i++ )
00669 {
00670 filter << fi.completeBaseName() + suffixes[i];
00671 }
00672
00673 bool ok = true;
00674 foreach( QString file, dir.entryList( filter ) )
00675 {
00676 if ( !QFile::remove( dir.canonicalPath() + "/" + file ) )
00677 {
00678 QgsDebugMsg( "Removing file failed : " + file );
00679 ok = false;
00680 }
00681 }
00682
00683 return ok;
00684 }
00685
00686 QMap< QString, QString> QgsVectorFileWriter::supportedFiltersAndFormats()
00687 {
00688 QMap<QString, QString> resultMap;
00689
00690 QgsApplication::registerOgrDrivers();
00691 int const drvCount = OGRGetDriverCount();
00692
00693 for ( int i = 0; i < drvCount; ++i )
00694 {
00695 OGRSFDriverH drv = OGRGetDriver( i );
00696 if ( drv )
00697 {
00698 QString drvName = OGR_Dr_GetName( drv );
00699 if ( OGR_Dr_TestCapability( drv, "CreateDataSource" ) != 0 )
00700 {
00701 QString filterString = filterForDriver( drvName );
00702 if ( filterString.isEmpty() )
00703 continue;
00704
00705 resultMap.insert( filterString, drvName );
00706 }
00707 }
00708 }
00709
00710 return resultMap;
00711 }
00712
00713 QMap<QString, QString> QgsVectorFileWriter::ogrDriverList()
00714 {
00715 QMap<QString, QString> resultMap;
00716
00717 QgsApplication::registerOgrDrivers();
00718 int const drvCount = OGRGetDriverCount();
00719
00720 for ( int i = 0; i < drvCount; ++i )
00721 {
00722 OGRSFDriverH drv = OGRGetDriver( i );
00723 if ( drv )
00724 {
00725 QString drvName = OGR_Dr_GetName( drv );
00726 if ( OGR_Dr_TestCapability( drv, "CreateDataSource" ) != 0 )
00727 {
00728 QPair<QString, QString> p = nameAndGlob( drvName );
00729 if ( p.first.isEmpty() )
00730 continue;
00731
00732 resultMap.insert( p.first, drvName );
00733 }
00734 }
00735 }
00736
00737 return resultMap;
00738 }
00739
00740 QString QgsVectorFileWriter::fileFilterString()
00741 {
00742 QString filterString;
00743 QMap< QString, QString> driverFormatMap = supportedFiltersAndFormats();
00744 QMap< QString, QString>::const_iterator it = driverFormatMap.constBegin();
00745 for ( ; it != driverFormatMap.constEnd(); ++it )
00746 {
00747 if ( filterString.isEmpty() )
00748 filterString += ";;";
00749
00750 filterString += it.key();
00751 }
00752 return filterString;
00753 }
00754
00755 QString QgsVectorFileWriter::filterForDriver( const QString& driverName )
00756 {
00757 QPair<QString, QString> p = nameAndGlob( driverName );
00758
00759 if ( p.first.isEmpty() || p.second.isEmpty() )
00760 return "";
00761
00762 return "[OGR] " + p.first + " (" + p.second.toLower() + " " + p.second.toUpper() + ")";
00763 }
00764
00765 QPair<QString, QString> QgsVectorFileWriter::nameAndGlob( QString driverName )
00766 {
00767 QString longName;
00768 QString glob;
00769
00770 if ( driverName.startsWith( "AVCE00" ) )
00771 {
00772 longName = "Arc/Info ASCII Coverage";
00773 glob = "*.e00";
00774 }
00775 else if ( driverName.startsWith( "BNA" ) )
00776 {
00777 longName = "Atlas BNA";
00778 glob = "*.bna";
00779 }
00780 else if ( driverName.startsWith( "CSV" ) )
00781 {
00782 longName = "Comma Separated Value";
00783 glob = "*.csv";
00784 }
00785 else if ( driverName.startsWith( "ESRI" ) )
00786 {
00787 longName = "ESRI Shapefile";
00788 glob = "*.shp";
00789 }
00790 else if ( driverName.startsWith( "FMEObjects Gateway" ) )
00791 {
00792 longName = "FMEObjects Gateway";
00793 glob = "*.fdd";
00794 }
00795 else if ( driverName.startsWith( "GeoJSON" ) )
00796 {
00797 longName = "GeoJSON";
00798 glob = "*.geojson";
00799 }
00800 else if ( driverName.startsWith( "GeoRSS" ) )
00801 {
00802 longName = "GeoRSS";
00803 glob = "*.xml";
00804 }
00805 else if ( driverName.startsWith( "GML" ) )
00806 {
00807 longName = "Geography Markup Language (GML)";
00808 glob = "*.gml";
00809 }
00810 else if ( driverName.startsWith( "GMT" ) )
00811 {
00812 longName = "Generic Mapping Tools (GMT)";
00813 glob = "*.gmt";
00814 }
00815 else if ( driverName.startsWith( "GPX" ) )
00816 {
00817 longName = "GPS eXchange Format";
00818 glob = "*.gpx";
00819 }
00820 else if ( driverName.startsWith( "Interlis 1" ) )
00821 {
00822 longName = "INTERLIS 1";
00823 glob = "*.itf *.xml *.ili";
00824 }
00825 else if ( driverName.startsWith( "Interlis 2" ) )
00826 {
00827 longName = "INTERLIS 2";
00828 glob = "*.itf *.xml *.ili";
00829 }
00830 else if ( driverName.startsWith( "KML" ) )
00831 {
00832 longName = "Keyhole Markup Language (KML)";
00833 glob = "*.kml" ;
00834 }
00835 else if ( driverName.startsWith( "MapInfo File" ) )
00836 {
00837 longName = "Mapinfo File";
00838 glob = "*.mif *.tab";
00839 }
00840 else if ( driverName.startsWith( "DGN" ) )
00841 {
00842 longName = "Microstation DGN";
00843 glob = "*.dgn";
00844 }
00845 else if ( driverName.startsWith( "S57" ) )
00846 {
00847 longName = "S-57 Base file";
00848 glob = "*.000";
00849 }
00850 else if ( driverName.startsWith( "SDTS" ) )
00851 {
00852 longName = "Spatial Data Transfer Standard (SDTS)";
00853 glob = "*catd.ddf";
00854 }
00855 else if ( driverName.startsWith( "SQLite" ) )
00856 {
00857 longName = "SQLite";
00858 glob = "*.sqlite";
00859 }
00860 else if ( driverName.startsWith( "DXF" ) )
00861 {
00862 longName = "AutoCAD DXF";
00863 glob = "*.dxf";
00864 }
00865 else if ( driverName.startsWith( "Geoconcept" ) )
00866 {
00867 longName = "Geoconcept";
00868 glob = "*.gxt *.txt";
00869 }
00870
00871 return QPair<QString, QString>( longName, glob );
00872 }