Skip to content
Permalink
Browse files
[FEATURE] allow saving vector layers as ogr vector files
git-svn-id: http://svn.osgeo.org/qgis/trunk@13169 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
jef committed Mar 27, 2010
1 parent 75d4a9d commit ae3d122853531c34d0a77538b2c45e38c603ac02
@@ -296,4 +296,7 @@ class QgsVectorDataProvider : QgsDataProvider
(e.g. no multipolygon in a polygon layer)
@note: added in version 1.4*/
bool doesStrictFeatureTypeCheck() const;

/** Returns a list of available encodings */
static const QStringList &availableEncodings();
};
@@ -105,6 +105,7 @@ SET(QGIS_APP_SRCS
ogr/qgsopenvectorlayerdialog.cpp
ogr/qgsnewogrconnection.cpp
ogr/qgsogrsublayersdialog.cpp
ogr/qgsvectorlayersaveasdialog.cpp

attributetable/qgsattributetabledialog.cpp
attributetable/qgsattributetablemodel.cpp
@@ -199,6 +200,7 @@ SET (QGIS_APP_MOC_HDRS
ogr/qgsopenvectorlayerdialog.h
ogr/qgsnewogrconnection.h
ogr/qgsogrsublayersdialog.h
ogr/qgsvectorlayersaveasdialog.h

attributetable/qgsattributetableview.h
attributetable/qgsattributetablemodel.h
@@ -36,7 +36,7 @@
#include "qgsvectorfilewriter.h"
#include "qgsgenericprojectionselector.h"
#include "qgsattributetabledialog.h"
#include "qgsencodingfiledialog.h"
#include "ogr/qgsvectorlayersaveasdialog.h"

#include "qgsrendererv2.h"
#include "qgssymbolv2.h"
@@ -53,6 +53,7 @@
#include <QMessageBox>
#include <QPainter>
#include <QSettings>
#include <QFileDialog>


QgsLegendLayer::QgsLegendLayer( QgsMapLayer* layer )
@@ -450,16 +451,6 @@ void QgsLegendLayer::table()
// the dialog will be deleted by itself on close
}

void QgsLegendLayer::saveAsShapefile()
{
saveAsShapefileGeneral( FALSE );
}

void QgsLegendLayer::saveSelectionAsShapefile()
{
saveAsShapefileGeneral( TRUE );
}

void QgsLegendLayer::saveAsVectorFile()
{
saveAsVectorFileGeneral( false );
@@ -504,177 +495,73 @@ void QgsLegendLayer::showInOverview()

void QgsLegendLayer::saveAsVectorFileGeneral( bool saveOnlySelection )
{
QgsCoordinateReferenceSystem destCRS;

if ( mLyr.layer()->type() != QgsMapLayer::VectorLayer )
return;

QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( mLyr.layer() );

//get output name and format
QSettings settings;
QString filter = QString( "Shapefiles (*.shp)" );
QString dirName = settings.value( "/UI/lastVectorfileDir", "." ).toString();
QString filterString = QgsVectorFileWriter::fileFilterString();
QString selectedFilter = settings.value( "/UI/lastVectorFilter", "[OGR] ESRI Shapefiles (*.shp *.SHP)" ).toString();
QString outputFile = QFileDialog::getSaveFileName( 0, tr( "Save layer as..." ), dirName, filterString, &selectedFilter );
if ( outputFile.isNull() )
{
return; //cancelled
}

settings.setValue( "/UI/lastVectorfileDir", QFileInfo( outputFile ).absolutePath() );
settings.setValue( "/UI/lastVectorFilter", selectedFilter );
QgsVectorLayerSaveAsDialog *dialog = new QgsVectorLayerSaveAsDialog( QgisApp::instance() );

QMap< QString, QString> filterDriverMap = QgsVectorFileWriter::supportedFiltersAndFormats();
QMap< QString, QString>::const_iterator it = filterDriverMap.find( selectedFilter + ";;" );
if ( it == filterDriverMap.constEnd() )
{
return; //unknown format
}

QString driverKey = *it;

//output CRS
QgsCoordinateReferenceSystem destCRS = vlayer->srs();
// Find out if we have projections enabled or not
if ( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() )
{
destCRS = QgisApp::instance()->mapCanvas()->mapRenderer()->destinationSrs();
}

QgsGenericProjectionSelector * mySelector = new QgsGenericProjectionSelector();
mySelector->setSelectedCrsId( destCRS.srsid() );
mySelector->setMessage( tr( "Select the coordinate reference system for the saved shapefile. "
"The data points will be transformed from the layer coordinate reference system." ) );

if ( mySelector->exec() )
{
QgsCoordinateReferenceSystem srs( mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId );
destCRS = srs;
// destCRS->createFromId(mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId)
}
else
if( dialog->exec() == QDialog::Accepted )
{
// Aborted CS selection, don't save.
delete mySelector;
return;
}
delete mySelector;
QString encoding = dialog->encoding();
QString vectorFilename = dialog->filename();
QString format = dialog->format();

if( dialog->crs() < 0 )
{
// Find out if we have projections enabled or not
if ( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() )
{
destCRS = QgisApp::instance()->mapCanvas()->mapRenderer()->destinationSrs();
}
else
{
destCRS = vlayer->srs();
}
}
else
{
destCRS = QgsCoordinateReferenceSystem( dialog->crs(), QgsCoordinateReferenceSystem::InternalCrsId );
}

// overwrite the file - user will already have been prompted
// to verify they want to overwrite by the file dialog above
// might not even exists in the given case.
if ( driverKey == "ESRI Shapefile" )
{
// overwrite the file - user will already have been prompted
// to verify they want to overwrite by the file dialog above
// might not even exists in the given case.
// add the extension if not present
if ( !outputFile.endsWith( ".shp", Qt::CaseInsensitive ) )
if( format == "ESRI Shapefile" )
{
outputFile += ".shp";
if ( !vectorFilename.endsWith( ".shp", Qt::CaseInsensitive ) )
{
vectorFilename += ".shp";
}
QgsVectorFileWriter::deleteShapeFile( vectorFilename );
}

// ok if the file existed it should be deleted now so we can continue...
QApplication::setOverrideCursor( Qt::WaitCursor );

QgsVectorFileWriter::WriterError error;
QString errorMessage;
error = QgsVectorFileWriter::writeAsVectorFormat( vlayer, vectorFilename, encoding, &destCRS, format, saveOnlySelection, &errorMessage );

QApplication::restoreOverrideCursor();

if ( error == QgsVectorFileWriter::NoError )
{
QMessageBox::information( 0, tr( "Saving done" ), tr( "Export to vector file has been completed" ) );
}
else
{
QMessageBox::warning( 0, tr( "Save error" ), tr( "Export to vector file failed.\nError: %1").arg( errorMessage ) );
}
QgsVectorFileWriter::deleteShapeFile( outputFile );
}

QString errorMessage;
QgsVectorFileWriter::WriterError error;
error = QgsVectorFileWriter::writeAsVectorFormat( vlayer, outputFile, "utf-8", &destCRS, driverKey, saveOnlySelection, &errorMessage );
}


void QgsLegendLayer::saveAsShapefileGeneral( bool saveOnlySelection )
{
QgsCoordinateReferenceSystem destCRS;

if ( mLyr.layer()->type() != QgsMapLayer::VectorLayer )
return;

QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( mLyr.layer() );

// get a name for the shapefile
// Get a file to process, starting at the current directory
QSettings settings;
QString filter = QString( "Shapefiles (*.shp)" );
QString dirName = settings.value( "/UI/lastShapefileDir", "." ).toString();

QgsEncodingFileDialog* openFileDialog = new QgsEncodingFileDialog( 0,
tr( "Save layer as..." ),
dirName,
filter,
QString( "" ) );
openFileDialog->setAcceptMode( QFileDialog::AcceptSave );

// allow for selection of more than one file
//openFileDialog->setMode(QFileDialog::AnyFile);

if ( openFileDialog->exec() != QDialog::Accepted )
return;


QString encoding = openFileDialog->encoding();
QString shapefileName = openFileDialog->selectedFiles().first();
settings.setValue( "/UI/lastShapefileDir", QFileInfo( shapefileName ).absolutePath() );


if ( shapefileName.isNull() )
return;

// add the extension if not present
if ( !shapefileName.endsWith( ".shp", Qt::CaseInsensitive ) )
{
shapefileName += ".shp";
}

destCRS = vlayer->srs();
// Find out if we have projections enabled or not
if ( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() )
{
destCRS = QgisApp::instance()->mapCanvas()->mapRenderer()->destinationSrs();
}

QgsGenericProjectionSelector * mySelector = new QgsGenericProjectionSelector();
mySelector->setSelectedCrsId( destCRS.srsid() );
mySelector->setMessage( tr( "Select the coordinate reference system for the saved shapefile. "
"The data points will be transformed from the layer coordinate reference system." ) );

if ( mySelector->exec() )
{
QgsCoordinateReferenceSystem srs( mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId );
destCRS = srs;
// destCRS->createFromId(mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId)
}
else
{
// Aborted CS selection, don't save.
delete mySelector;
return;
}

delete mySelector;

// overwrite the file - user will already have been prompted
// to verify they want to overwrite by the file dialog above
// might not even exists in the given case.
QgsVectorFileWriter::deleteShapeFile( shapefileName );

// ok if the file existed it should be deleted now so we can continue...
QApplication::setOverrideCursor( Qt::WaitCursor );

QgsVectorFileWriter::WriterError error;
QString errorMessage;
error = QgsVectorFileWriter::writeAsShapefile( vlayer, shapefileName, encoding, &destCRS, saveOnlySelection, &errorMessage );

QApplication::restoreOverrideCursor();

if ( error == QgsVectorFileWriter::NoError )
{
QMessageBox::information( 0, tr( "Saving done" ), tr( "Export to Shapefile has been completed" ) );
}
else
{
QMessageBox::warning( 0, tr( "Save error" ), errorMessage );
}
delete dialog;
}



QString QgsLegendLayer::nameFromLayer( QgsMapLayer* layer )
{
QString sourcename = layer->publicSource(); //todo: move this duplicated code into a new function
@@ -1,6 +1,6 @@
/***************************************************************************
* Copyright (C) 2005 by Tim Sutton *
* aps02ts@macbuntu *
* Copyright (C) 2005 by Tim Sutton *
* aps02ts@macbuntu *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
@@ -84,9 +84,6 @@ class QgsLegendLayer : public QgsLegendItem
/**Show layer attribute table*/
void table();

void saveAsShapefile();
void saveSelectionAsShapefile();

void saveAsVectorFile();
void saveSelectionAsVectorFile();

@@ -111,9 +108,6 @@ class QgsLegendLayer : public QgsLegendItem

QPixmap getOriginalPixmap();

/**Save as shapefile (called from saveAsShapefile and saveSelectionAsShapefile)*/
void saveAsShapefileGeneral( bool saveOnlySelection );

void saveAsVectorFileGeneral( bool saveOnlySelection );

private:
@@ -22,9 +22,11 @@
#include <QMessageBox>
#include <QInputDialog>
#include <QTextCodec>

#include "qgslogger.h"
#include "qgsencodingfiledialog.h"
#include "qgsopenvectorlayerdialog.h"
#include "qgsvectordataprovider.h"

#include <ogr_api.h>
#include "qgsproviderregistry.h"
#include "qgsnewogrconnection.h"
@@ -40,8 +42,10 @@ QgsOpenVectorLayerDialog::QgsOpenVectorLayerDialog( QWidget* parent, Qt::WFlags
cmbConnections->blockSignals( true );
radioSrcFile->setChecked( true );
mDataSourceType = "file";

//set encoding
// cmbEncodings->setItemText( cmbEncodings->currentIndex(), QString( QTextCodec::codecForLocale()->name() ) );
cmbEncodings->addItems( QgsVectorDataProvider::availableEncodings() );

QSettings settings;
QString enc = settings.value( "/UI/encoding", QString( "System" ) ).toString();

0 comments on commit ae3d122

Please sign in to comment.