Skip to content

Commit

Permalink
[vector file writer] Add coordinate transformation context to fix KML…
Browse files Browse the repository at this point in the history
…/GPX export
  • Loading branch information
nirvn committed Feb 13, 2020
1 parent 50bdd36 commit 9ce12c0
Show file tree
Hide file tree
Showing 14 changed files with 424 additions and 198 deletions.
99 changes: 78 additions & 21 deletions python/core/auto_generated/qgsvectorfilewriter.sip.in
Expand Up @@ -230,7 +230,7 @@ Creates a clone of the FieldValueConverter.
};


static QgsVectorFileWriter::WriterError writeAsVectorFormat( QgsVectorLayer *layer,
static QgsVectorFileWriter::WriterError writeAsVectorFormat( QgsVectorLayer *layer,
const QString &fileName,
const QString &fileEncoding,
const QgsCoordinateReferenceSystem &destCRS = QgsCoordinateReferenceSystem(),
Expand All @@ -249,7 +249,7 @@ Creates a clone of the FieldValueConverter.
bool includeZ = false,
const QgsAttributeList &attributes = QgsAttributeList(),
QgsVectorFileWriter::FieldValueConverter *fieldValueConverter = 0
);
) /Deprecated/;
%Docstring
Write contents of vector layer to an (OGR supported) vector format

Expand All @@ -259,7 +259,7 @@ Write contents of vector layer to an (OGR supported) vector format
:param destCRS: CRS to reproject exported geometries to, or invalid CRS for no reprojection
:param driverName: OGR driver to use
:param onlySelected: write only selected features of layer
:param errorMessage: pointer to buffer fo error message
:param errorMessage: will be set to the error message text, if an error occurs while writing the layer
:param datasourceOptions: list of OGR data source creation options
:param layerOptions: list of OGR layer creation options
:param skipAttributeCreation: only write geometries
Expand All @@ -273,10 +273,13 @@ Write contents of vector layer to an (OGR supported) vector format
:param includeZ: set to ``True`` to include z dimension in output. This option is only valid if overrideGeometryType is set. (added in QGIS 2.14)
:param attributes: attributes to export (empty means all unless skipAttributeCreation is set)
:param fieldValueConverter: field value converter (added in QGIS 2.16)

.. deprecated::
Use writeAsVectorFormatV2() instead.
%End


static QgsVectorFileWriter::WriterError writeAsVectorFormat( QgsVectorLayer *layer,
static QgsVectorFileWriter::WriterError writeAsVectorFormat( QgsVectorLayer *layer,
const QString &fileName,
const QString &fileEncoding,
const QgsCoordinateTransform &ct,
Expand All @@ -295,7 +298,7 @@ Write contents of vector layer to an (OGR supported) vector format
bool includeZ = false,
const QgsAttributeList &attributes = QgsAttributeList(),
QgsVectorFileWriter::FieldValueConverter *fieldValueConverter = 0
);
) /Deprecated/;
%Docstring
Writes a layer out to a vector file.

Expand All @@ -306,7 +309,7 @@ Writes a layer out to a vector file.
for no transformation
:param driverName: OGR driver to use
:param onlySelected: write only selected features of layer
:param errorMessage: pointer to buffer fo error message
:param errorMessage: will be set to the error message text, if an error occurs while writing the layer
:param datasourceOptions: list of OGR data source creation options
:param layerOptions: list of OGR layer creation options
:param skipAttributeCreation: only write geometries
Expand All @@ -322,6 +325,9 @@ Writes a layer out to a vector file.
:param fieldValueConverter: field value converter (added in QGIS 2.16)

.. versionadded:: 2.2

.. deprecated::
Use writeAsVectorFormatV2() instead.
%End

class SaveVectorOptions
Expand Down Expand Up @@ -381,38 +387,89 @@ Constructor
};


static QgsVectorFileWriter::WriterError writeAsVectorFormat( QgsVectorLayer *layer,
static QgsVectorFileWriter::WriterError writeAsVectorFormat( QgsVectorLayer *layer,
const QString &fileName,
const QgsVectorFileWriter::SaveVectorOptions &options,
QString *newFilename = 0,
QString *errorMessage /Out/ = 0
);
) /Deprecated/;
%Docstring
Writes a layer out to a vector file.

:param layer: source layer to write
:param fileName: file name to write to
:param options: options.
:param newFilename: QString pointer which will contain the new file name created (in case it is different to fileName).
:param errorMessage: pointer to buffer fo error message
:param errorMessage: will be set to the error message text, if an error occurs while writing the layer

.. versionadded:: 3.0

.. deprecated::
Use writeAsVectorFormatV2() instead.
%End

QgsVectorFileWriter( const QString &vectorFileName,
const QString &fileEncoding,
const QgsFields &fields,
QgsWkbTypes::Type geometryType,
const QgsCoordinateReferenceSystem &srs = QgsCoordinateReferenceSystem(),
const QString &driverName = "GPKG",
const QStringList &datasourceOptions = QStringList(),
const QStringList &layerOptions = QStringList(),
QString *newFilename = 0,
QgsVectorFileWriter::SymbologyExport symbologyExport = QgsVectorFileWriter::NoSymbology,
QgsFeatureSink::SinkFlags sinkFlags = 0
) /Deprecated/;



static QgsVectorFileWriter *create( const QString &fileName,
const QgsFields &fields,
QgsWkbTypes::Type geometryType,
const QgsCoordinateReferenceSystem &srs,
const QgsCoordinateTransformContext &transformContext,
const QgsVectorFileWriter::SaveVectorOptions &options,
QgsFeatureSink::SinkFlags sinkFlags = 0,
QString *newFilename = 0,
QString *newLayer = 0 );
%Docstring
Create a new vector file writer.

:param fileName: file name to write to
:param fields: fields to write
:param geometryType: geometry type of output file
:param srs: spatial reference system of output file
:param transformContext: coordinate transform context
:param options: save options
:param sinkFlags: feature sink flags
:param newFilename: potentially modified file name (output parameter)
:param newLayer: potentially modified layer name (output parameter)

.. versionadded:: 3.10.3
%End

QgsVectorFileWriter( const QString &vectorFileName,
const QString &fileEncoding,
const QgsFields &fields,
QgsWkbTypes::Type geometryType,
const QgsCoordinateReferenceSystem &srs = QgsCoordinateReferenceSystem(),
const QString &driverName = "GPKG",
const QStringList &datasourceOptions = QStringList(),
const QStringList &layerOptions = QStringList(),
QString *newFilename = 0,
QgsVectorFileWriter::SymbologyExport symbologyExport = QgsVectorFileWriter::NoSymbology,
QgsFeatureSink::SinkFlags sinkFlags = 0
);
static QgsVectorFileWriter::WriterError writeAsVectorFormatV2( QgsVectorLayer *layer,
const QString &fileName,
const QgsCoordinateTransformContext &transformContext,
const QgsVectorFileWriter::SaveVectorOptions &options,
QString *newFilename = 0,
QString *newLayer = 0,
QString *errorMessage /Out/ = 0 );
%Docstring
Writes a layer out to a vector file.

:param layer: source layer to write
:param fileName: file name to write to
:param transformContext: coordinate transform context
:param options: save options
:param newFilename: potentially modified file name (output parameter)
:param newLayer: potentially modified layer name (output parameter)

:return: - Error message code, or QgsVectorFileWriter.NoError if the write operation was successful
- errorMessage: will be set to the error message text, if an error occurs while writing the layer

.. versionadded:: 3.10.3
%End

struct FilterFormatDetails
{
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/processing/qgsalgorithmpackage.cpp
Expand Up @@ -216,7 +216,7 @@ bool QgsPackageAlgorithm::packageVectorLayer( QgsVectorLayer *layer, const QStri
QString error;
QString newFilename;
QString newLayer;
if ( QgsVectorFileWriter::writeAsVectorFormat( layer, path, options, &newFilename, &error, &newLayer ) != QgsVectorFileWriter::NoError )
if ( QgsVectorFileWriter::writeAsVectorFormatV2( layer, path, context.transformContext(), options, &newFilename, &newLayer, &error ) != QgsVectorFileWriter::NoError )
{
feedback->reportError( QObject::tr( "Packaging layer failed: %1" ).arg( error ) );
return false;
Expand Down
19 changes: 13 additions & 6 deletions src/core/processing/qgsprocessingutils.cpp
Expand Up @@ -627,9 +627,14 @@ QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, Qgs
// use QgsVectorFileWriter for OGR destinations instead of QgsVectorLayerImport, as that allows
// us to use any OGR format which supports feature addition
QString finalFileName;
std::unique_ptr< QgsVectorFileWriter > writer = qgis::make_unique< QgsVectorFileWriter >( destination, options.value( QStringLiteral( "fileEncoding" ) ).toString(), newFields, geometryType, crs, format, QgsVectorFileWriter::defaultDatasetOptions( format ),
QgsVectorFileWriter::defaultLayerOptions( format ), &finalFileName, QgsVectorFileWriter::NoSymbology, sinkFlags );

QgsVectorFileWriter::SaveVectorOptions saveOptions;
saveOptions.fileEncoding = options.value( QStringLiteral( "fileEncoding" ) ).toString();
saveOptions.driverName = format;
saveOptions.datasourceOptions = QgsVectorFileWriter::defaultDatasetOptions( format );
saveOptions.layerOptions = QgsVectorFileWriter::defaultLayerOptions( format );
saveOptions.symbologyExport = QgsVectorFileWriter::NoSymbology;
saveOptions.actionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;
std::unique_ptr< QgsVectorFileWriter > writer( QgsVectorFileWriter::create( destination, newFields, geometryType, crs, context.transformContext(), saveOptions, sinkFlags, &finalFileName ) );
if ( writer->hasError() )
{
throw QgsProcessingException( QObject::tr( "Could not create layer %1: %2" ).arg( destination, writer->errorMessage() ) );
Expand Down Expand Up @@ -892,8 +897,10 @@ QString convertToCompatibleFormatInternal( const QgsVectorLayer *vl, bool select
{
QString temp = QgsProcessingUtils::generateTempFilename( baseName + '.' + preferredFormat );

QgsVectorFileWriter writer( temp, context.defaultEncoding(),
vl->fields(), vl->wkbType(), vl->crs(), QgsVectorFileWriter::driverForExtension( preferredFormat ) );
QgsVectorFileWriter::SaveVectorOptions saveOptions;
saveOptions.fileEncoding = context.defaultEncoding();
saveOptions.driverName = QgsVectorFileWriter::driverForExtension( preferredFormat );
std::unique_ptr< QgsVectorFileWriter > writer( QgsVectorFileWriter::create( temp, vl->fields(), vl->wkbType(), vl->crs(), context.transformContext(), saveOptions ) );
QgsFeature f;
QgsFeatureIterator it;
if ( selectedFeaturesOnly )
Expand All @@ -905,7 +912,7 @@ QString convertToCompatibleFormatInternal( const QgsVectorLayer *vl, bool select
{
if ( feedback->isCanceled() )
return QString();
writer.addFeature( f, QgsFeatureSink::FastInsert );
writer->addFeature( f, QgsFeatureSink::FastInsert );
}
return temp;
}
Expand Down
24 changes: 9 additions & 15 deletions src/core/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -409,21 +409,15 @@ QgsVectorLayerExporter::ExportError QgsOgrProvider::createEmptyLayer( const QStr

QString newLayerName( layerName );

std::unique_ptr< QgsVectorFileWriter > writer = qgis::make_unique< QgsVectorFileWriter >(
uri,
encoding,
fields,
wkbType,
srs,
driverName,
dsOptions,
layerOptions,
nullptr,
QgsVectorFileWriter::NoSymbology,
nullptr,
layerName,
action,
&newLayerName );
QgsVectorFileWriter::SaveVectorOptions saveOptions;
saveOptions.layerName = layerName;
saveOptions.fileEncoding = encoding;
saveOptions.driverName = driverName;
saveOptions.datasourceOptions = dsOptions;
saveOptions.layerOptions = layerOptions;
saveOptions.actionOnExistingFile = action;
saveOptions.symbologyExport = QgsVectorFileWriter::NoSymbology;
std::unique_ptr< QgsVectorFileWriter > writer( QgsVectorFileWriter::create( uri, fields, wkbType, srs, QgsCoordinateTransformContext(), saveOptions, nullptr, nullptr, &newLayerName ) );
layerName = newLayerName;

QgsVectorFileWriter::WriterError error = writer->hasError();
Expand Down
14 changes: 9 additions & 5 deletions src/core/qgsabstractgeopdfexporter.cpp
Expand Up @@ -15,6 +15,7 @@
***************************************************************************/

#include "qgsabstractgeopdfexporter.h"
#include "qgscoordinatetransformcontext.h"
#include "qgsrenderedfeaturehandlerinterface.h"
#include "qgsfeaturerequest.h"
#include "qgslogger.h"
Expand Down Expand Up @@ -162,19 +163,22 @@ bool QgsAbstractGeoPdfExporter::saveTemporaryLayers()
// write out features to disk
const QgsFeatureList features = it.value();
QString layerName;
QgsVectorFileWriter writer( filePath, QString(), features.first().fields(), features.first().geometry().wkbType(), QgsCoordinateReferenceSystem(), QStringLiteral( "GPKG" ), QStringList(), QStringList(), nullptr, QgsVectorFileWriter::NoSymbology, QgsFeatureSink::RegeneratePrimaryKey, &layerName );
if ( writer.hasError() )
QgsVectorFileWriter::SaveVectorOptions saveOptions;
saveOptions.driverName = QStringLiteral( "GPKG" );
saveOptions.symbologyExport = QgsVectorFileWriter::NoSymbology;
std::unique_ptr< QgsVectorFileWriter > writer( QgsVectorFileWriter::create( filePath, features.first().fields(), features.first().geometry().wkbType(), QgsCoordinateReferenceSystem(), QgsCoordinateTransformContext(), saveOptions, QgsFeatureSink::RegeneratePrimaryKey, nullptr, &layerName ) );
if ( writer->hasError() )
{
mErrorMessage = writer.errorMessage();
mErrorMessage = writer->errorMessage();
QgsDebugMsg( mErrorMessage );
return false;
}
for ( const QgsFeature &feature : features )
{
QgsFeature f = feature;
if ( !writer.addFeature( f, QgsFeatureSink::FastInsert ) )
if ( !writer->addFeature( f, QgsFeatureSink::FastInsert ) )
{
mErrorMessage = writer.errorMessage();
mErrorMessage = writer->errorMessage();
QgsDebugMsg( mErrorMessage );
return false;
}
Expand Down

0 comments on commit 9ce12c0

Please sign in to comment.