QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgsalgorithmexportlayersinformation.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmexportlayersinformation.cpp
3 ---------------------------------
4 begin : December 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
20#include "qgsproviderregistry.h"
21
23
24QString QgsExportLayersInformationAlgorithm::name() const
25{
26 return QStringLiteral( "exportlayersinformation" );
27}
28
29QString QgsExportLayersInformationAlgorithm::displayName() const
30{
31 return QObject::tr( "Export layer(s) information" );
32}
33
34QStringList QgsExportLayersInformationAlgorithm::tags() const
35{
36 return QObject::tr( "metadata,details,extent" ).split( ',' );
37}
38
39QString QgsExportLayersInformationAlgorithm::group() const
40{
41 return QObject::tr( "Layer tools" );
42}
43
44QString QgsExportLayersInformationAlgorithm::groupId() const
45{
46 return QStringLiteral( "layertools" );
47}
48
49void QgsExportLayersInformationAlgorithm::initAlgorithm( const QVariantMap & )
50{
51 addParameter( new QgsProcessingParameterMultipleLayers( QStringLiteral( "LAYERS" ), QObject::tr( "Input layer(s)" ), Qgis::ProcessingSourceType::MapLayer ) );
52 addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Output" ), Qgis::ProcessingSourceType::VectorPolygon, QVariant() ) );
53}
54
55QString QgsExportLayersInformationAlgorithm::shortHelpString() const
56{
57 return QObject::tr( "This algorithm creates a polygon layer with features corresponding to the extent of selected layer(s).\n\n"
58 "Additional layer details - CRS, provider name, file path, layer name, subset filter, abstract and attribution - are attached as attributes to each feature." );
59}
60
61QString QgsExportLayersInformationAlgorithm::shortDescription() const
62{
63 return QObject::tr( "Creates a polygon layer with features corresponding to the extent of selected layer(s)." );
64}
65
66QgsExportLayersInformationAlgorithm *QgsExportLayersInformationAlgorithm::createInstance() const
67{
68 return new QgsExportLayersInformationAlgorithm();
69}
70
71bool QgsExportLayersInformationAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
72{
73 const QList<QgsMapLayer *> layers = parameterAsLayerList( parameters, QStringLiteral( "LAYERS" ), context );
74 for ( QgsMapLayer *layer : layers )
75 {
76 if ( !mCrs.isValid() )
77 {
78 mCrs = layer->crs();
79 }
80 else if ( mCrs.authid() != QLatin1String( "EPSG:4326" ) )
81 {
82 if ( mCrs != layer->crs() )
83 {
84 // mixed CRSes, set output CRS to EPSG:4326
85 mCrs = QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) );
86 }
87 }
88 mLayers.emplace_back( layer->clone() );
89 }
90
91 if ( !mCrs.isValid() )
92 mCrs = QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) );
93
94 if ( mLayers.empty() )
95 feedback->reportError( QObject::tr( "No layers selected" ), false );
96
97 return true;
98}
99
100QVariantMap QgsExportLayersInformationAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
101{
102 QgsFields outFields;
103 outFields.append( QgsField( QStringLiteral( "name" ), QMetaType::Type::QString ) );
104 outFields.append( QgsField( QStringLiteral( "source" ), QMetaType::Type::QString ) );
105 outFields.append( QgsField( QStringLiteral( "crs" ), QMetaType::Type::QString ) );
106 outFields.append( QgsField( QStringLiteral( "provider" ), QMetaType::Type::QString ) );
107 outFields.append( QgsField( QStringLiteral( "file_path" ), QMetaType::Type::QString ) );
108 outFields.append( QgsField( QStringLiteral( "layer_name" ), QMetaType::Type::QString ) );
109 outFields.append( QgsField( QStringLiteral( "subset" ), QMetaType::Type::QString ) );
110 outFields.append( QgsField( QStringLiteral( "abstract" ), QMetaType::Type::QString ) );
111 outFields.append( QgsField( QStringLiteral( "attribution" ), QMetaType::Type::QString ) );
112
113 QString outputDest;
114 std::unique_ptr<QgsFeatureSink> outputSink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, outputDest, outFields, Qgis::WkbType::Polygon, mCrs ) );
115
116 const QList<QgsMapLayer *> layers = parameterAsLayerList( parameters, QStringLiteral( "LAYERS" ), context );
117
118 const double step = layers.size() > 0 ? 100.0 / layers.size() : 1;
119 int i = 0;
120 for ( const std::unique_ptr<QgsMapLayer> &layer : mLayers )
121 {
122 i++;
123 if ( feedback->isCanceled() )
124 {
125 break;
126 }
127
128 feedback->setProgress( i * step );
129
130 QgsFeature feature;
131
132 QgsAttributes attributes;
133 attributes << layer->name()
134 << layer->source()
135 << layer->crs().authid();
136 if ( layer->dataProvider() )
137 {
138 const QVariantMap parts = QgsProviderRegistry::instance()->decodeUri( layer->dataProvider()->name(), layer->source() );
139 attributes << layer->dataProvider()->name()
140 << parts[QStringLiteral( "path" )]
141 << parts[QStringLiteral( "layerName" )]
142 << parts[QStringLiteral( "subset" )];
143 }
144 else
145 {
146 attributes << QVariant() << QVariant() << QVariant() << QVariant();
147 }
148 attributes << layer->metadata().rights().join( ';' )
149 << layer->serverProperties()->abstract();
150 feature.setAttributes( attributes );
151
152 QgsRectangle rect = layer->extent();
153 if ( !rect.isEmpty() )
154 {
155 if ( layer->crs() != mCrs )
156 {
157 QgsCoordinateTransform transform( layer->crs(), mCrs, context.transformContext() );
158 transform.setBallparkTransformsAreAppropriate( true );
159 try
160 {
161 rect = transform.transformBoundingBox( rect );
162 }
163 catch ( QgsCsException &e )
164 {
165 Q_UNUSED( e )
166 rect = QgsRectangle();
167 feedback->pushInfo( QObject::tr( "Extent of layer %1 could not be reprojected" ).arg( layer->name() ) );
168 }
169 }
170 feature.setGeometry( QgsGeometry::fromRect( rect ) );
171 }
172 if ( !outputSink->addFeature( feature, QgsFeatureSink::FastInsert ) )
173 throw QgsProcessingException( writeFeatureError( outputSink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
174 }
175
176 outputSink->finalize();
177
178 QVariantMap outputs;
179 outputs.insert( QStringLiteral( "OUTPUT" ), outputDest );
180 return outputs;
181}
182
@ MapLayer
Any map layer type (raster, vector, mesh, point cloud, annotation or plugin layer).
Definition qgis.h:3532
@ VectorPolygon
Vector polygon layers.
Definition qgis.h:3536
@ Polygon
Polygon.
Definition qgis.h:281
A vector of attributes.
Represents a coordinate reference system (CRS).
Handles coordinate transforms between two coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:53
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition qgsfeedback.h:61
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:54
Container of fields for a vector layer.
Definition qgsfields.h:46
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Definition qgsfields.cpp:73
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
Base class for all map layer types.
Definition qgsmaplayer.h:80
Contains information about the context in which a processing algorithm is executed.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
A feature sink output for processing algorithms.
A parameter for processing algorithms which accepts multiple map layers.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
A rectangle specified with double values.