Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions src/core/utils/layerutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <qgssymbol.h>
#include <qgssymbollayer.h>
#include <qgstextbuffersettings.h>
#include <qgsvectorfilewriter.h>
#include <qgsvectorlayer.h>
#include <qgsvectorlayerlabeling.h>
#include <qgsvectorlayerutils.h>
Expand Down Expand Up @@ -545,6 +546,16 @@ bool LayerUtils::hasMValue( QgsVectorLayer *layer )
return QgsWkbTypes::hasM( layer->wkbType() );
}

QSet<QVariant> LayerUtils::uniqueValuesForVectorLayerFieldIndex( QgsVectorLayer *layer, int fieldIndex )
{
if ( !layer )
{
return QSet<QVariant>();
}

return layer->uniqueValues( fieldIndex );
}

QgsVectorLayer *LayerUtils::loadVectorLayer( const QString &uri, const QString &name, const QString &provider )
{
QgsVectorLayer *layer = new QgsVectorLayer( uri, name, provider );
Expand Down Expand Up @@ -595,3 +606,64 @@ FeatureIterator LayerUtils::createFeatureIteratorFromRectangle( QgsVectorLayer *
const QgsFeatureRequest request = QgsFeatureRequest( rectangle );
return FeatureIterator( layer, request );
}

QString LayerUtils::saveVectorLayerAs( QgsVectorLayer *layer, const QString &filePath, const QString &driverName, const QString &filterExpression )
{
if ( !layer || filePath.isEmpty() )
{
return QString();
}

QFileInfo fileInfo( filePath );
const QString finalDriverName = driverName.isEmpty() ? QgsVectorFileWriter::driverForExtension( fileInfo.suffix() ) : driverName;
if ( finalDriverName.isEmpty() )
{
return QString();
}
QDir dir;
if ( !dir.mkpath( fileInfo.absolutePath() ) )
{
return QString();
}

QStringList datasetOptions = QgsVectorFileWriter::defaultDatasetOptions( finalDriverName );
if ( finalDriverName == QStringLiteral( "GPX" ) )
{
datasetOptions.removeAll( QStringLiteral( "GPX_USE_EXTENSIONS=NO" ) );
datasetOptions << QStringLiteral( "GPX_USE_EXTENSIONS=YES" );
}

QString finalFileName;
QString finalLayerName;
QgsVectorFileWriter::SaveVectorOptions saveOptions;
saveOptions.fileEncoding = QStringLiteral( "UTF8" );
saveOptions.layerName = fileInfo.completeBaseName();
saveOptions.driverName = finalDriverName;
saveOptions.datasourceOptions = datasetOptions;
saveOptions.layerOptions = QgsVectorFileWriter::defaultLayerOptions( finalDriverName );
saveOptions.symbologyExport = Qgis::FeatureSymbologyExport::NoSymbology;
saveOptions.actionOnExistingFile = QgsVectorFileWriter::CreateOrOverwriteFile;

std::unique_ptr<QgsVectorFileWriter> writer( QgsVectorFileWriter::create( filePath, layer->fields(), layer->wkbType(), layer->crs(), QgsProject::instance()->transformContext(), saveOptions, QgsFeatureSink::RegeneratePrimaryKey, &finalFileName, &finalLayerName ) );
if ( writer->hasError() )
{
qInfo() << QStringLiteral( "Vector layer file writer error: %1" ).arg( writer->errorMessage() );
return QString();
}

QgsFeatureRequest request;
if ( !filterExpression.isEmpty() )
{
request.setFilterExpression( filterExpression );
request.setExpressionContext( layer->createExpressionContext() );
}

QgsFeatureIterator it = layer->getFeatures( request );
QgsFeature feature;
while ( it.nextFeature( feature ) )
{
writer->addFeature( feature, QgsFeatureSink::FastInsert );
}

return finalFileName;
}
15 changes: 15 additions & 0 deletions src/core/utils/layerutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ class LayerUtils : public QObject
*/
Q_INVOKABLE static bool hasMValue( QgsVectorLayer *layer );

/**
* Returns a list of unique values for a given \a fieldIndex from the \a layer.
*/
Q_INVOKABLE QSet<QVariant> uniqueValuesForVectorLayerFieldIndex( QgsVectorLayer *layer, int fieldIndex );

/**
* Loads a vector layer.
* \param uri the data source uri
Expand Down Expand Up @@ -226,6 +231,16 @@ class LayerUtils : public QObject
* Returns a feature iterator to get features overlapping a given \a rectangle within the provided \a layer.
*/
Q_INVOKABLE static FeatureIterator createFeatureIteratorFromRectangle( QgsVectorLayer *layer, const QgsRectangle &rectangle );

/**
* Saves a vector layer into an on-disk dataset a given path using the OGR provider.
* \param layer the vector layer to save features from
* \param filePath the file path where the dataset will be writen
* \param driverName an optional OGR driver name (if left empty, the file path extension will drive the OGR driver)
* \param filterExpression an optional filter expression used to save a subset of features from the layer (note that only the global, project, and layer expression context scopes are used)
* \returns If successful, finalized file path will be returned, otherwise an empty string will be returned
*/
Q_INVOKABLE static QString saveVectorLayerAs( QgsVectorLayer *layer, const QString &filePath, const QString &driverName = QString(), const QString &filterExpression = QString() );
};

#endif // LAYERUTILS_H
Loading