Skip to content

Commit fce38c5

Browse files
committed
vector save as: separated MITAB and MIF formats, fixes #6233; added test if OGR SpatiaLite is available
1 parent a07c4da commit fce38c5

File tree

4 files changed

+97
-29
lines changed

4 files changed

+97
-29
lines changed

src/app/ogr/qgsvectorlayersaveasdialog.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ QgsVectorLayerSaveAsDialog::QgsVectorLayerSaveAsDialog( long srsid, QWidget* par
3838
for ( QMap< QString, QString>::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
3939
{
4040
mFormatComboBox->addItem( it.key(), it.value() );
41-
if ( it.key() == "SQLite" )
42-
{
43-
mFormatComboBox->addItem( "SpatiaLite", tr( "SpatiaLite" ) );
44-
}
4541
}
4642

4743
QString format = settings.value( "/UI/lastVectorFormat", "ESRI Shapefile" ).toString();

src/app/qgisapp.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4166,13 +4166,6 @@ void QgisApp::saveAsVectorFileGeneral( bool saveOnlySelection )
41664166
QString format = dialog->format();
41674167
QStringList datasourceOptions = dialog->datasourceOptions();
41684168

4169-
if ( format == "SpatiaLite" )
4170-
{
4171-
if ( !datasourceOptions.contains( "SPATIALITE=YES" ) )
4172-
datasourceOptions.append( "SPATIALITE=YES" );
4173-
format = "SQLite";
4174-
}
4175-
41764169
switch ( dialog->crs() )
41774170
{
41784171
case -2: // Project CRS

src/core/qgsvectorfilewriter.cpp

Lines changed: 93 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,30 @@ QgsVectorFileWriter::QgsVectorFileWriter(
7171
QString vectorFileName = theVectorFileName;
7272
QString fileEncoding = theFileEncoding;
7373

74+
QStringList dsOptions = datasourceOptions;
75+
76+
QString ogrDriverName;
77+
if ( driverName == "MapInfo MIF" )
78+
{
79+
ogrDriverName = "MapInfo File";
80+
}
81+
else if ( driverName == "SpatiaLite" )
82+
{
83+
ogrDriverName = "SQLite";
84+
if ( !dsOptions.contains( "SPATIALITE=YES" ) )
85+
{
86+
dsOptions.append( "SPATIALITE=YES" );
87+
}
88+
}
89+
else
90+
{
91+
ogrDriverName = driverName;
92+
}
93+
7494
// find driver in OGR
7595
OGRSFDriverH poDriver;
7696
QgsApplication::registerOgrDrivers();
77-
poDriver = OGRGetDriverByName( driverName.toLocal8Bit().data() );
97+
poDriver = OGRGetDriverByName( ogrDriverName.toLocal8Bit().data() );
7898

7999
if ( poDriver == NULL )
80100
{
@@ -157,22 +177,22 @@ QgsVectorFileWriter::QgsVectorFileWriter(
157177
}
158178

159179
char **options = NULL;
160-
if ( !datasourceOptions.isEmpty() )
180+
if ( !dsOptions.isEmpty() )
161181
{
162-
options = new char *[ datasourceOptions.size()+1 ];
163-
for ( int i = 0; i < datasourceOptions.size(); i++ )
182+
options = new char *[ dsOptions.size()+1 ];
183+
for ( int i = 0; i < dsOptions.size(); i++ )
164184
{
165-
options[i] = CPLStrdup( datasourceOptions[i].toLocal8Bit().data() );
185+
options[i] = CPLStrdup( dsOptions[i].toLocal8Bit().data() );
166186
}
167-
options[ datasourceOptions.size()] = NULL;
187+
options[ dsOptions.size()] = NULL;
168188
}
169189

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

173193
if ( options )
174194
{
175-
for ( int i = 0; i < datasourceOptions.size(); i++ )
195+
for ( int i = 0; i < dsOptions.size(); i++ )
176196
CPLFree( options[i] );
177197
delete [] options;
178198
options = NULL;
@@ -603,6 +623,7 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
603623
bool skipAttributeCreation,
604624
QString *newFilename )
605625
{
626+
QgsDebugMsg( "fileName = " + fileName );
606627
const QgsCoordinateReferenceSystem* outputCRS;
607628
QgsCoordinateTransform* ct = 0;
608629
int shallTransform = false;
@@ -626,6 +647,8 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
626647
QgsVectorFileWriter* writer =
627648
new QgsVectorFileWriter( fileName, fileEncoding, skipAttributeCreation ? QgsFieldMap() : layer->pendingFields(), layer->wkbType(), outputCRS, driverName, datasourceOptions, layerOptions, newFilename );
628649

650+
QgsDebugMsg( "newFilename = " + *newFilename );
651+
629652
// check whether file creation was successful
630653
WriterError err = writer->hasError();
631654
if ( err != NoError )
@@ -797,6 +820,7 @@ QMap<QString, QString> QgsVectorFileWriter::ogrDriverList()
797820
QgsApplication::registerOgrDrivers();
798821
int const drvCount = OGRGetDriverCount();
799822

823+
QStringList writableDrivers;
800824
for ( int i = 0; i < drvCount; ++i )
801825
{
802826
OGRSFDriverH drv = OGRGetDriver( i );
@@ -805,18 +829,54 @@ QMap<QString, QString> QgsVectorFileWriter::ogrDriverList()
805829
QString drvName = OGR_Dr_GetName( drv );
806830
if ( OGR_Dr_TestCapability( drv, "CreateDataSource" ) != 0 )
807831
{
808-
QString longName;
809-
QString trLongName;
810-
QString glob;
811-
QString exts;
812-
if ( QgsVectorFileWriter::driverMetadata( drvName, longName, trLongName, glob, exts ) && !trLongName.isEmpty() )
832+
// Add separate format for Mapinfo MIF (MITAB is OGR default)
833+
if ( drvName == "MapInfo File" )
813834
{
814-
resultMap.insert( trLongName, drvName );
835+
writableDrivers << "MapInfo MIF";
815836
}
837+
else if ( drvName == "SQLite" )
838+
{
839+
// Unfortunately it seems that there is no simple way to detect if
840+
// OGR SQLite driver is compiled with SpatiaLite support.
841+
// We have HAVE_SPATIALITE in QGIS, but that may differ from OGR
842+
// http://lists.osgeo.org/pipermail/gdal-dev/2012-November/034580.html
843+
// -> test if creation failes
844+
QString option = "SPATIALITE=YES";
845+
char **options = new char *[2];
846+
options[0] = CPLStrdup( option.toLocal8Bit().data() );
847+
options[1] = NULL;
848+
OGRSFDriverH poDriver;
849+
QgsApplication::registerOgrDrivers();
850+
poDriver = OGRGetDriverByName( drvName.toLocal8Bit().data() );
851+
if ( poDriver )
852+
{
853+
OGRDataSourceH ds = OGR_Dr_CreateDataSource( poDriver, TO8( QString( "/vsimem/spatialitetest.sqlite" ) ), options );
854+
if ( ds )
855+
{
856+
writableDrivers << "SpatiaLite";
857+
OGR_DS_Destroy( ds );
858+
}
859+
}
860+
CPLFree( options[0] );
861+
delete [] options;
862+
}
863+
writableDrivers << drvName;
816864
}
817865
}
818866
}
819867

868+
foreach ( QString drvName, writableDrivers )
869+
{
870+
QString longName;
871+
QString trLongName;
872+
QString glob;
873+
QString exts;
874+
if ( QgsVectorFileWriter::driverMetadata( drvName, longName, trLongName, glob, exts ) && !trLongName.isEmpty() )
875+
{
876+
resultMap.insert( trLongName, drvName );
877+
}
878+
}
879+
820880
return resultMap;
821881
}
822882

@@ -942,10 +1002,18 @@ bool QgsVectorFileWriter::driverMetadata( QString driverName, QString &longName,
9421002
}
9431003
else if ( driverName.startsWith( "MapInfo File" ) )
9441004
{
945-
longName = "Mapinfo File";
946-
trLongName = QObject::tr( "Mapinfo File" );
947-
glob = "*.mif *.tab";
948-
ext = "mif tab";
1005+
longName = "Mapinfo TAB";
1006+
trLongName = QObject::tr( "Mapinfo TAB" );
1007+
glob = "*.tab";
1008+
ext = "tab";
1009+
}
1010+
// 'MapInfo MIF' is internal QGIS addition to distinguish between MITAB and MIF
1011+
else if ( driverName.startsWith( "MapInfo MIF" ) )
1012+
{
1013+
longName = "Mapinfo MIF";
1014+
trLongName = QObject::tr( "Mapinfo MIF" );
1015+
glob = "*.mif";
1016+
ext = "mif";
9491017
}
9501018
else if ( driverName.startsWith( "DGN" ) )
9511019
{
@@ -975,6 +1043,14 @@ bool QgsVectorFileWriter::driverMetadata( QString driverName, QString &longName,
9751043
glob = "*.sqlite";
9761044
ext = "sqlite";
9771045
}
1046+
// QGIS internal addition for SpatialLite
1047+
else if ( driverName.startsWith( "SpatiaLite" ) )
1048+
{
1049+
longName = "SpatiaLite";
1050+
trLongName = QObject::tr( "SpatiaLite" );
1051+
glob = "*.sqlite";
1052+
ext = "sqlite";
1053+
}
9781054
else if ( driverName.startsWith( "DXF" ) )
9791055
{
9801056
longName = "AutoCAD DXF";

src/core/qgsvectorfilewriter.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,10 @@ class CORE_EXPORT QgsVectorFileWriter
9898
/**Returns map with format filter string as key and OGR format key as value*/
9999
static QMap< QString, QString> supportedFiltersAndFormats();
100100

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

104107
/**Returns filter string that can be used for dialogs*/

0 commit comments

Comments
 (0)