QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
qgsprojectviewsettings.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsprojectviewsettings.cpp
3 -----------------------------
4 begin : October 2019
5 copyright : (C) 2019 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17#include "moc_qgsprojectviewsettings.cpp"
18#include "qgis.h"
19#include "qgsproject.h"
20#include "qgsmaplayerutils.h"
22#include <QDomElement>
23
25 : QObject( project )
26 , mProject( project )
27{
28
29}
30
32{
33 mDefaultViewExtent = QgsReferencedRectangle();
34
35 mDefaultRotation = 0;
36
37 const bool fullExtentChanged = !mPresetFullExtent.isNull();
38 mPresetFullExtent = QgsReferencedRectangle();
39 if ( fullExtentChanged )
41
42 if ( mUseProjectScales || !mMapScales.empty() )
43 {
44 mUseProjectScales = false;
45 mMapScales.clear();
46 emit mapScalesChanged();
47 }
48}
49
51{
52 return mDefaultViewExtent;
53}
54
56{
57 mDefaultViewExtent = extent;
58}
59
61{
62 return mPresetFullExtent;
63}
64
66{
67 if ( extent == mPresetFullExtent )
68 return;
69
70 mPresetFullExtent = extent;
72}
73
75{
76 if ( !mProject )
77 return mPresetFullExtent;
78
79 if ( !mPresetFullExtent.isNull() )
80 {
81 QgsCoordinateTransform ct( mPresetFullExtent.crs(), mProject->crs(), mProject->transformContext() );
83 return QgsReferencedRectangle( ct.transformBoundingBox( mPresetFullExtent ), mProject->crs() );
84 }
85 else
86 {
87 const QList< QgsMapLayer * > layers = mProject->mapLayers( true ).values();
88
89 QList< QgsMapLayer * > nonBaseMapLayers;
90 std::copy_if( layers.begin(), layers.end(),
91 std::back_inserter( nonBaseMapLayers ),
92 []( const QgsMapLayer * layer ) { return !( layer->properties() & Qgis::MapLayerProperty::IsBasemapLayer ); } );
93
94 // unless ALL layers from the project are basemap layers, we exclude these by default as their extent won't be useful for the project.
95 if ( !nonBaseMapLayers.empty( ) )
96 return QgsReferencedRectangle( QgsMapLayerUtils::combinedExtent( nonBaseMapLayers, mProject->crs(), mProject->transformContext() ), mProject->crs() );
97 else
98 return QgsReferencedRectangle( QgsMapLayerUtils::combinedExtent( layers, mProject->crs(), mProject->transformContext() ), mProject->crs() );
99 }
100}
101
102void QgsProjectViewSettings::setMapScales( const QVector<double> &scales )
103{
104 // sort scales in descending order
105 QVector< double > sorted = scales;
106 std::sort( sorted.begin(), sorted.end(), std::greater<double>() );
107
108 if ( sorted == mapScales() )
109 return;
110
111 mMapScales = sorted;
112
113 emit mapScalesChanged();
114}
115
117{
118 return mMapScales;
119}
120
122{
123 if ( enabled == useProjectScales() )
124 return;
125
126 mUseProjectScales = enabled;
127 emit mapScalesChanged();
128}
129
131{
132 return mUseProjectScales;
133}
134
136{
137 return mDefaultRotation;
138}
139
141{
142 mDefaultRotation = rotation;
143}
144
145bool QgsProjectViewSettings::readXml( const QDomElement &element, const QgsReadWriteContext & )
146{
147 const bool useProjectScale = element.attribute( QStringLiteral( "UseProjectScales" ), QStringLiteral( "0" ) ).toInt();
148
149 QDomNodeList scalesNodes = element.elementsByTagName( QStringLiteral( "Scales" ) );
150 QVector< double > newScales;
151 if ( !scalesNodes.isEmpty() )
152 {
153 const QDomElement scalesElement = scalesNodes.at( 0 ).toElement();
154 scalesNodes = scalesElement.elementsByTagName( QStringLiteral( "Scale" ) );
155 for ( int i = 0; i < scalesNodes.count(); i++ )
156 {
157 const QDomElement scaleElement = scalesNodes.at( i ).toElement();
158 newScales.append( scaleElement.attribute( QStringLiteral( "Value" ) ).toDouble() );
159 }
160 }
161 if ( useProjectScale != mUseProjectScales || newScales != mMapScales )
162 {
163 mMapScales = newScales;
164 mUseProjectScales = useProjectScale;
165 emit mapScalesChanged();
166 }
167
168 const QDomElement defaultViewElement = element.firstChildElement( QStringLiteral( "DefaultViewExtent" ) );
169 if ( !defaultViewElement.isNull() )
170 {
171 const double xMin = defaultViewElement.attribute( QStringLiteral( "xmin" ) ).toDouble();
172 const double yMin = defaultViewElement.attribute( QStringLiteral( "ymin" ) ).toDouble();
173 const double xMax = defaultViewElement.attribute( QStringLiteral( "xmax" ) ).toDouble();
174 const double yMax = defaultViewElement.attribute( QStringLiteral( "ymax" ) ).toDouble();
176 crs.readXml( defaultViewElement );
177 mDefaultViewExtent = QgsReferencedRectangle( QgsRectangle( xMin, yMin, xMax, yMax ), crs );
178 }
179 else
180 {
181 mDefaultViewExtent = QgsReferencedRectangle();
182 }
183
184 const QDomElement presetViewElement = element.firstChildElement( QStringLiteral( "PresetFullExtent" ) );
185 if ( !presetViewElement.isNull() )
186 {
187 const double xMin = presetViewElement.attribute( QStringLiteral( "xmin" ) ).toDouble();
188 const double yMin = presetViewElement.attribute( QStringLiteral( "ymin" ) ).toDouble();
189 const double xMax = presetViewElement.attribute( QStringLiteral( "xmax" ) ).toDouble();
190 const double yMax = presetViewElement.attribute( QStringLiteral( "ymax" ) ).toDouble();
192 crs.readXml( presetViewElement );
193 setPresetFullExtent( QgsReferencedRectangle( QgsRectangle( xMin, yMin, xMax, yMax ), crs ) );
194 }
195 else
196 {
198 }
199
200 mDefaultRotation = element.attribute( QStringLiteral( "rotation" ), QStringLiteral( "0" ) ).toDouble();
201
202 return true;
203}
204
205QDomElement QgsProjectViewSettings::writeXml( QDomDocument &doc, const QgsReadWriteContext & ) const
206{
207 QDomElement element = doc.createElement( QStringLiteral( "ProjectViewSettings" ) );
208 element.setAttribute( QStringLiteral( "UseProjectScales" ), mUseProjectScales ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
209
210 element.setAttribute( QStringLiteral( "rotation" ), qgsDoubleToString( mDefaultRotation ) );
211
212 QDomElement scales = doc.createElement( QStringLiteral( "Scales" ) );
213 for ( const double scale : mMapScales )
214 {
215 QDomElement scaleElement = doc.createElement( QStringLiteral( "Scale" ) );
216 scaleElement.setAttribute( QStringLiteral( "Value" ), qgsDoubleToString( scale ) );
217 scales.appendChild( scaleElement );
218 }
219 element.appendChild( scales );
220
221 if ( !mDefaultViewExtent.isNull() )
222 {
223 QDomElement defaultViewElement = doc.createElement( QStringLiteral( "DefaultViewExtent" ) );
224 defaultViewElement.setAttribute( QStringLiteral( "xmin" ), qgsDoubleToString( mDefaultViewExtent.xMinimum() ) );
225 defaultViewElement.setAttribute( QStringLiteral( "ymin" ), qgsDoubleToString( mDefaultViewExtent.yMinimum() ) );
226 defaultViewElement.setAttribute( QStringLiteral( "xmax" ), qgsDoubleToString( mDefaultViewExtent.xMaximum() ) );
227 defaultViewElement.setAttribute( QStringLiteral( "ymax" ), qgsDoubleToString( mDefaultViewExtent.yMaximum() ) );
228 mDefaultViewExtent.crs().writeXml( defaultViewElement, doc );
229 element.appendChild( defaultViewElement );
230 }
231
232 if ( !mPresetFullExtent.isNull() )
233 {
234 QDomElement presetViewElement = doc.createElement( QStringLiteral( "PresetFullExtent" ) );
235 presetViewElement.setAttribute( QStringLiteral( "xmin" ), qgsDoubleToString( mPresetFullExtent.xMinimum() ) );
236 presetViewElement.setAttribute( QStringLiteral( "ymin" ), qgsDoubleToString( mPresetFullExtent.yMinimum() ) );
237 presetViewElement.setAttribute( QStringLiteral( "xmax" ), qgsDoubleToString( mPresetFullExtent.xMaximum() ) );
238 presetViewElement.setAttribute( QStringLiteral( "ymax" ), qgsDoubleToString( mPresetFullExtent.yMaximum() ) );
239 mPresetFullExtent.crs().writeXml( presetViewElement, doc );
240 element.appendChild( presetViewElement );
241 }
242
243 return element;
244}
This class represents a coordinate reference system (CRS).
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
Class for doing transforms between two map coordinate systems.
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool handle180Crossover=false) const
Transforms a rectangle from the source CRS to the destination CRS.
static QgsRectangle combinedExtent(const QList< QgsMapLayer * > &layers, const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &transformContext)
Returns the combined extent of a list of layers.
Base class for all map layer types.
Definition qgsmaplayer.h:76
double defaultRotation() const
Returns the default map rotation (in clockwise degrees) for maps in the project.
QgsReferencedRectangle defaultViewExtent() const
Returns the default view extent, which should be used as the initial map extent when this project is ...
bool useProjectScales() const
Returns true if project mapScales() are enabled.
QgsReferencedRectangle presetFullExtent() const
Returns the project's preset full extent.
void setPresetFullExtent(const QgsReferencedRectangle &extent)
Sets the project's preset full extent.
void reset()
Resets the settings to a default state.
void presetFullExtentChanged()
Emitted whenever the presetFullExtent() is changed.
void setDefaultViewExtent(const QgsReferencedRectangle &extent)
Sets the default view extent, which should be used as the initial map extent when this project is ope...
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void setDefaultRotation(double rotation)
Set the default rotation of maps in the project, in clockwise degrees.
void setMapScales(const QVector< double > &scales)
Sets the list of custom project map scales.
void setUseProjectScales(bool enabled)
Sets whether project mapScales() are enabled.
QVector< double > mapScales() const
Returns the list of custom project map scales.
QgsProjectViewSettings(QgsProject *project=nullptr)
Constructor for QgsProjectViewSettings for the specified project.
void mapScalesChanged()
Emitted when the list of custom project map scales changes.
QgsReferencedRectangle fullExtent() const
Returns the full extent of the project, which represents the maximal limits of the project.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:107
QgsCoordinateTransformContext transformContext
Definition qgsproject.h:113
QgsCoordinateReferenceSystem crs
Definition qgsproject.h:112
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
double xMinimum
double yMinimum
double xMaximum
double yMaximum
QgsCoordinateReferenceSystem crs() const
Returns the associated coordinate reference system, or an invalid CRS if no reference system is set.
A QgsRectangle with associated coordinate reference system.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition qgis.h:5983
const QgsCoordinateReferenceSystem & crs