QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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  if ( QgsVectorLayer *currentVectorLayer = qobject_cast<QgsVectorLayer *>( layer ) )
56  {
57 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
58  // Qt < 5.15 does not correctly support layer level opacity in PDF exports -- see https://github.com/qgis/QGIS/issues/42698
59  if ( !qgsDoubleNear( currentVectorLayer->opacity(), 1.0 ) && !( flags & EffectsCheckFlag::IgnoreGeoPdfSupportedEffects ) )
60  {
61  layers << layer->name();
62  }
63 #endif
64  if ( currentVectorLayer->featureBlendMode() != QPainter::CompositionMode_SourceOver )
65  {
66  layers << layer->name();
67  }
68  // check label blend modes
69  if ( QgsPalLabeling::staticWillUseLayer( currentVectorLayer ) )
70  {
71  // Check all label blending properties
72  layerFormat.readFromLayer( currentVectorLayer );
73  if ( layerFormat.containsAdvancedEffects() )
74  {
75  layers << layer->name();
76  }
77  }
78  }
79  }
80  }
81 
82  return qgis::setToList( layers );
83 }
84 
85 void QgsMapSettingsUtils::worldFileParameters( const QgsMapSettings &mapSettings, double &a, double &b, double &c, double &d, double &e, double &f )
86 {
87  QgsMapSettings ms = mapSettings;
88 
89  const double rotation = ms.rotation();
90  const double alpha = rotation / 180 * M_PI;
91 
92  // reset rotation to 0 to calculate world file parameters
93  ms.setRotation( 0 );
94 
95  const double xOrigin = ms.visibleExtent().xMinimum() + ( ms.mapUnitsPerPixel() / 2 );
96  const double yOrigin = ms.visibleExtent().yMaximum() - ( ms.mapUnitsPerPixel() / 2 );
97 
98  const double xCenter = ms.visibleExtent().center().x();
99  const double yCenter = ms.visibleExtent().center().y();
100 
101  // scaling matrix
102  double s[6];
103  s[0] = ms.mapUnitsPerPixel();
104  s[1] = 0;
105  s[2] = xOrigin;
106  s[3] = 0;
107  s[4] = -ms.mapUnitsPerPixel();
108  s[5] = yOrigin;
109 
110  // rotation matrix
111  double r[6];
112  r[0] = std::cos( alpha );
113  r[1] = -std::sin( alpha );
114  r[2] = xCenter * ( 1 - std::cos( alpha ) ) + yCenter * std::sin( alpha );
115  r[3] = std::sin( alpha );
116  r[4] = std::cos( alpha );
117  r[5] = - xCenter * std::sin( alpha ) + yCenter * ( 1 - std::cos( alpha ) );
118 
119  // result = rotation x scaling = rotation(scaling(X))
120  a = r[0] * s[0] + r[1] * s[3];
121  b = r[0] * s[1] + r[1] * s[4];
122  c = r[0] * s[2] + r[1] * s[5] + r[2];
123  d = r[3] * s[0] + r[4] * s[3];
124  // Pixel YDim - almost always negative
125  // See https://en.wikipedia.org/wiki/World_file#cite_ref-3, https://github.com/qgis/QGIS/issues/26379
126  e = r[3] * s[1] + r[4] * s[4];
127  f = r[3] * s[2] + r[4] * s[5] + r[5];
128 }
129 
131 {
132  double a, b, c, d, e, f;
133  worldFileParameters( mapSettings, a, b, c, d, e, f );
134 
135  QString content;
136  // Pixel XDim
137  content += qgsDoubleToString( a ) + "\r\n";
138  // Rotation on y axis
139  content += qgsDoubleToString( d ) + "\r\n";
140  // Rotation on x axis
141  content += qgsDoubleToString( b ) + "\r\n";
142  // Pixel YDim
143  content += qgsDoubleToString( e ) + "\r\n";
144  // Origin X (top left cell)
145  content += qgsDoubleToString( c ) + "\r\n";
146  // Origin Y (top left cell)
147  content += qgsDoubleToString( f ) + "\r\n";
148 
149  return content;
150 }
QgsPointXY::y
double y
Definition: qgspointxy.h:63
qgspallabeling.h
QgsPalLabeling::staticWillUseLayer
static bool staticWillUseLayer(const QgsMapLayer *layer)
Called to find out whether a specified layer is used for labeling.
Definition: qgspallabeling.cpp:3796
QgsMapSettings::setRotation
void setRotation(double rotation)
Sets the rotation of the resulting map image, in degrees clockwise.
Definition: qgsmapsettings.cpp:107
QgsRectangle::center
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Definition: qgsrectangle.h:251
QgsMapSettings::mapUnitsPerPixel
double mapUnitsPerPixel() const
Returns the distance in geographical coordinates that equals to one pixel in the map.
Definition: qgsmapsettings.cpp:453
qgsmapsettings.h
qgsDoubleToString
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:2204
QgsTextFormat
Container for all settings relating to text rendering.
Definition: qgstextformat.h:40
QgsMapSettings::rotation
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
Definition: qgsmapsettings.cpp:102
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:2265
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:458
QgsRectangle::xMinimum
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
QgsMapSettingsUtils::worldFileContent
static QString worldFileContent(const QgsMapSettings &mapSettings)
Creates the content of a world file.
Definition: qgsmapsettingsutils.cpp:130
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:85
QgsTextFormat::readFromLayer
void readFromLayer(QgsVectorLayer *layer)
Reads settings from a layer's custom properties (for QGIS 2.x projects).
Definition: qgstextformat.cpp:404
QgsRectangle::yMaximum
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
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
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
qgsabstractgeopdfexporter.h
QgsPointXY::x
double x
Definition: qgspointxy.h:62
qgstextformat.h
QgsMapSettings
The QgsMapSettings class contains configuration for rendering of the map. The rendering itself is don...
Definition: qgsmapsettings.h:88
QgsMapSettings::visibleExtent
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
Definition: qgsmapsettings.cpp:411
QgsMapSettings::layers
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
Definition: qgsmapsettings.cpp:299
QgsTextFormat::containsAdvancedEffects
bool containsAdvancedEffects() const
Returns true if any component of the font format requires advanced effects such as blend modes,...
Definition: qgstextformat.cpp:817
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:129