Skip to content

Commit

Permalink
vector save as: separated MITAB and MIF formats, fixes #6233; added t…
Browse files Browse the repository at this point in the history
…est if OGR SpatiaLite is available
  • Loading branch information
blazek committed Nov 7, 2012
1 parent a07c4da commit fce38c5
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 29 deletions.
4 changes: 0 additions & 4 deletions src/app/ogr/qgsvectorlayersaveasdialog.cpp
Expand Up @@ -38,10 +38,6 @@ QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( long srsid, QWidget* par
for ( QMap< QString, QString>::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
{
mFormatComboBox->addItem( it.key(), it.value() );
if ( it.key() == "SQLite" )
{
mFormatComboBox->addItem( "SpatiaLite", tr( "SpatiaLite" ) );
}
}

QString format = settings.value( "/UI/lastVectorFormat", "ESRI Shapefile" ).toString();
Expand Down
7 changes: 0 additions & 7 deletions src/app/qgisapp.cpp
Expand Up @@ -4166,13 +4166,6 @@ void QgisApp::saveAsVectorFileGeneral( bool saveOnlySelection )
QString format = dialog->format();
QStringList datasourceOptions = dialog->datasourceOptions();

if ( format == "SpatiaLite" )
{
if ( !datasourceOptions.contains( "SPATIALITE=YES" ) )
datasourceOptions.append( "SPATIALITE=YES" );
format = "SQLite";
}

switch ( dialog->crs() )
{
case -2: // Project CRS
Expand Down
110 changes: 93 additions & 17 deletions src/core/qgsvectorfilewriter.cpp
Expand Up @@ -71,10 +71,30 @@ QgsVectorFileWriter::QgsVectorFileWriter(
QString vectorFileName = theVectorFileName;
QString fileEncoding = theFileEncoding;

QStringList dsOptions = datasourceOptions;

QString ogrDriverName;
if ( driverName == "MapInfo MIF" )
{
ogrDriverName = "MapInfo File";
}
else if ( driverName == "SpatiaLite" )
{
ogrDriverName = "SQLite";
if ( !dsOptions.contains( "SPATIALITE=YES" ) )
{
dsOptions.append( "SPATIALITE=YES" );
}
}
else
{
ogrDriverName = driverName;
}

// find driver in OGR
OGRSFDriverH poDriver;
QgsApplication::registerOgrDrivers();
poDriver = OGRGetDriverByName( driverName.toLocal8Bit().data() );
poDriver = OGRGetDriverByName( ogrDriverName.toLocal8Bit().data() );

if ( poDriver == NULL )
{
Expand Down Expand Up @@ -157,22 +177,22 @@ QgsVectorFileWriter::QgsVectorFileWriter(
}

char **options = NULL;
if ( !datasourceOptions.isEmpty() )
if ( !dsOptions.isEmpty() )
{
options = new char *[ datasourceOptions.size()+1 ];
for ( int i = 0; i < datasourceOptions.size(); i++ )
options = new char *[ dsOptions.size()+1 ];
for ( int i = 0; i < dsOptions.size(); i++ )
{
options[i] = CPLStrdup( datasourceOptions[i].toLocal8Bit().data() );
options[i] = CPLStrdup( dsOptions[i].toLocal8Bit().data() );
}
options[ datasourceOptions.size()] = NULL;
options[ dsOptions.size()] = NULL;
}

// create the data source
mDS = OGR_Dr_CreateDataSource( poDriver, TO8( vectorFileName ), options );

if ( options )
{
for ( int i = 0; i < datasourceOptions.size(); i++ )
for ( int i = 0; i < dsOptions.size(); i++ )
CPLFree( options[i] );
delete [] options;
options = NULL;
Expand Down Expand Up @@ -603,6 +623,7 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
bool skipAttributeCreation,
QString *newFilename )
{
QgsDebugMsg( "fileName = " + fileName );
const QgsCoordinateReferenceSystem* outputCRS;
QgsCoordinateTransform* ct = 0;
int shallTransform = false;
Expand All @@ -626,6 +647,8 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
QgsVectorFileWriter* writer =
new QgsVectorFileWriter( fileName, fileEncoding, skipAttributeCreation ? QgsFieldMap() : layer->pendingFields(), layer->wkbType(), outputCRS, driverName, datasourceOptions, layerOptions, newFilename );

QgsDebugMsg( "newFilename = " + *newFilename );

// check whether file creation was successful
WriterError err = writer->hasError();
if ( err != NoError )
Expand Down Expand Up @@ -797,6 +820,7 @@ QMap<QString, QString> QgsVectorFileWriter::ogrDriverList()
QgsApplication::registerOgrDrivers();
int const drvCount = OGRGetDriverCount();

QStringList writableDrivers;
for ( int i = 0; i < drvCount; ++i )
{
OGRSFDriverH drv = OGRGetDriver( i );
Expand All @@ -805,18 +829,54 @@ QMap<QString, QString> QgsVectorFileWriter::ogrDriverList()
QString drvName = OGR_Dr_GetName( drv );
if ( OGR_Dr_TestCapability( drv, "CreateDataSource" ) != 0 )
{
QString longName;
QString trLongName;
QString glob;
QString exts;
if ( QgsVectorFileWriter::driverMetadata( drvName, longName, trLongName, glob, exts ) && !trLongName.isEmpty() )
// Add separate format for Mapinfo MIF (MITAB is OGR default)
if ( drvName == "MapInfo File" )
{
resultMap.insert( trLongName, drvName );
writableDrivers << "MapInfo MIF";
}
else if ( drvName == "SQLite" )
{
// Unfortunately it seems that there is no simple way to detect if
// OGR SQLite driver is compiled with SpatiaLite support.
// We have HAVE_SPATIALITE in QGIS, but that may differ from OGR
// http://lists.osgeo.org/pipermail/gdal-dev/2012-November/034580.html
// -> test if creation failes
QString option = "SPATIALITE=YES";
char **options = new char *[2];
options[0] = CPLStrdup( option.toLocal8Bit().data() );
options[1] = NULL;
OGRSFDriverH poDriver;
QgsApplication::registerOgrDrivers();
poDriver = OGRGetDriverByName( drvName.toLocal8Bit().data() );
if ( poDriver )
{
OGRDataSourceH ds = OGR_Dr_CreateDataSource( poDriver, TO8( QString( "/vsimem/spatialitetest.sqlite" ) ), options );
if ( ds )
{
writableDrivers << "SpatiaLite";
OGR_DS_Destroy( ds );
}
}
CPLFree( options[0] );
delete [] options;
}
writableDrivers << drvName;
}
}
}

foreach ( QString drvName, writableDrivers )
{
QString longName;
QString trLongName;
QString glob;
QString exts;
if ( QgsVectorFileWriter::driverMetadata( drvName, longName, trLongName, glob, exts ) && !trLongName.isEmpty() )
{
resultMap.insert( trLongName, drvName );
}
}

return resultMap;
}

Expand Down Expand Up @@ -942,10 +1002,18 @@ bool QgsVectorFileWriter::driverMetadata( QString driverName, QString &longName,
}
else if ( driverName.startsWith( "MapInfo File" ) )
{
longName = "Mapinfo File";
trLongName = QObject::tr( "Mapinfo File" );
glob = "*.mif *.tab";
ext = "mif tab";
longName = "Mapinfo TAB";
trLongName = QObject::tr( "Mapinfo TAB" );
glob = "*.tab";
ext = "tab";
}
// 'MapInfo MIF' is internal QGIS addition to distinguish between MITAB and MIF
else if ( driverName.startsWith( "MapInfo MIF" ) )
{
longName = "Mapinfo MIF";
trLongName = QObject::tr( "Mapinfo MIF" );
glob = "*.mif";
ext = "mif";
}
else if ( driverName.startsWith( "DGN" ) )
{
Expand Down Expand Up @@ -975,6 +1043,14 @@ bool QgsVectorFileWriter::driverMetadata( QString driverName, QString &longName,
glob = "*.sqlite";
ext = "sqlite";
}
// QGIS internal addition for SpatialLite
else if ( driverName.startsWith( "SpatiaLite" ) )
{
longName = "SpatiaLite";
trLongName = QObject::tr( "SpatiaLite" );
glob = "*.sqlite";
ext = "sqlite";
}
else if ( driverName.startsWith( "DXF" ) )
{
longName = "AutoCAD DXF";
Expand Down
5 changes: 4 additions & 1 deletion src/core/qgsvectorfilewriter.h
Expand Up @@ -98,7 +98,10 @@ class CORE_EXPORT QgsVectorFileWriter
/**Returns map with format filter string as key and OGR format key as value*/
static QMap< QString, QString> supportedFiltersAndFormats();

/**Returns driver list that can be used for dialogs*/
/**Returns driver list that can be used for dialogs. It contains all OGR drivers
* + some additional internal QGIS driver names to distinguish between more
* supported formats of the same OGR driver
*/
static QMap< QString, QString> ogrDriverList();

/**Returns filter string that can be used for dialogs*/
Expand Down

0 comments on commit fce38c5

Please sign in to comment.