QGIS API Documentation  3.6.0-Noosa (5873452)
qgsrendercontext.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrendercontext.cpp
3  --------------------
4  begin : March 16, 2008
5  copyright : (C) 2008 by Marco Hugentobler
6  email : marco dot hugentobler at karto dot baug dot ethz dot ch
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 
19 #include "qgsrendercontext.h"
20 
21 #include "qgsmapsettings.h"
22 #include "qgsexpression.h"
23 #include "qgsvectorlayer.h"
25 #include "qgslogger.h"
26 #include "qgspoint.h"
27 
28 #define POINTS_TO_MM 2.83464567
29 #define INCH_TO_MM 25.4
30 
32  : mFlags( DrawEditingInfo | UseAdvancedEffects | DrawSelection | UseRenderingOptimization )
33 {
35  // For RenderMetersInMapUnits support, when rendering in Degrees, the Ellipsoid must be set
36  // - for Previews/Icons the default Extent can be used
37  mDistanceArea.setEllipsoid( mDistanceArea.sourceCrs().ellipsoidAcronym() );
38 }
39 
41  : mFlags( rh.mFlags )
42  , mPainter( rh.mPainter )
43  , mCoordTransform( rh.mCoordTransform )
44  , mDistanceArea( rh.mDistanceArea )
45  , mExtent( rh.mExtent )
46  , mMapToPixel( rh.mMapToPixel )
47  , mRenderingStopped( rh.mRenderingStopped )
48  , mScaleFactor( rh.mScaleFactor )
49  , mRendererScale( rh.mRendererScale )
50  , mLabelingEngine( rh.mLabelingEngine )
51  , mSelectionColor( rh.mSelectionColor )
52  , mVectorSimplifyMethod( rh.mVectorSimplifyMethod )
53  , mExpressionContext( rh.mExpressionContext )
54  , mGeometry( rh.mGeometry )
55  , mFeatureFilterProvider( rh.mFeatureFilterProvider ? rh.mFeatureFilterProvider->clone() : nullptr )
56  , mSegmentationTolerance( rh.mSegmentationTolerance )
57  , mSegmentationToleranceType( rh.mSegmentationToleranceType )
58  , mTransformContext( rh.mTransformContext )
59  , mPathResolver( rh.mPathResolver )
60  , mTextRenderFormat( rh.mTextRenderFormat )
61 #ifdef QGISDEBUG
62  , mHasTransformContext( rh.mHasTransformContext )
63 #endif
64 {
65 }
66 
68 {
69  mFlags = rh.mFlags;
70  mPainter = rh.mPainter;
71  mCoordTransform = rh.mCoordTransform;
72  mExtent = rh.mExtent;
73  mMapToPixel = rh.mMapToPixel;
74  mRenderingStopped = rh.mRenderingStopped;
75  mScaleFactor = rh.mScaleFactor;
76  mRendererScale = rh.mRendererScale;
77  mLabelingEngine = rh.mLabelingEngine;
78  mSelectionColor = rh.mSelectionColor;
79  mVectorSimplifyMethod = rh.mVectorSimplifyMethod;
80  mExpressionContext = rh.mExpressionContext;
81  mGeometry = rh.mGeometry;
82  mFeatureFilterProvider.reset( rh.mFeatureFilterProvider ? rh.mFeatureFilterProvider->clone() : nullptr );
83  mSegmentationTolerance = rh.mSegmentationTolerance;
84  mSegmentationToleranceType = rh.mSegmentationToleranceType;
85  mDistanceArea = rh.mDistanceArea;
86  mTransformContext = rh.mTransformContext;
87  mPathResolver = rh.mPathResolver;
88  mTextRenderFormat = rh.mTextRenderFormat;
89 #ifdef QGISDEBUG
90  mHasTransformContext = rh.mHasTransformContext;
91 #endif
92 
93  return *this;
94 }
95 
97 {
98  QgsRenderContext context;
99  context.setPainter( painter );
100  if ( painter && painter->device() )
101  {
102  context.setScaleFactor( painter->device()->logicalDpiX() / 25.4 );
103  }
104  else
105  {
106  context.setScaleFactor( 3.465 ); //assume 88 dpi as standard value
107  }
108  return context;
109 }
110 
112 {
113 #ifdef QGISDEBUG
114  if ( !mHasTransformContext )
115  QgsDebugMsgLevel( QStringLiteral( "No QgsCoordinateTransformContext context set for transform" ), 4 );
116 #endif
117  return mTransformContext;
118 }
119 
121 {
122  mTransformContext = context;
123 #ifdef QGISDEBUG
124  mHasTransformContext = true;
125 #endif
126 }
127 
128 void QgsRenderContext::setFlags( QgsRenderContext::Flags flags )
129 {
130  mFlags = flags;
131 }
132 
134 {
135  if ( on )
136  mFlags |= flag;
137  else
138  mFlags &= ~flag;
139 }
140 
141 QgsRenderContext::Flags QgsRenderContext::flags() const
142 {
143  return mFlags;
144 }
145 
147 {
148  return mFlags.testFlag( flag );
149 }
150 
152 {
153  QgsRenderContext ctx;
154  ctx.setMapToPixel( mapSettings.mapToPixel() );
155  ctx.setExtent( mapSettings.visibleExtent() );
161  ctx.setSelectionColor( mapSettings.selectionColor() );
168  ctx.setScaleFactor( mapSettings.outputDpi() / 25.4 ); // = pixels per mm
169  ctx.setRendererScale( mapSettings.scale() );
170  ctx.setExpressionContext( mapSettings.expressionContext() );
171  ctx.setSegmentationTolerance( mapSettings.segmentationTolerance() );
173  ctx.mDistanceArea.setSourceCrs( mapSettings.destinationCrs(), mapSettings.transformContext() );
174  ctx.mDistanceArea.setEllipsoid( mapSettings.ellipsoid() );
175  ctx.setTransformContext( mapSettings.transformContext() );
176  ctx.setPathResolver( mapSettings.pathResolver() );
177  ctx.setTextRenderFormat( mapSettings.textRenderFormat() );
178  //this flag is only for stopping during the current rendering progress,
179  //so must be false at every new render operation
180  ctx.setRenderingStopped( false );
181 
182  return ctx;
183 }
184 
186 {
187  return mFlags.testFlag( ForceVectorOutput );
188 }
189 
191 {
192  return mFlags.testFlag( UseAdvancedEffects );
193 }
194 
196 {
197  setFlag( UseAdvancedEffects, enabled );
198 }
199 
201 {
202  return mFlags.testFlag( DrawEditingInfo );
203 }
204 
206 {
207  return mFlags.testFlag( DrawSelection );
208 }
209 
211 {
212  mCoordTransform = t;
213 }
214 
216 {
217  setFlag( DrawEditingInfo, b );
218 }
219 
221 {
222  setFlag( ForceVectorOutput, force );
223 }
224 
226 {
227  setFlag( DrawSelection, showSelection );
228 }
229 
231 {
232  return mFlags.testFlag( UseRenderingOptimization );
233 }
234 
236 {
237  setFlag( UseRenderingOptimization, enabled );
238 }
239 
241 {
242  if ( ffp )
243  {
244  mFeatureFilterProvider.reset( ffp->clone() );
245  }
246  else
247  {
248  mFeatureFilterProvider.reset( nullptr );
249  }
250 }
251 
253 {
254  return mFeatureFilterProvider.get();
255 }
256 
258 {
259  double conversionFactor = 1.0;
260  switch ( unit )
261  {
263  conversionFactor = mScaleFactor;
264  break;
265 
267  conversionFactor = mScaleFactor / POINTS_TO_MM;
268  break;
269 
271  conversionFactor = mScaleFactor * INCH_TO_MM;
272  break;
273 
275  {
276  size = convertMetersToMapUnits( size );
278  // Fall through to RenderMapUnits with size in meters converted to size in MapUnits
280  }
282  {
283  double mup = scale.computeMapUnitsPerPixel( *this );
284  if ( mup > 0 )
285  {
286  conversionFactor = 1.0 / mup;
287  }
288  else
289  {
290  conversionFactor = 1.0;
291  }
292  break;
293  }
295  conversionFactor = 1.0;
296  break;
297 
300  //no sensible value
301  conversionFactor = 1.0;
302  break;
303  }
304 
305  double convertedSize = size * conversionFactor;
306 
307  if ( unit == QgsUnitTypes::RenderMapUnits )
308  {
309  //check max/min size
310  if ( scale.minSizeMMEnabled )
311  convertedSize = std::max( convertedSize, scale.minSizeMM * mScaleFactor );
312  if ( scale.maxSizeMMEnabled )
313  convertedSize = std::min( convertedSize, scale.maxSizeMM * mScaleFactor );
314  }
315 
316  return convertedSize;
317 }
318 
319 double QgsRenderContext::convertToMapUnits( double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale ) const
320 {
321  double mup = mMapToPixel.mapUnitsPerPixel();
322 
323  switch ( unit )
324  {
326  {
327  size = convertMetersToMapUnits( size );
328  // Fall through to RenderMapUnits with values of meters converted to MapUnits
330  }
332  {
333  // check scale
334  double minSizeMU = std::numeric_limits<double>::lowest();
335  if ( scale.minSizeMMEnabled )
336  {
337  minSizeMU = scale.minSizeMM * mScaleFactor * mup;
338  }
339  if ( !qgsDoubleNear( scale.minScale, 0.0 ) )
340  {
341  minSizeMU = std::max( minSizeMU, size * ( mRendererScale / scale.minScale ) );
342  }
343  size = std::max( size, minSizeMU );
344 
345  double maxSizeMU = std::numeric_limits<double>::max();
346  if ( scale.maxSizeMMEnabled )
347  {
348  maxSizeMU = scale.maxSizeMM * mScaleFactor * mup;
349  }
350  if ( !qgsDoubleNear( scale.maxScale, 0.0 ) )
351  {
352  maxSizeMU = std::min( maxSizeMU, size * ( mRendererScale / scale.maxScale ) );
353  }
354  size = std::min( size, maxSizeMU );
355 
356  return size;
357  }
359  {
360  return size * mScaleFactor * mup;
361  }
363  {
364  return size * mScaleFactor * mup / POINTS_TO_MM;
365  }
367  {
368  return size * mScaleFactor * mup * INCH_TO_MM;
369  }
371  {
372  return size * mup;
373  }
374 
377  //no sensible value
378  return 0.0;
379  }
380  return 0.0;
381 }
382 
383 double QgsRenderContext::convertFromMapUnits( double sizeInMapUnits, QgsUnitTypes::RenderUnit outputUnit ) const
384 {
385  double mup = mMapToPixel.mapUnitsPerPixel();
386 
387  switch ( outputUnit )
388  {
390  {
391  return sizeInMapUnits / convertMetersToMapUnits( 1.0 );
392  }
394  {
395  return sizeInMapUnits;
396  }
398  {
399  return sizeInMapUnits / ( mScaleFactor * mup );
400  }
402  {
403  return sizeInMapUnits / ( mScaleFactor * mup / POINTS_TO_MM );
404  }
406  {
407  return sizeInMapUnits / ( mScaleFactor * mup * INCH_TO_MM );
408  }
410  {
411  return sizeInMapUnits / mup;
412  }
413 
416  //no sensible value
417  return 0.0;
418  }
419  return 0.0;
420 }
421 
422 double QgsRenderContext::convertMetersToMapUnits( double meters ) const
423 {
424  switch ( mDistanceArea.sourceCrs().mapUnits() )
425  {
427  return meters;
429  {
430  QgsPointXY pointCenter = mExtent.center();
431  // The Extent is in the sourceCrs(), when different from destinationCrs()
432  // - the point must be transformed, since DistanceArea uses the destinationCrs()
433  // Note: the default QgsCoordinateTransform() : authid() will return an empty String
434  if ( !mCoordTransform.isShortCircuited() )
435  {
436  pointCenter = mCoordTransform.transform( pointCenter );
437  }
438  return mDistanceArea.measureLineProjected( pointCenter, meters );
439  }
448  return ( meters * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceMeters, mDistanceArea.sourceCrs().mapUnits() ) );
449  }
450  return meters;
451 }
452 
453 
void setForceVectorOutput(bool force)
Meters value as Map units.
Definition: qgsunittypes.h:120
double convertToMapUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to map units.
Enable layer opacity and blending effects.
void setRenderingStopped(bool stopped)
double minSizeMM
The minimum size in millimeters, or 0.0 if unset.
Enable vector simplification and other rendering optimizations.
virtual QgsFeatureFilterProvider * clone() const =0
Create a clone of the feature filter provider.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
const QgsExpressionContext & expressionContext() const
Gets the expression context.
QgsCoordinateTransformContext transformContext() const
Returns the context&#39;s coordinate transform context, which stores various information regarding which ...
void setFlags(QgsRenderContext::Flags flags)
Set combination of flags that will be used for rendering.
Use antialiasing while drawing.
double convertFromMapUnits(double sizeInMapUnits, QgsUnitTypes::RenderUnit outputUnit) const
Converts a size from map units to the specified units.
void setCoordinateTransform(const QgsCoordinateTransform &t)
Sets the current coordinate transform for the context.
QgsPointXY transform(const QgsPointXY &point, TransformDirection direction=ForwardTransform) const SIP_THROW(QgsCsException)
Transform the point from the source CRS to the destination CRS.
A class to represent a 2D point.
Definition: qgspointxy.h:43
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:265
void setSimplifyHints(SimplifyHints simplifyHints)
Sets the simplification hints of the vector layer managed.
void setRendererScale(double scale)
Sets the renderer map scale.
Whether to make extra effort to update map image with partially rendered layers (better for interacti...
void setPathResolver(const QgsPathResolver &resolver)
Sets the path resolver for conversion between relative and absolute paths during rendering operations...
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the context&#39;s coordinate transform context, which stores various information regarding which dat...
double computeMapUnitsPerPixel(const QgsRenderContext &c) const
Computes a map units per pixel scaling factor, respecting the minimum and maximum scales set for the ...
Flags flags() const
Returns combination of flags used for rendering.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Percentage of another measurement (e.g., canvas size, feature size)
Definition: qgsunittypes.h:116
Enable layer opacity and blending effects.
void setTextRenderFormat(TextRenderFormat format)
Sets the text render format, which dictates how text is rendered (e.g.
Whether vector selections should be shown in the rendered map.
void setExtent(const QgsRectangle &extent)
When rendering a map layer, calling this method sets the "clipping" extent for the layer (in the laye...
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
double maxScale
The maximum scale, or 0.0 if unset.
const QgsFeatureFilterProvider * featureFilterProvider() const
Gets the filter feature provider used for additional filtering of rendered features.
bool minSizeMMEnabled
Whether the minimum size in mm should be respected.
QgsCoordinateReferenceSystem destinationCrs() const
returns CRS of destination coordinate reference system
Vector graphics should not be cached and drawn as raster images.
The QgsMapSettings class contains configuration for rendering of the map.
double convertMetersToMapUnits(double meters) const
Convert meter distances to active MapUnit values for QgsUnitTypes::RenderMetersInMapUnits.
void setSelectionColor(const QColor &color)
No simplification can be applied.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
void setUseAdvancedEffects(bool enabled)
Used to enable or disable advanced effects such as blend modes.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
#define FALLTHROUGH
Definition: qgis.h:656
QgsRenderContext & operator=(const QgsRenderContext &rh)
#define INCH_TO_MM
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
bool isShortCircuited() const
Returns true if the transform short circuits because the source and destination are equivalent...
Whether vector selections should be shown in the rendered map.
double scale() const
Returns the calculated map scale.
void setDrawEditingInformation(bool b)
Enable anti-aliasing for map rendering.
points (e.g., for font sizes)
Definition: qgsunittypes.h:118
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
bool drawEditingInformation() const
Draw bounds of symbols (for debugging/testing)
Degrees, for planar geographic CRS distance measurements.
Definition: qgsunittypes.h:62
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
Abstract interface for use by classes that filter the features of a layer.
void setSegmentationToleranceType(QgsAbstractGeometry::SegmentationToleranceType type)
Sets segmentation tolerance type (maximum angle or maximum difference between curve and approximation...
Contains information about the context in which a coordinate transform is executed.
double mapUnitsPerPixel() const
Returns current map units per pixel.
const QgsMapToPixel & mapToPixel() const
Draw bounds of symbols (for debugging/testing)
Vector graphics should not be cached and drawn as raster images.
Enable drawing of vertex markers for layers in editing mode.
QgsAbstractGeometry::SegmentationToleranceType segmentationToleranceType() const
Gets segmentation tolerance type (maximum angle or maximum difference between curve and approximation...
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
bool forceVectorOutput() const
QgsCoordinateReferenceSystem sourceCrs() const
Returns the source spatial reference system.
void setSegmentationTolerance(double tolerance)
Sets the segmentation tolerance applied when rendering curved geometries.
bool useRenderingOptimization() const
Returns true if the rendering optimization (geometry simplification) can be executed.
Draw map such that there are no problems between adjacent tiles.
Unknown distance unit.
Definition: qgsunittypes.h:65
Render is a &#39;canvas preview&#39; render, and shortcuts should be taken to ensure fast rendering...
double outputDpi() const
Returns DPI used for conversion between real world units (e.g.
Render is a &#39;canvas preview&#39; render, and shortcuts should be taken to ensure fast rendering...
Contains information about the context of a rendering operation.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
#define POINTS_TO_MM
QString ellipsoid() const
Returns ellipsoid&#39;s acronym.
double segmentationTolerance() const
Gets the segmentation tolerance applied when rendering curved geometries.
QPainter * painter()
Returns the destination QPainter for the render operation.
double maxSizeMM
The maximum size in millimeters, or 0.0 if unset.
void setShowSelection(bool showSelection)
Sets whether vector selections should be shown in the rendered map.
Struct for storing maximum and minimum scales for measurements in map units.
Whether to make extra effort to update map image with partially rendered layers (better for interacti...
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
double measureLineProjected(const QgsPointXY &p1, double distance=1, double azimuth=M_PI_2, QgsPointXY *projectedPoint=nullptr) const
Calculates the distance from one point with distance in meters and azimuth (direction) When the sourc...
bool useAdvancedEffects() const
Returns true if advanced effects such as blend modes such be used.
void setMapToPixel(const QgsMapToPixel &mtp)
Class for doing transforms between two map coordinate systems.
void setUseRenderingOptimization(bool enabled)
bool showSelection() const
Returns true if vector selections should be shown in the rendered map.
void setFlag(Flag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
void setFeatureFilterProvider(const QgsFeatureFilterProvider *ffp)
Set a filter feature provider used for additional filtering of rendered features. ...
Enable vector simplification and other rendering optimizations.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool testFlag(Flag flag) const
Check whether a particular flag is enabled.
QgsRenderContext::TextRenderFormat textRenderFormat() const
Returns the text render format, which dictates how text is rendered (e.g.
QColor selectionColor() const
Gets color that is used for drawing of selected vector features.
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:230
bool testFlag(Flag flag) const
Check whether a particular flag is enabled.
Terrestrial miles.
Definition: qgsunittypes.h:61
Draw map such that there are no problems between adjacent tiles.
Flag
Enumeration of flags that affect rendering operations.
static Q_INVOKABLE double fromUnitToUnitFactor(QgsUnitTypes::DistanceUnit fromUnit, QgsUnitTypes::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
Enable drawing of vertex markers for layers in editing mode.
double minScale
The minimum scale, or 0.0 if unset.
bool maxSizeMMEnabled
Whether the maximum size in mm should be respected.
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:111
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.