QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsmapsettingsutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmapsettingsutils.cpp
3  -------------------
4  begin : May 2017
5  copyright : (C) 2017 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 
18 #include "qgsmapsettings.h"
19 #include "qgsmapsettingsutils.h"
20 #include "qgspallabeling.h"
21 #include "qgstextformat.h"
22 #include "qgsvectorlayer.h"
24 
25 #include <QString>
26 
27 QStringList QgsMapSettingsUtils::containsAdvancedEffects( const QgsMapSettings &mapSettings, EffectsCheckFlags flags )
28 {
29  QSet< QString > layers;
30 
31  QgsTextFormat layerFormat;
32  const auto constLayers = mapSettings.layers();
33  for ( QgsMapLayer *layer : constLayers )
34  {
35  if ( layer && layer->isInScaleRange( mapSettings.scale() ) )
36  {
37  bool layerHasAdvancedBlendMode = false;
38  if ( layer->blendMode() != QPainter::CompositionMode_SourceOver )
39  {
41  {
42  layerHasAdvancedBlendMode = !QgsAbstractGeoPdfExporter::compositionModeSupported( layer->blendMode() );
43  }
44  else
45  {
46  layerHasAdvancedBlendMode = true;
47  }
48  }
49 
50  if ( layerHasAdvancedBlendMode )
51  {
52  layers << layer->name();
53  }
54  // if vector layer, check labels and feature blend mode
55  QgsVectorLayer *currentVectorLayer = qobject_cast<QgsVectorLayer *>( layer );
56  if ( currentVectorLayer )
57  {
58  if ( !qgsDoubleNear( currentVectorLayer->opacity(), 1.0 ) && !( flags & EffectsCheckFlag::IgnoreGeoPdfSupportedEffects ) )
59  {
60  layers << layer->name();
61  }
62  if ( currentVectorLayer->featureBlendMode() != QPainter::CompositionMode_SourceOver )
63  {
64  layers << layer->name();
65  }
66  // check label blend modes
67  if ( QgsPalLabeling::staticWillUseLayer( currentVectorLayer ) )
68  {
69  // Check all label blending properties
70  layerFormat.readFromLayer( currentVectorLayer );
71  if ( layerFormat.containsAdvancedEffects() )
72  {
73  layers << layer->name();
74  }
75  }
76  }
77  }
78  }
79 
80  return qgis::setToList( layers );
81 }
82 
83 void QgsMapSettingsUtils::worldFileParameters( const QgsMapSettings &mapSettings, double &a, double &b, double &c, double &d, double &e, double &f )
84 {
85  QgsMapSettings ms = mapSettings;
86 
87  double rotation = ms.rotation();
88  double alpha = rotation / 180 * M_PI;
89 
90  // reset rotation to 0 to calculate world file parameters
91  ms.setRotation( 0 );
92 
93  double xOrigin = ms.visibleExtent().xMinimum() + ( ms.mapUnitsPerPixel() / 2 );
94  double yOrigin = ms.visibleExtent().yMaximum() - ( ms.mapUnitsPerPixel() / 2 );
95 
96  double xCenter = ms.visibleExtent().center().x();
97  double yCenter = ms.visibleExtent().center().y();
98 
99  // scaling matrix
100  double s[6];
101  s[0] = ms.mapUnitsPerPixel();
102  s[1] = 0;
103  s[2] = xOrigin;
104  s[3] = 0;
105  s[4] = -ms.mapUnitsPerPixel();
106  s[5] = yOrigin;
107 
108  // rotation matrix
109  double r[6];
110  r[0] = std::cos( alpha );
111  r[1] = -std::sin( alpha );
112  r[2] = xCenter * ( 1 - std::cos( alpha ) ) + yCenter * std::sin( alpha );
113  r[3] = std::sin( alpha );
114  r[4] = std::cos( alpha );
115  r[5] = - xCenter * std::sin( alpha ) + yCenter * ( 1 - std::cos( alpha ) );
116 
117  // result = rotation x scaling = rotation(scaling(X))
118  a = r[0] * s[0] + r[1] * s[3];
119  b = r[0] * s[1] + r[1] * s[4];
120  c = r[0] * s[2] + r[1] * s[5] + r[2];
121  d = r[3] * s[0] + r[4] * s[3];
122  // Pixel YDim - almost always negative
123  // See https://en.wikipedia.org/wiki/World_file#cite_ref-3, https://github.com/qgis/QGIS/issues/26379
124  e = r[3] * s[1] + r[4] * s[4];
125  f = r[3] * s[2] + r[4] * s[5] + r[5];
126 }
127 
129 {
130  double a, b, c, d, e, f;
131  worldFileParameters( mapSettings, a, b, c, d, e, f );
132 
133  QString content;
134  // Pixel XDim
135  content += qgsDoubleToString( a ) + "\r\n";
136  // Rotation on y axis
137  content += qgsDoubleToString( d ) + "\r\n";
138  // Rotation on x axis
139  content += qgsDoubleToString( b ) + "\r\n";
140  // Pixel YDim
141  content += qgsDoubleToString( e ) + "\r\n";
142  // Origin X (top left cell)
143  content += qgsDoubleToString( c ) + "\r\n";
144  // Origin Y (top left cell)
145  content += qgsDoubleToString( f ) + "\r\n";
146 
147  return content;
148 }
QgsVectorLayer::featureBlendMode
QPainter::CompositionMode featureBlendMode() const
Returns the current blending mode for features.
Definition: qgsvectorlayer.cpp:4319
QgsPointXY::y
double y
Definition: qgspointxy.h:48
qgspallabeling.h
QgsMapSettings::setRotation
void setRotation(double rotation)
Sets the rotation of the resulting map image, in degrees clockwise.
Definition: qgsmapsettings.cpp:106
QgsMapSettings::mapUnitsPerPixel
double mapUnitsPerPixel() const
Returns the distance in geographical coordinates that equals to one pixel in the map.
Definition: qgsmapsettings.cpp:390
qgsmapsettings.h
QgsPalLabeling::staticWillUseLayer
static bool staticWillUseLayer(QgsVectorLayer *layer)
called to find out whether the layer is used for labeling
Definition: qgspallabeling.cpp:3536
qgsDoubleToString
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:275
QgsTextFormat
Definition: qgstextformat.h:38
QgsMapSettings::rotation
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
Definition: qgsmapsettings.cpp:101
qgsmapsettingsutils.h
QgsMapSettingsUtils::EffectsCheckFlag::IgnoreGeoPdfSupportedEffects
@ IgnoreGeoPdfSupportedEffects
Ignore advanced effects which are supported in GeoPDF exports.
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:315
QgsMapSettingsUtils::containsAdvancedEffects
static QStringList containsAdvancedEffects(const QgsMapSettings &mapSettings, EffectsCheckFlags flags=QgsMapSettingsUtils::EffectsCheckFlags())
Checks whether any of the layers attached to a map settings object contain advanced effects.
Definition: qgsmapsettingsutils.cpp:27
QgsMapSettings::scale
double scale() const
Returns the calculated map scale.
Definition: qgsmapsettings.cpp:395
QgsMapSettingsUtils::worldFileContent
static QString worldFileContent(const QgsMapSettings &mapSettings)
Creates the content of a world file.
Definition: qgsmapsettingsutils.cpp:128
QgsRectangle::yMaximum
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
qgsvectorlayer.h
QgsMapSettingsUtils::worldFileParameters
static void worldFileParameters(const QgsMapSettings &mapSettings, double &a, double &b, double &c, double &d, double &e, double &f)
Computes the six parameters of a world file.
Definition: qgsmapsettingsutils.cpp:83
QgsTextFormat::readFromLayer
void readFromLayer(QgsVectorLayer *layer)
Reads settings from a layer's custom properties (for QGIS 2.x projects).
Definition: qgstextformat.cpp:196
QgsRectangle::center
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:230
c
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
Definition: porting_processing.dox:1
QgsVectorLayer
Definition: qgsvectorlayer.h:385
QgsMapLayer
Definition: qgsmaplayer.h:81
qgsabstractgeopdfexporter.h
QgsPointXY::x
double x
Definition: qgspointxy.h:47
QgsMapSettings::layers
QList< QgsMapLayer * > layers() const
Gets list of layers for map rendering The layers are stored in the reverse order of how they are rend...
Definition: qgsmapsettings.cpp:281
QgsVectorLayer::opacity
double opacity
Definition: qgsvectorlayer.h:394
qgstextformat.h
QgsMapSettings
Definition: qgsmapsettings.h:86
QgsMapSettings::visibleExtent
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
Definition: qgsmapsettings.cpp:370
QgsRectangle::xMinimum
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
QgsTextFormat::containsAdvancedEffects
bool containsAdvancedEffects() const
Returns true if any component of the font format requires advanced effects such as blend modes,...
Definition: qgstextformat.cpp:552
QgsAbstractGeoPdfExporter::compositionModeSupported
static bool compositionModeSupported(QPainter::CompositionMode mode)
Returns true if the specified composition mode is supported for layers during GeoPDF exports.
Definition: qgsabstractgeopdfexporter.cpp:139