QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsalgorithmsavefeatures.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsalgorithmsavefeatures.cpp
3  ---------------------
4  begin : July 2020
5  copyright : (C) 2020 by Mathieu Pellerin
6  email : nirvn dot asia at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgsvectorfilewriter.h"
20 
22 
23 QString QgsSaveFeaturesAlgorithm::name() const
24 {
25  return QStringLiteral( "savefeatures" );
26 }
27 
28 QString QgsSaveFeaturesAlgorithm::displayName() const
29 {
30  return QObject::tr( "Save vector features to file" );
31 }
32 
33 QStringList QgsSaveFeaturesAlgorithm::tags() const
34 {
35  return QObject::tr( "save,write,export" ).split( ',' );
36 }
37 
38 QString QgsSaveFeaturesAlgorithm::group() const
39 {
40  return QObject::tr( "Vector general" );
41 }
42 
43 QString QgsSaveFeaturesAlgorithm::groupId() const
44 {
45  return QStringLiteral( "vectorgeneral" );
46 }
47 
48 QString QgsSaveFeaturesAlgorithm::shortHelpString() const
49 {
50  return QObject::tr( "This algorithm saves vector features to a specified file dataset.\n\n"
51  "For dataset formats supporting layers, an optional layer name parameter can be used to specify a custom string.\n\n"
52  "Optional GDAL-defined dataset and layer options can be specified. For more information on this, "
53  "read the online GDAL documentation." );
54 }
55 
56 QgsSaveFeaturesAlgorithm *QgsSaveFeaturesAlgorithm::createInstance() const
57 {
58  return new QgsSaveFeaturesAlgorithm();
59 }
60 
61 void QgsSaveFeaturesAlgorithm::initAlgorithm( const QVariantMap & )
62 {
63  addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Vector features" ) ) );
64  addParameter( new QgsProcessingParameterFileDestination( QStringLiteral( "OUTPUT" ), QObject::tr( "Saved features" ), QgsVectorFileWriter::fileFilterString(), QVariant(), false ) );
65 
66  std::unique_ptr< QgsProcessingParameterString > param = qgis::make_unique< QgsProcessingParameterString >( QStringLiteral( "LAYER_NAME" ), QObject::tr( "Layer name" ), QVariant(), false, true );
67  param->setFlags( param->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
68  addParameter( param.release() );
69  param = qgis::make_unique< QgsProcessingParameterString >( QStringLiteral( "DATASOURCE_OPTIONS" ), QObject::tr( "GDAL dataset options (separate individual options with semicolons)" ), QVariant(), false, true );
70  param->setFlags( param->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
71  addParameter( param.release() );
72  param = qgis::make_unique< QgsProcessingParameterString >( QStringLiteral( "LAYER_OPTIONS" ), QObject::tr( "GDAL layer options (separate individual options with semicolons)" ), QVariant(), false, true );
73  param->setFlags( param->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
74  addParameter( param.release() );
75 
76  addOutput( new QgsProcessingOutputString( QStringLiteral( "FILE_PATH" ), QObject::tr( "File name and path" ) ) );
77  addOutput( new QgsProcessingOutputString( QStringLiteral( "LAYER_NAME" ), QObject::tr( "Layer name" ) ) );
78 }
79 
80 QVariantMap QgsSaveFeaturesAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
81 {
82  std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
83 
84  QString layerName = parameterAsString( parameters, QStringLiteral( "LAYER_NAME" ), context ).trimmed();
85  QVariantMap createOptions;
86  if ( !layerName.isEmpty() )
87  {
88  createOptions[QStringLiteral( "layerName" )] = layerName;
89  }
90 
91  QStringList datasourceOptions = parameterAsString( parameters, QStringLiteral( "DATASOURCE_OPTIONS" ), context ).trimmed().split( ';', QString::SkipEmptyParts );
92  QStringList layerOptions = parameterAsString( parameters, QStringLiteral( "LAYER_OPTIONS" ), context ).trimmed().split( ';', QString::SkipEmptyParts );
93 
94 
95  QString dest;
96  std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, source->fields(),
97  source->wkbType(), source->sourceCrs(), QgsFeatureSink::SinkFlags(), createOptions, datasourceOptions, layerOptions ) );
98  if ( !sink )
99  throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
100 
101  double step = source->featureCount() > 0 ? 100.0 / source->featureCount() : 1;
102  long long i = 0;
103 
105  QgsFeature feat;
106  while ( features.nextFeature( feat ) )
107  {
108  i++;
109  if ( feedback->isCanceled() )
110  {
111  break;
112  }
113 
114  feedback->setProgress( i * step );
115 
116  sink->addFeature( feat, QgsFeatureSink::FastInsert );
117  }
118 
119  QString filePath = dest;
120  layerName.clear(); // value of final layer name will be extracted from the destination string
121  int separatorIndex = dest.indexOf( '|' );
122  if ( separatorIndex > -1 )
123  {
124  QRegularExpression layerNameRx( QStringLiteral( "\\|layername=([^\\|]*)" ) );
125  QRegularExpressionMatch match = layerNameRx.match( dest );
126  if ( match.hasMatch() )
127  {
128  layerName = match.captured( 1 );
129  }
130  filePath = dest.mid( 0, separatorIndex );
131  }
132 
133  QVariantMap outputs;
134  outputs.insert( QStringLiteral( "OUTPUT" ), dest );
135  outputs.insert( QStringLiteral( "FILE_PATH" ), filePath );
136  outputs.insert( QStringLiteral( "LAYER_NAME" ), layerName );
137  return outputs;
138 }
139 
QgsFeedback::setProgress
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:62
QgsProcessingFeedback
Base class for providing feedback from a processing algorithm.
Definition: qgsprocessingfeedback.h:38
QgsProcessingParameterDefinition::FlagAdvanced
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
Definition: qgsprocessingparameters.h:423
QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks
@ FlagSkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Definition: qgsprocessingutils.h:477
QgsProcessingParameterFeatureSource
An input feature source (such as vector layers) parameter for processing algorithms.
Definition: qgsprocessingparameters.h:2734
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:76
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:44
QgsProcessingParameterFileDestination
A generic file based destination parameter, for specifying the destination path for a file (non-map l...
Definition: qgsprocessingparameters.h:3127
qgsalgorithmsavefeatures.h
QgsProcessingOutputString
A string output for processing algorithms.
Definition: qgsprocessingoutputs.h:317
QgsFeedback::isCanceled
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:53
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:374
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
qgsvectorfilewriter.h
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:265
QgsProcessingException
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
QgsFeatureSink::FastInsert
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
Definition: qgsfeaturesink.h:70
QgsVectorFileWriter::fileFilterString
static QString fileFilterString(VectorFormatOptions options=SortRecommended)
Returns filter string that can be used for dialogs.
Definition: qgsvectorfilewriter.cpp:3497