QGIS API Documentation 4.3.0-Master (d3b565c628d)
Loading...
Searching...
No Matches
qgsalgorithmextractlayoutmapextent.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmextractlayoutmapextent.cpp
3 ---------------------
4 begin : March 2019
5 copyright : (C) 2019 by Nyall Dawson
6 email : nyall dot dawson 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 "layout/qgslayout.h"
25
26#include <QString>
27
28using namespace Qt::StringLiterals;
29
31
32QString QgsLayoutMapExtentToLayerAlgorithm::name() const
33{
34 return u"printlayoutmapextenttolayer"_s;
35}
36
37QString QgsLayoutMapExtentToLayerAlgorithm::displayName() const
38{
39 return QObject::tr( "Print layout map extent to layer" );
40}
41
42QStringList QgsLayoutMapExtentToLayerAlgorithm::tags() const
43{
44 return QObject::tr( "layout,composer,composition,visible" ).split( ',' );
45}
46
47QString QgsLayoutMapExtentToLayerAlgorithm::group() const
48{
49 return QObject::tr( "Cartography" );
50}
51
52QString QgsLayoutMapExtentToLayerAlgorithm::groupId() const
53{
54 return u"cartography"_s;
55}
56
57QString QgsLayoutMapExtentToLayerAlgorithm::shortDescription() const
58{
59 return QObject::tr( "Creates a polygon layer containing the extent of a print layout map item." );
60}
61
62void QgsLayoutMapExtentToLayerAlgorithm::initAlgorithm( const QVariantMap & )
63{
64 addParameter( new QgsProcessingParameterLayout( u"LAYOUT"_s, QObject::tr( "Print layout" ) ) );
65 addParameter( new QgsProcessingParameterLayoutItem( u"MAP"_s, QObject::tr( "Map item" ), QVariant(), u"LAYOUT"_s, QgsLayoutItemRegistry::LayoutMap, true ) );
66 auto crsParam = std::make_unique<QgsProcessingParameterCrs>( u"CRS"_s, QObject::tr( "Override CRS" ), QVariant(), true );
67 crsParam->setFlags( crsParam->flags() | Qgis::ProcessingParameterFlag::Advanced );
68 addParameter( crsParam.release() );
69 addParameter( new QgsProcessingParameterFeatureSink( u"OUTPUT"_s, QObject::tr( "Extent" ), Qgis::ProcessingSourceType::VectorPolygon ) );
70 addOutput( new QgsProcessingOutputNumber( u"WIDTH"_s, QObject::tr( "Map width" ) ) );
71 addOutput( new QgsProcessingOutputNumber( u"HEIGHT"_s, QObject::tr( "Map height" ) ) );
72 addOutput( new QgsProcessingOutputNumber( u"SCALE"_s, QObject::tr( "Map scale" ) ) );
73 addOutput( new QgsProcessingOutputNumber( u"ROTATION"_s, QObject::tr( "Map rotation" ) ) );
74}
75
76Qgis::ProcessingAlgorithmFlags QgsLayoutMapExtentToLayerAlgorithm::flags() const
77{
79}
80
81QString QgsLayoutMapExtentToLayerAlgorithm::shortHelpString() const
82{
83 return QObject::tr(
84 "This algorithm creates a polygon layer containing the extent of a print layout map item (or items), "
85 "with attributes specifying the map size (in layout units), scale and rotation.\n\n"
86 "If the map item parameter is specified, then only the matching map extent will be exported. If it "
87 "is not specified, all map extents from the layout will be exported.\n\n"
88 "Optionally, a specific output CRS can be specified. If it is not specified, the original map "
89 "item CRS will be used."
90 );
91}
92
93QgsLayoutMapExtentToLayerAlgorithm *QgsLayoutMapExtentToLayerAlgorithm::createInstance() const
94{
95 return new QgsLayoutMapExtentToLayerAlgorithm();
96}
97
98bool QgsLayoutMapExtentToLayerAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
99{
100 QGS_MARK_ALGORITHM_SOURCE
101
102 // this needs to be done in main thread, layouts are not thread safe
103 QgsPrintLayout *layout = parameterAsLayout( parameters, u"LAYOUT"_s, context );
104 if ( !layout )
105 throw QgsProcessingException( QObject::tr( "Cannot find layout with name \"%1\"" ).arg( parameters.value( u"LAYOUT"_s ).toString() ) );
106
107 QgsLayoutItemMap *map = qobject_cast<QgsLayoutItemMap *>( parameterAsLayoutItem( parameters, u"MAP"_s, context, layout ) );
108 if ( !map && parameters.value( u"MAP"_s ).isValid() )
109 throw QgsProcessingException( QObject::tr( "Cannot find matching map item with ID %1" ).arg( parameters.value( u"MAP"_s ).toString() ) );
110
111 QList<QgsLayoutItemMap *> maps;
112 if ( map )
113 maps << map;
114 else
115 layout->layoutItems( maps );
116
117 const QgsCoordinateReferenceSystem overrideCrs = parameterAsCrs( parameters, u"CRS"_s, context );
118
119 mFeatures.reserve( maps.size() );
120 for ( QgsLayoutItemMap *map : maps )
121 {
122 if ( !mCrs.isValid() )
123 mCrs = !overrideCrs.isValid() ? map->crs() : overrideCrs;
124
125 QgsGeometry extent = QgsGeometry::fromQPolygonF( map->visibleExtentPolygon() );
126 if ( map->crs() != mCrs )
127 {
128 try
129 {
130 extent.transform( QgsCoordinateTransform( map->crs(), mCrs, context.transformContext() ) );
131 }
132 catch ( QgsCsException & )
133 {
134 feedback->reportError( QObject::tr( "Error reprojecting map to destination CRS" ) );
135 continue;
136 }
137 }
138
139 mWidth = map->rect().width();
140 mHeight = map->rect().height();
141 mScale = map->scale();
142 mRotation = map->mapRotation();
143
144 QgsFeature f;
145 f.setAttributes( QgsAttributes() << map->displayName() << mWidth << mHeight << mScale << mRotation );
146 f.setGeometry( extent );
147
148 mFeatures << f;
149 }
150 return true;
151}
152
153QVariantMap QgsLayoutMapExtentToLayerAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
154{
155 QgsFields fields;
156 fields.append( QgsField( u"map"_s, QMetaType::Type::QString ) );
157 fields.append( QgsField( u"width"_s, QMetaType::Type::Double ) );
158 fields.append( QgsField( u"height"_s, QMetaType::Type::Double ) );
159 fields.append( QgsField( u"scale"_s, QMetaType::Type::Double ) );
160 fields.append( QgsField( u"rotation"_s, QMetaType::Type::Double ) );
161
162 QString dest;
163 std::unique_ptr<QgsFeatureSink> sink( parameterAsSink( parameters, u"OUTPUT"_s, context, dest, fields, Qgis::WkbType::Polygon, mCrs ) );
164 if ( !sink )
165 throw QgsProcessingException( invalidSinkError( parameters, u"OUTPUT"_s ) );
166
167 for ( QgsFeature &f : mFeatures )
168 {
169 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
170 throw QgsProcessingException( writeFeatureError( sink.get(), parameters, u"OUTPUT"_s ) );
171 else
172 feedback->featureAddedToSink( u"OUTPUT"_s );
173 }
174
175 sink->finalize();
176 feedback->featureSinkFinalized( u"OUTPUT"_s );
177
178 feedback->setProgress( 100 );
179
180 QVariantMap outputs;
181 outputs.insert( u"OUTPUT"_s, dest );
182 // these numeric outputs only have value for single-map layouts
183 outputs.insert( u"WIDTH"_s, mFeatures.size() == 1 ? mWidth : QVariant() );
184 outputs.insert( u"HEIGHT"_s, mFeatures.size() == 1 ? mHeight : QVariant() );
185 outputs.insert( u"SCALE"_s, mFeatures.size() == 1 ? mScale : QVariant() );
186 outputs.insert( u"ROTATION"_s, mFeatures.size() == 1 ? mRotation : QVariant() );
187 return outputs;
188}
189
@ VectorPolygon
Vector polygon layers.
Definition qgis.h:3752
QFlags< ProcessingAlgorithmFlag > ProcessingAlgorithmFlags
Flags indicating how and when an algorithm operates and should be exposed to users.
Definition qgis.h:3826
@ Polygon
Polygon.
Definition qgis.h:298
@ RequiresProject
The algorithm requires that a valid QgsProject is available from the processing context in order to e...
Definition qgis.h:3813
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
Definition qgis.h:3982
A vector of attributes.
Represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
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:60
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition qgsfeedback.h:65
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:56
Container of fields for a vector layer.
Definition qgsfields.h:45
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Definition qgsfields.cpp:75
A geometry is the spatial representation of a feature.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
Layout graphical items for displaying a map.
Print layout, a QgsLayout subclass for static or atlas-based layouts.
virtual Qgis::ProcessingAlgorithmFlags flags() const
Returns the flags indicating how and when the algorithm operates and should be exposed to users.
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.
void featureAddedToSink(const QString &output)
Reports that a feature was added to the the sink associated with the specified algorithm output.
void featureSinkFinalized(const QString &output)
Reports that a feature sink has been finalized.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
A numeric output for processing algorithms.
A feature sink output for processing algorithms.
A print layout item parameter, allowing users to select a particular item from a print layout.
A print layout parameter, allowing users to select a print layout.