QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
qgsrasterlayerrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterlayerrenderer.cpp
3  --------------------------------------
4  Date : December 2013
5  Copyright : (C) 2013 by Martin Dobias
6  Email : wonder dot sk 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 "qgsrasterlayerrenderer.h"
17 
18 #include "qgsmessagelog.h"
19 #include "qgsrasterdataprovider.h"
20 #include "qgsrasterdrawer.h"
21 #include "qgsrasteriterator.h"
22 #include "qgsrasterlayer.h"
23 #include "qgsrasterprojector.h"
24 #include "qgsrendercontext.h"
25 #include "qgsproject.h"
26 #include "qgsexception.h"
28 #include "qgsmapclippingutils.h"
29 
30 #include <QElapsedTimer>
31 #include <QPointer>
32 
34 
35 QgsRasterLayerRendererFeedback::QgsRasterLayerRendererFeedback( QgsRasterLayerRenderer *r )
36  : mR( r )
37  , mMinimalPreviewInterval( 250 )
38 {
39  setRenderPartialOutput( r->renderContext()->testFlag( QgsRenderContext::RenderPartialOutput ) );
40 }
41 
42 void QgsRasterLayerRendererFeedback::onNewData()
43 {
44  if ( !renderPartialOutput() )
45  return; // we were not asked for partial renders and we may not have a temporary image for overwriting...
46 
47  // update only once upon a time
48  // (preview itself takes some time)
49  if ( mLastPreview.isValid() && mLastPreview.msecsTo( QTime::currentTime() ) < mMinimalPreviewInterval )
50  return;
51 
52  // TODO: update only the area that got new data
53 
54  QgsDebugMsgLevel( QStringLiteral( "new raster preview! %1" ).arg( mLastPreview.msecsTo( QTime::currentTime() ) ), 3 );
55  QElapsedTimer t;
56  t.start();
57  QgsRasterBlockFeedback feedback;
58  feedback.setPreviewOnly( true );
59  feedback.setRenderPartialOutput( true );
60  QgsRasterIterator iterator( mR->mPipe->last() );
61  QgsRasterDrawer drawer( &iterator );
62  drawer.draw( mR->renderContext()->painter(), mR->mRasterViewPort, &mR->renderContext()->mapToPixel(), &feedback );
63  mR->mReadyToCompose = true;
64  QgsDebugMsgLevel( QStringLiteral( "total raster preview time: %1 ms" ).arg( t.elapsed() ), 3 );
65  mLastPreview = QTime::currentTime();
66 }
67 
71  : QgsMapLayerRenderer( layer->id(), &rendererContext )
72  , mProviderCapabilities( static_cast<QgsRasterDataProvider::Capability>( layer->dataProvider()->capabilities() ) )
73  , mFeedback( new QgsRasterLayerRendererFeedback( this ) )
74 {
75  mReadyToCompose = false;
76  QgsMapToPixel mapToPixel = rendererContext.mapToPixel();
77  if ( rendererContext.mapToPixel().mapRotation() )
78  {
79  // unset rotation for the sake of local computations.
80  // Rotation will be handled by QPainter later
81  // TODO: provide a method of QgsMapToPixel to fetch map center
82  // in geographical units
83  QgsPointXY center = mapToPixel.toMapCoordinates(
84  static_cast<int>( mapToPixel.mapWidth() / 2.0 ),
85  static_cast<int>( mapToPixel.mapHeight() / 2.0 )
86  );
87  mapToPixel.setMapRotation( 0, center.x(), center.y() );
88  }
89 
90  QgsRectangle myProjectedViewExtent;
91  QgsRectangle myProjectedLayerExtent;
92 
93  if ( rendererContext.coordinateTransform().isValid() )
94  {
95  QgsDebugMsgLevel( QStringLiteral( "coordinateTransform set -> project extents." ), 4 );
96  if ( rendererContext.extent().xMinimum() == std::numeric_limits<double>::lowest() &&
97  rendererContext.extent().yMinimum() == std::numeric_limits<double>::lowest() &&
98  rendererContext.extent().xMaximum() == std::numeric_limits<double>::max() &&
99  rendererContext.extent().yMaximum() == std::numeric_limits<double>::max() )
100  {
101  // We get in this situation if the view CRS is geographical and the
102  // extent goes beyond -180,-90,180,90. To avoid reprojection issues to the
103  // layer CRS, then this dummy extent is returned by QgsMapRendererJob::reprojectToLayerExtent()
104  // Don't try to reproject it now to view extent as this would return
105  // a null rectangle.
106  myProjectedViewExtent = rendererContext.extent();
107  }
108  else
109  {
110  try
111  {
112  QgsCoordinateTransform ct = rendererContext.coordinateTransform();
114  myProjectedViewExtent = ct.transformBoundingBox( rendererContext.extent() );
115  }
116  catch ( QgsCsException &cs )
117  {
118  QgsMessageLog::logMessage( QObject::tr( "Could not reproject view extent: %1" ).arg( cs.what() ), QObject::tr( "Raster" ) );
119  myProjectedViewExtent.setMinimal();
120  }
121  }
122 
123  try
124  {
125  QgsCoordinateTransform ct = rendererContext.coordinateTransform();
127  myProjectedLayerExtent = ct.transformBoundingBox( layer->extent() );
128  }
129  catch ( QgsCsException &cs )
130  {
131  QgsMessageLog::logMessage( QObject::tr( "Could not reproject layer extent: %1" ).arg( cs.what() ), QObject::tr( "Raster" ) );
132  myProjectedLayerExtent.setMinimal();
133  }
134  }
135  else
136  {
137  QgsDebugMsgLevel( QStringLiteral( "coordinateTransform not set" ), 4 );
138  myProjectedViewExtent = rendererContext.extent();
139  myProjectedLayerExtent = layer->extent();
140  }
141 
142  // clip raster extent to view extent
143  QgsRectangle myRasterExtent = layer->ignoreExtents() ? myProjectedViewExtent : myProjectedViewExtent.intersect( myProjectedLayerExtent );
144  if ( myRasterExtent.isEmpty() )
145  {
146  QgsDebugMsgLevel( QStringLiteral( "draw request outside view extent." ), 2 );
147  // nothing to do
148  return;
149  }
150 
151  QgsDebugMsgLevel( "theViewExtent is " + rendererContext.extent().toString(), 4 );
152  QgsDebugMsgLevel( "myProjectedViewExtent is " + myProjectedViewExtent.toString(), 4 );
153  QgsDebugMsgLevel( "myProjectedLayerExtent is " + myProjectedLayerExtent.toString(), 4 );
154  QgsDebugMsgLevel( "myRasterExtent is " + myRasterExtent.toString(), 4 );
155 
156  //
157  // The first thing we do is set up the QgsRasterViewPort. This struct stores all the settings
158  // relating to the size (in pixels and coordinate system units) of the raster part that is
159  // in view in the map window. It also stores the origin.
160  //
161  //this is not a class level member because every time the user pans or zooms
162  //the contents of the rasterViewPort will change
163  mRasterViewPort = new QgsRasterViewPort();
164 
165  mRasterViewPort->mDrawnExtent = myRasterExtent;
166  if ( rendererContext.coordinateTransform().isValid() )
167  {
168  mRasterViewPort->mSrcCRS = layer->crs();
169  mRasterViewPort->mDestCRS = rendererContext.coordinateTransform().destinationCrs();
170  mRasterViewPort->mTransformContext = rendererContext.transformContext();
171  }
172  else
173  {
174  mRasterViewPort->mSrcCRS = QgsCoordinateReferenceSystem(); // will be invalid
175  mRasterViewPort->mDestCRS = QgsCoordinateReferenceSystem(); // will be invalid
176  }
177 
178  // get dimensions of clipped raster image in device coordinate space (this is the size of the viewport)
179  mRasterViewPort->mTopLeftPoint = mapToPixel.transform( myRasterExtent.xMinimum(), myRasterExtent.yMaximum() );
180  mRasterViewPort->mBottomRightPoint = mapToPixel.transform( myRasterExtent.xMaximum(), myRasterExtent.yMinimum() );
181 
182  // align to output device grid, i.e. std::floor/ceil to integers
183  // TODO: this should only be done if paint device is raster - screen, image
184  // for other devices (pdf) it can have floating point origin
185  // we could use floating point for raster devices as well, but respecting the
186  // output device grid should make it more effective as the resampling is done in
187  // the provider anyway
188  mRasterViewPort->mTopLeftPoint.setX( std::floor( mRasterViewPort->mTopLeftPoint.x() ) );
189  mRasterViewPort->mTopLeftPoint.setY( std::floor( mRasterViewPort->mTopLeftPoint.y() ) );
190  mRasterViewPort->mBottomRightPoint.setX( std::ceil( mRasterViewPort->mBottomRightPoint.x() ) );
191  mRasterViewPort->mBottomRightPoint.setY( std::ceil( mRasterViewPort->mBottomRightPoint.y() ) );
192  // recalc myRasterExtent to aligned values
193  myRasterExtent.set(
194  mapToPixel.toMapCoordinates( mRasterViewPort->mTopLeftPoint.x(),
195  mRasterViewPort->mBottomRightPoint.y() ),
196  mapToPixel.toMapCoordinates( mRasterViewPort->mBottomRightPoint.x(),
197  mRasterViewPort->mTopLeftPoint.y() )
198  );
199 
200  //raster viewport top left / bottom right are already rounded to int
201  mRasterViewPort->mWidth = static_cast<qgssize>( std::abs( mRasterViewPort->mBottomRightPoint.x() - mRasterViewPort->mTopLeftPoint.x() ) );
202  mRasterViewPort->mHeight = static_cast<qgssize>( std::abs( mRasterViewPort->mBottomRightPoint.y() - mRasterViewPort->mTopLeftPoint.y() ) );
203 
204  //the drawable area can start to get very very large when you get down displaying 2x2 or smaller, this is because
205  //mapToPixel.mapUnitsPerPixel() is less then 1,
206  //so we will just get the pixel data and then render these special cases differently in paintImageToCanvas()
207 
208  QgsDebugMsgLevel( QStringLiteral( "mapUnitsPerPixel = %1" ).arg( mapToPixel.mapUnitsPerPixel() ), 3 );
209  QgsDebugMsgLevel( QStringLiteral( "mWidth = %1" ).arg( layer->width() ), 3 );
210  QgsDebugMsgLevel( QStringLiteral( "mHeight = %1" ).arg( layer->height() ), 3 );
211  QgsDebugMsgLevel( QStringLiteral( "myRasterExtent.xMinimum() = %1" ).arg( myRasterExtent.xMinimum() ), 3 );
212  QgsDebugMsgLevel( QStringLiteral( "myRasterExtent.xMaximum() = %1" ).arg( myRasterExtent.xMaximum() ), 3 );
213  QgsDebugMsgLevel( QStringLiteral( "myRasterExtent.yMinimum() = %1" ).arg( myRasterExtent.yMinimum() ), 3 );
214  QgsDebugMsgLevel( QStringLiteral( "myRasterExtent.yMaximum() = %1" ).arg( myRasterExtent.yMaximum() ), 3 );
215 
216  QgsDebugMsgLevel( QStringLiteral( "mTopLeftPoint.x() = %1" ).arg( mRasterViewPort->mTopLeftPoint.x() ), 3 );
217  QgsDebugMsgLevel( QStringLiteral( "mBottomRightPoint.x() = %1" ).arg( mRasterViewPort->mBottomRightPoint.x() ), 3 );
218  QgsDebugMsgLevel( QStringLiteral( "mTopLeftPoint.y() = %1" ).arg( mRasterViewPort->mTopLeftPoint.y() ), 3 );
219  QgsDebugMsgLevel( QStringLiteral( "mBottomRightPoint.y() = %1" ).arg( mRasterViewPort->mBottomRightPoint.y() ), 3 );
220 
221  QgsDebugMsgLevel( QStringLiteral( "mWidth = %1" ).arg( mRasterViewPort->mWidth ), 3 );
222  QgsDebugMsgLevel( QStringLiteral( "mHeight = %1" ).arg( mRasterViewPort->mHeight ), 3 );
223 
224  // /\/\/\ - added to handle zoomed-in rasters
225 
226  // TODO R->mLastViewPort = *mRasterViewPort;
227 
228  // TODO: is it necessary? Probably WMS only?
229  layer->dataProvider()->setDpi( 25.4 * rendererContext.scaleFactor() );
230 
231 
232  // copy the whole raster pipe!
233  mPipe = new QgsRasterPipe( *layer->pipe() );
234  QObject::connect( mPipe->provider(), &QgsRasterDataProvider::statusChanged, layer, &QgsRasterLayer::statusChanged );
235  QgsRasterRenderer *rasterRenderer = mPipe->renderer();
236  if ( rasterRenderer
237  && !( rendererContext.flags() & QgsRenderContext::RenderPreviewJob )
238  && !( rendererContext.flags() & QgsRenderContext::Render3DMap ) )
239  {
240  layer->refreshRendererIfNeeded( rasterRenderer, rendererContext.extent() );
241  }
242 
243  const QgsRasterLayerTemporalProperties *temporalProperties = qobject_cast< const QgsRasterLayerTemporalProperties * >( layer->temporalProperties() );
244  if ( temporalProperties->isActive() && renderContext()->isTemporal() )
245  {
246  switch ( temporalProperties->mode() )
247  {
249  break;
250 
252  // in this mode we need to pass on the desired render temporal range to the data provider
253  if ( mPipe->provider()->temporalCapabilities() )
254  {
255  mPipe->provider()->temporalCapabilities()->setRequestedTemporalRange( rendererContext.temporalRange() );
257  }
258  break;
259  }
260  }
261  else if ( mPipe->provider()->temporalCapabilities() )
262  {
263  mPipe->provider()->temporalCapabilities()->setRequestedTemporalRange( QgsDateTimeRange() );
265  }
266 
268 }
269 
271 {
272  delete mFeedback;
273 
274  delete mRasterViewPort;
275  delete mPipe;
276 }
277 
279 {
280  // Skip rendering of out of view tiles (xyz)
281  if ( !mRasterViewPort || ( renderContext()->testFlag( QgsRenderContext::Flag::RenderPreviewJob ) &&
282  !( mProviderCapabilities &
283  QgsRasterInterface::Capability::Prefetch ) ) )
284  return true;
285 
286  QElapsedTimer time;
287  time.start();
288  //
289  //
290  // The goal here is to make as many decisions as possible early on (outside of the rendering loop)
291  // so that we can maximise performance of the rendering process. So now we check which drawing
292  // procedure to use :
293  //
294 
295  QgsScopedQPainterState painterSate( renderContext()->painter() );
296  if ( !mClippingRegions.empty() )
297  {
298  bool needsPainterClipPath = false;
299  const QPainterPath path = QgsMapClippingUtils::calculatePainterClipRegion( mClippingRegions, *renderContext(), QgsMapLayerType::RasterLayer, needsPainterClipPath );
300  if ( needsPainterClipPath )
301  renderContext()->painter()->setClipPath( path, Qt::IntersectClip );
302  }
303 
304  QgsRasterProjector *projector = mPipe->projector();
305  bool restoreOldResamplingStage = false;
306  QgsRasterPipe::ResamplingStage oldResamplingState = mPipe->resamplingStage();
307 
308  // TODO add a method to interface to get provider and get provider
309  // params in QgsRasterProjector
310  if ( projector )
311  {
312  // Force provider resampling if reprojection is needed
314  mRasterViewPort->mSrcCRS != mRasterViewPort->mDestCRS &&
315  oldResamplingState != QgsRasterPipe::ResamplingStage::Provider )
316  {
317  restoreOldResamplingStage = true;
319  }
320  projector->setCrs( mRasterViewPort->mSrcCRS, mRasterViewPort->mDestCRS, mRasterViewPort->mTransformContext );
321  }
322 
323  // Drawer to pipe?
324  QgsRasterIterator iterator( mPipe->last() );
325  QgsRasterDrawer drawer( &iterator );
326  drawer.draw( renderContext()->painter(), mRasterViewPort, &renderContext()->mapToPixel(), mFeedback );
327 
328  if ( restoreOldResamplingStage )
329  {
330  mPipe->setResamplingStage( oldResamplingState );
331  }
332 
333  const QStringList errors = mFeedback->errors();
334  for ( const QString &error : errors )
335  {
336  mErrors.append( error );
337  }
338 
339  QgsDebugMsgLevel( QStringLiteral( "total raster draw time (ms): %1" ).arg( time.elapsed(), 5 ), 4 );
340  mReadyToCompose = true;
341 
342  return !mFeedback->isCanceled();
343 }
344 
346 {
347  return mFeedback;
348 }
349 
351 {
352  // preview of intermediate raster rendering results requires a temporary output image
354 }
355 
This class represents a coordinate reference system (CRS).
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.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system, which the transform will transform coordinates t...
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
QString what() const
Definition: qgsexception.h:48
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:45
static QList< QgsMapClippingRegion > collectClippingRegionsForLayer(const QgsRenderContext &context, const QgsMapLayer *layer)
Collects the list of map clipping regions from a context which apply to a map layer.
static QPainterPath calculatePainterClipRegion(const QList< QgsMapClippingRegion > &regions, const QgsRenderContext &context, QgsMapLayerType layerType, bool &shouldClip)
Returns a QPainterPath representing the intersection of clipping regions from context which should be...
Base class for utility classes that encapsulate information necessary for rendering of map layers.
bool mReadyToCompose
The flag must be set to false in renderer's constructor if wants to use the smarter map redraws funct...
QStringList errors() const
Returns list of errors (problems) that happened during the rendering.
QgsRenderContext * renderContext()
Returns the render context associated with the renderer.
virtual QgsRectangle extent() const
Returns the extent of the layer.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:91
void statusChanged(const QString &status)
Emit a signal with status (e.g. to be caught by QgisApp and display a msg on status bar)
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:39
int mapHeight() const
Returns current map height in pixels.
void setMapRotation(double degrees, double cx, double cy)
Set map rotation in degrees (clockwise)
double mapUnitsPerPixel() const
Returns current map units per pixel.
QgsPointXY toMapCoordinates(int x, int y) const
Transform device coordinates to map (world) coordinates.
int mapWidth() const
Returns current map width in pixels The information is only known if setRotation was used.
QgsPointXY transform(const QgsPointXY &p) const
Transform the point p from map (world) coordinates to device coordinates.
Definition: qgsmaptopixel.h:82
double mapRotation() const
Returns current map rotation in degrees (clockwise)
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
A class to represent a 2D point.
Definition: qgspointxy.h:44
void setX(double x) SIP_HOLDGIL
Sets the x value of the point.
Definition: qgspointxy.h:107
double y
Definition: qgspointxy.h:48
Q_GADGET double x
Definition: qgspointxy.h:47
void setY(double y) SIP_HOLDGIL
Sets the y value of the point.
Definition: qgspointxy.h:117
Feedback object tailored for raster block reading.
void setPreviewOnly(bool preview)
set flag whether the block request is for preview purposes only
void setRenderPartialOutput(bool enable)
Set whether our painter is drawing to a temporary image used just by this layer.
void setIntervalHandlingMethod(IntervalHandlingMethod method)
Sets the desired method to use when resolving a temporal interval to matching layers or bands in the ...
Base class for raster data providers.
virtual QgsRasterDataProvider::ProviderCapabilities providerCapabilities() const
Returns flags containing the supported capabilities of the data provider.
void setDpi(int dpi)
Sets the output device resolution.
@ ProviderHintCanPerformProviderResampling
Provider can perform resampling (to be opposed to post rendering resampling) (since QGIS 3....
void statusChanged(const QString &) const
Emit a message to be displayed on status bar, usually used by network providers (WMS,...
QgsRasterDataProviderTemporalCapabilities * temporalCapabilities() override
Returns the provider's temporal capabilities.
The drawing pipe for raster layers.
void draw(QPainter *p, QgsRasterViewPort *viewPort, const QgsMapToPixel *qgsMapToPixel, QgsRasterBlockFeedback *feedback=nullptr)
Draws raster data.
Iterator for sequentially processing raster cells.
Implementation of threaded rendering for raster layers.
bool render() override
Do the rendering (based on data stored in the class).
QgsRasterLayerRenderer(QgsRasterLayer *layer, QgsRenderContext &rendererContext)
bool forceRasterRender() const override
Returns true if the renderer must be rendered to a raster paint device (e.g.
QgsFeedback * feedback() const override
Access to feedback object of the layer renderer (may be nullptr)
Implementation of map layer temporal properties for raster layers.
@ ModeFixedTemporalRange
Mode when temporal properties have fixed start and end datetimes.
@ ModeTemporalRangeFromDataProvider
Mode when raster layer delegates temporal range handling to the dataprovider.
TemporalMode mode() const
Returns the temporal properties mode.
QgsRasterDataProviderTemporalCapabilities::IntervalHandlingMethod intervalHandlingMethod() const
Returns the desired method to use when resolving a temporal interval to matching layers or bands in t...
Represents a raster layer.
int height() const
Returns the height of the (unclipped) raster.
QgsRasterPipe * pipe()
Returns the raster pipe.
void refreshRendererIfNeeded(QgsRasterRenderer *rasterRenderer, const QgsRectangle &extent)
Refresh renderer with new extent, if needed.
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
bool ignoreExtents() const
If the ignoreExtent flag is set, the layer will also render outside the bounding box reported by the ...
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
int width() const
Returns the width of the (unclipped) raster.
Base class for processing modules.
Definition: qgsrasterpipe.h:47
ResamplingStage
Stage at which resampling occurs.
@ Provider
Resampling occurs in Provider.
QgsRasterDataProvider * provider() const
QgsRasterProjector * projector() const
QgsRasterInterface * last() const
QgsRasterRenderer * renderer() const
ResamplingStage resamplingStage() const
Returns which stage of the pipe should apply resampling.
void setResamplingStage(ResamplingStage stage)
Select which stage of the pipe should apply resampling.
QgsRasterProjector implements approximate projection support for it calculates grid of points in sour...
Q_DECL_DEPRECATED void setCrs(const QgsCoordinateReferenceSystem &srcCRS, const QgsCoordinateReferenceSystem &destCRS, int srcDatumTransform=-1, int destDatumTransform=-1)
Sets the source and destination CRS.
Raster renderer pipe that applies colors to a raster.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
void set(const QgsPointXY &p1, const QgsPointXY &p2)
Sets the rectangle from two QgsPoints.
Definition: qgsrectangle.h:105
void setMinimal() SIP_HOLDGIL
Set a rectangle so that min corner is at max and max corner is at min.
Definition: qgsrectangle.h:151
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:437
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Definition: qgsrectangle.h:312
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
QPainter * painter()
Returns the destination QPainter for the render operation.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QgsCoordinateTransformContext transformContext() const
Returns the context's coordinate transform context, which stores various information regarding which ...
@ RenderPreviewJob
Render is a 'canvas preview' render, and shortcuts should be taken to ensure fast rendering.
@ RenderPartialOutput
Whether to make extra effort to update map image with partially rendered layers (better for interacti...
@ Render3DMap
Render is for a 3D map.
Flags flags() const
Returns combination of flags used for rendering.
bool testFlag(Flag flag) const
Check whether a particular flag is enabled.
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
const QgsRectangle & extent() const
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
Scoped object for saving and restoring a QPainter object's state.
bool isActive() const
Returns true if the temporal property is active.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...
Definition: qgis.h:769
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
This class provides details of the viewable area that a raster will be rendered into.
qgssize mHeight
Height, number of rows to be rendered.
QgsCoordinateReferenceSystem mDestCRS
Target coordinate system.
QgsPointXY mBottomRightPoint
Coordinate (in output device coordinate system) of bottom right corner of the part of the raster that...
QgsPointXY mTopLeftPoint
Coordinate (in output device coordinate system) of top left corner of the part of the raster that is ...
QgsCoordinateReferenceSystem mSrcCRS
Source coordinate system.
QgsRectangle mDrawnExtent
Intersection of current map extent and layer extent.
QgsCoordinateTransformContext mTransformContext
Coordinate transform context.
qgssize mWidth
Width, number of columns to be rendered.