QGIS API Documentation 3.29.0-Master (19d7edcfed)
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
21#include "layout/qgslayout.h"
24
26
27QString QgsLayoutMapExtentToLayerAlgorithm::name() const
28{
29 return QStringLiteral( "printlayoutmapextenttolayer" );
30}
31
32QString QgsLayoutMapExtentToLayerAlgorithm::displayName() const
33{
34 return QObject::tr( "Print layout map extent to layer" );
35}
36
37QStringList QgsLayoutMapExtentToLayerAlgorithm::tags() const
38{
39 return QObject::tr( "layout,composer,composition,visible" ).split( ',' );
40}
41
42QString QgsLayoutMapExtentToLayerAlgorithm::group() const
43{
44 return QObject::tr( "Cartography" );
45}
46
47QString QgsLayoutMapExtentToLayerAlgorithm::groupId() const
48{
49 return QStringLiteral( "cartography" );
50}
51
52QString QgsLayoutMapExtentToLayerAlgorithm::shortDescription() const
53{
54 return QObject::tr( "Creates a polygon layer containing the extent of a print layout map item." );
55}
56
57void QgsLayoutMapExtentToLayerAlgorithm::initAlgorithm( const QVariantMap & )
58{
59 addParameter( new QgsProcessingParameterLayout( QStringLiteral( "LAYOUT" ), QObject::tr( "Print layout" ) ) );
60 addParameter( new QgsProcessingParameterLayoutItem( QStringLiteral( "MAP" ), QObject::tr( "Map item" ), QVariant(), QStringLiteral( "LAYOUT" ), QgsLayoutItemRegistry::LayoutMap, true ) );
61 auto crsParam = std::make_unique< QgsProcessingParameterCrs >( QStringLiteral( "CRS" ), QObject::tr( "Override CRS" ), QVariant(), true );
62 crsParam->setFlags( crsParam->flags() | QgsProcessingParameterDefinition::FlagAdvanced );
63 addParameter( crsParam.release() );
64 addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Extent" ), QgsProcessing::TypeVectorPolygon ) );
65 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "WIDTH" ), QObject::tr( "Map width" ) ) );
66 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "HEIGHT" ), QObject::tr( "Map height" ) ) );
67 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "SCALE" ), QObject::tr( "Map scale" ) ) );
68 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "ROTATION" ), QObject::tr( "Map rotation" ) ) );
69}
70
71QgsProcessingAlgorithm::Flags QgsLayoutMapExtentToLayerAlgorithm::flags() const
72{
73 return QgsProcessingAlgorithm::flags() | FlagRequiresProject;
74}
75
76QString QgsLayoutMapExtentToLayerAlgorithm::shortHelpString() const
77{
78 return QObject::tr( "This algorithm creates a polygon layer containing the extent of a print layout map item (or items), "
79 "with attributes specifying the map size (in layout units), scale and rotation.\n\n"
80 "If the map item parameter is specified, then only the matching map extent will be exported. If it "
81 "is not specified, all map extents from the layout will be exported.\n\n"
82 "Optionally, a specific output CRS can be specified. If it is not specified, the original map "
83 "item CRS will be used." );
84}
85
86QgsLayoutMapExtentToLayerAlgorithm *QgsLayoutMapExtentToLayerAlgorithm::createInstance() const
87{
88 return new QgsLayoutMapExtentToLayerAlgorithm();
89}
90
91bool QgsLayoutMapExtentToLayerAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
92{
93 // this needs to be done in main thread, layouts are not thread safe
94 QgsPrintLayout *layout = parameterAsLayout( parameters, QStringLiteral( "LAYOUT" ), context );
95 if ( !layout )
96 throw QgsProcessingException( QObject::tr( "Cannot find layout with name \"%1\"" ).arg( parameters.value( QStringLiteral( "LAYOUT" ) ).toString() ) );
97
98 QgsLayoutItemMap *map = qobject_cast< QgsLayoutItemMap * >( parameterAsLayoutItem( parameters, QStringLiteral( "MAP" ), context, layout ) );
99 if ( !map && parameters.value( QStringLiteral( "MAP" ) ).isValid() )
100 throw QgsProcessingException( QObject::tr( "Cannot find matching map item with ID %1" ).arg( parameters.value( QStringLiteral( "MAP" ) ).toString() ) );
101
102 QList< QgsLayoutItemMap *> maps;
103 if ( map )
104 maps << map;
105 else
106 layout->layoutItems( maps );
107
108 const QgsCoordinateReferenceSystem overrideCrs = parameterAsCrs( parameters, QStringLiteral( "CRS" ), context );
109
110 mFeatures.reserve( maps.size() );
111 for ( QgsLayoutItemMap *map : maps )
112 {
113 if ( !mCrs.isValid() )
114 mCrs = !overrideCrs.isValid() ? map->crs() : overrideCrs;
115
116 QgsGeometry extent = QgsGeometry::fromQPolygonF( map->visibleExtentPolygon() );
117 if ( map->crs() != mCrs )
118 {
119 try
120 {
121 extent.transform( QgsCoordinateTransform( map->crs(), mCrs, context.transformContext() ) );
122 }
123 catch ( QgsCsException & )
124 {
125 feedback->reportError( QObject::tr( "Error reprojecting map to destination CRS" ) );
126 continue;
127 }
128 }
129
130 mWidth = map->rect().width();
131 mHeight = map->rect().height();
132 mScale = map->scale();
133 mRotation = map->mapRotation();
134
135 QgsFeature f;
136 f.setAttributes( QgsAttributes() << map->displayName() << mWidth << mHeight << mScale << mRotation );
137 f.setGeometry( extent );
138
139 mFeatures << f;
140 }
141 return true;
142}
143
144QVariantMap QgsLayoutMapExtentToLayerAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
145{
146 QgsFields fields;
147 fields.append( QgsField( QStringLiteral( "map" ), QVariant::String ) );
148 fields.append( QgsField( QStringLiteral( "width" ), QVariant::Double ) );
149 fields.append( QgsField( QStringLiteral( "height" ), QVariant::Double ) );
150 fields.append( QgsField( QStringLiteral( "scale" ), QVariant::Double ) );
151 fields.append( QgsField( QStringLiteral( "rotation" ), QVariant::Double ) );
152
153 QString dest;
154 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, QgsWkbTypes::Polygon, mCrs ) );
155 if ( !sink )
156 throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
157
158 for ( QgsFeature &f : mFeatures )
159 {
160 if ( !sink->addFeature( f, QgsFeatureSink::FastInsert ) )
161 throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
162 }
163
164 feedback->setProgress( 100 );
165
166 QVariantMap outputs;
167 outputs.insert( QStringLiteral( "OUTPUT" ), dest );
168 // these numeric outputs only have value for single-map layouts
169 outputs.insert( QStringLiteral( "WIDTH" ), mFeatures.size() == 1 ? mWidth : QVariant() );
170 outputs.insert( QStringLiteral( "HEIGHT" ), mFeatures.size() == 1 ? mHeight : QVariant() );
171 outputs.insert( QStringLiteral( "SCALE" ), mFeatures.size() == 1 ? mScale : QVariant() );
172 outputs.insert( QStringLiteral( "ROTATION" ), mFeatures.size() == 1 ? mRotation : QVariant() );
173 return outputs;
174}
175
177
A vector of attributes.
Definition: qgsattributes.h:59
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Class for doing transforms between two map coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
@ 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:56
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:160
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:170
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:63
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:51
Container of fields for a vector layer.
Definition: qgsfields.h:45
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition: qgsfields.cpp:59
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:164
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
static QgsGeometry fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
Layout graphical items for displaying a map.
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
Definition: qgslayout.h:122
Print layout, a QgsLayout subclass for static or atlas-based layouts.
virtual Flags 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.
Definition: qgsexception.h:83
Base class for providing feedback from a processing algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
A numeric output for processing algorithms.
@ FlagAdvanced
Parameter is an advanced parameter which should be hidden from users by default.
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.
@ TypeVectorPolygon
Vector polygon layers.
Definition: qgsprocessing.h:51