QGIS API Documentation  3.20.0-Odense (decaadbb31)
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 
16 #include "qgsprojectviewsettings.h"
17 #include "qgis.h"
18 #include "qgsproject.h"
19 #include "qgslogger.h"
20 #include "qgsmaplayerutils.h"
21 #include <QDomElement>
22 
24  : QObject( project )
25  , mProject( project )
26 {
27 
28 }
29 
31 {
32  mDefaultViewExtent = QgsReferencedRectangle();
33 
34  const bool fullExtentChanged = !mPresetFullExtent.isNull();
35  mPresetFullExtent = QgsReferencedRectangle();
36  if ( fullExtentChanged )
38 
39  if ( mUseProjectScales || !mMapScales.empty() )
40  {
41  mUseProjectScales = false;
42  mMapScales.clear();
43  emit mapScalesChanged();
44  }
45 }
46 
48 {
49  return mDefaultViewExtent;
50 }
51 
53 {
54  mDefaultViewExtent = extent;
55 }
56 
58 {
59  return mPresetFullExtent;
60 }
61 
63 {
64  if ( extent == mPresetFullExtent )
65  return;
66 
67  mPresetFullExtent = extent;
69 }
70 
72 {
73  if ( !mProject )
74  return mPresetFullExtent;
75 
76  if ( !mPresetFullExtent.isNull() )
77  {
78  QgsCoordinateTransform ct( mPresetFullExtent.crs(), mProject->crs(), mProject->transformContext() );
80  return QgsReferencedRectangle( ct.transformBoundingBox( mPresetFullExtent ), mProject->crs() );
81  }
82  else
83  {
84  const QList< QgsMapLayer * > layers = mProject->mapLayers( true ).values();
85  return QgsReferencedRectangle( QgsMapLayerUtils::combinedExtent( layers, mProject->crs(), mProject->transformContext() ), mProject->crs() );
86  }
87 }
88 
89 void QgsProjectViewSettings::setMapScales( const QVector<double> &scales )
90 {
91  // sort scales in descending order
92  QVector< double > sorted = scales;
93  std::sort( sorted.begin(), sorted.end(), std::greater<double>() );
94 
95  if ( sorted == mapScales() )
96  return;
97 
98  mMapScales = sorted;
99 
100  emit mapScalesChanged();
101 }
102 
103 QVector<double> QgsProjectViewSettings::mapScales() const
104 {
105  return mMapScales;
106 }
107 
109 {
110  if ( enabled == useProjectScales() )
111  return;
112 
113  mUseProjectScales = enabled;
114  emit mapScalesChanged();
115 }
116 
118 {
119  return mUseProjectScales;
120 }
121 
122 bool QgsProjectViewSettings::readXml( const QDomElement &element, const QgsReadWriteContext & )
123 {
124  bool useProjectScale = element.attribute( QStringLiteral( "UseProjectScales" ), QStringLiteral( "0" ) ).toInt();
125 
126  QDomNodeList scalesNodes = element.elementsByTagName( QStringLiteral( "Scales" ) );
127  QVector< double > newScales;
128  if ( !scalesNodes.isEmpty() )
129  {
130  QDomElement scalesElement = scalesNodes.at( 0 ).toElement();
131  scalesNodes = scalesElement.elementsByTagName( QStringLiteral( "Scale" ) );
132  for ( int i = 0; i < scalesNodes.count(); i++ )
133  {
134  QDomElement scaleElement = scalesNodes.at( i ).toElement();
135  newScales.append( scaleElement.attribute( QStringLiteral( "Value" ) ).toDouble() );
136  }
137  }
138  if ( useProjectScale != mUseProjectScales || newScales != mMapScales )
139  {
140  mMapScales = newScales;
141  mUseProjectScales = useProjectScale;
142  emit mapScalesChanged();
143  }
144 
145  QDomElement defaultViewElement = element.firstChildElement( QStringLiteral( "DefaultViewExtent" ) );
146  if ( !defaultViewElement.isNull() )
147  {
148  double xMin = defaultViewElement.attribute( QStringLiteral( "xmin" ) ).toDouble();
149  double yMin = defaultViewElement.attribute( QStringLiteral( "ymin" ) ).toDouble();
150  double xMax = defaultViewElement.attribute( QStringLiteral( "xmax" ) ).toDouble();
151  double yMax = defaultViewElement.attribute( QStringLiteral( "ymax" ) ).toDouble();
153  crs.readXml( defaultViewElement );
154  mDefaultViewExtent = QgsReferencedRectangle( QgsRectangle( xMin, yMin, xMax, yMax ), crs );
155  }
156  else
157  {
158  mDefaultViewExtent = QgsReferencedRectangle();
159  }
160 
161  QDomElement presetViewElement = element.firstChildElement( QStringLiteral( "PresetFullExtent" ) );
162  if ( !presetViewElement.isNull() )
163  {
164  double xMin = presetViewElement.attribute( QStringLiteral( "xmin" ) ).toDouble();
165  double yMin = presetViewElement.attribute( QStringLiteral( "ymin" ) ).toDouble();
166  double xMax = presetViewElement.attribute( QStringLiteral( "xmax" ) ).toDouble();
167  double yMax = presetViewElement.attribute( QStringLiteral( "ymax" ) ).toDouble();
169  crs.readXml( presetViewElement );
170  setPresetFullExtent( QgsReferencedRectangle( QgsRectangle( xMin, yMin, xMax, yMax ), crs ) );
171  }
172  else
173  {
175  }
176 
177  return true;
178 }
179 
180 QDomElement QgsProjectViewSettings::writeXml( QDomDocument &doc, const QgsReadWriteContext & ) const
181 {
182  QDomElement element = doc.createElement( QStringLiteral( "ProjectViewSettings" ) );
183  element.setAttribute( QStringLiteral( "UseProjectScales" ), mUseProjectScales ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
184 
185  QDomElement scales = doc.createElement( QStringLiteral( "Scales" ) );
186  for ( double scale : mMapScales )
187  {
188  QDomElement scaleElement = doc.createElement( QStringLiteral( "Scale" ) );
189  scaleElement.setAttribute( QStringLiteral( "Value" ), qgsDoubleToString( scale ) );
190  scales.appendChild( scaleElement );
191  }
192  element.appendChild( scales );
193 
194  if ( !mDefaultViewExtent.isNull() )
195  {
196  QDomElement defaultViewElement = doc.createElement( QStringLiteral( "DefaultViewExtent" ) );
197  defaultViewElement.setAttribute( QStringLiteral( "xmin" ), qgsDoubleToString( mDefaultViewExtent.xMinimum() ) );
198  defaultViewElement.setAttribute( QStringLiteral( "ymin" ), qgsDoubleToString( mDefaultViewExtent.yMinimum() ) );
199  defaultViewElement.setAttribute( QStringLiteral( "xmax" ), qgsDoubleToString( mDefaultViewExtent.xMaximum() ) );
200  defaultViewElement.setAttribute( QStringLiteral( "ymax" ), qgsDoubleToString( mDefaultViewExtent.yMaximum() ) );
201  mDefaultViewExtent.crs().writeXml( defaultViewElement, doc );
202  element.appendChild( defaultViewElement );
203  }
204 
205  if ( !mPresetFullExtent.isNull() )
206  {
207  QDomElement presetViewElement = doc.createElement( QStringLiteral( "PresetFullExtent" ) );
208  presetViewElement.setAttribute( QStringLiteral( "xmin" ), qgsDoubleToString( mPresetFullExtent.xMinimum() ) );
209  presetViewElement.setAttribute( QStringLiteral( "ymin" ), qgsDoubleToString( mPresetFullExtent.yMinimum() ) );
210  presetViewElement.setAttribute( QStringLiteral( "xmax" ), qgsDoubleToString( mPresetFullExtent.xMaximum() ) );
211  presetViewElement.setAttribute( QStringLiteral( "ymax" ), qgsDoubleToString( mPresetFullExtent.yMaximum() ) );
212  mPresetFullExtent.crs().writeXml( presetViewElement, doc );
213  element.appendChild( presetViewElement );
214  }
215 
216  return element;
217 }
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, TransformDirection direction=ForwardTransform, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
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.
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 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:99
QgsCoordinateTransformContext transformContext
Definition: qgsproject.h:105
QgsCoordinateReferenceSystem crs
Definition: qgsproject.h:104
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.
Definition: qgsrectangle.h:42
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:479
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:550
const QgsCoordinateReferenceSystem & crs