QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsmaprenderertask.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmaprenderertask.h
3  -------------------------
4  begin : Apr 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 "qgsannotation.h"
19 #include "qgsannotationmanager.h"
20 #include "qgsmaprenderertask.h"
21 #include "qgsmapsettingsutils.h"
22 #include "qgsogrutils.h"
23 #include "qgslogger.h"
27 #include "qgsfeaturerequest.h"
28 #include "qgsvectorlayer.h"
29 
30 #include <QFile>
31 #include <QImageWriter>
32 #include <QTextStream>
33 #include <QTimeZone>
34 #ifndef QT_NO_PRINTER
35 #include <QPrinter>
36 #endif
37 
38 #include "gdal.h"
39 #include "cpl_conv.h"
40 
42 
43 class QgsMapRendererTaskGeoPdfExporter : public QgsAbstractGeoPdfExporter
44 {
45 
46  public:
47 
48  QgsMapRendererTaskGeoPdfExporter( const QgsMapSettings &ms )
49  {
50  // collect details upfront, while we are still in the main thread
51  const QList< QgsMapLayer * > layers = ms.layers();
52  for ( const QgsMapLayer *layer : layers )
53  {
54  VectorComponentDetail detail;
55  detail.name = layer->name();
56  detail.mapLayerId = layer->id();
57  if ( const QgsVectorLayer *vl = qobject_cast< const QgsVectorLayer * >( layer ) )
58  {
59  detail.displayAttribute = vl->displayField();
60  }
61  mLayerDetails[ layer->id() ] = detail;
62  }
63  }
64 
65  private:
66 
67  QgsAbstractGeoPdfExporter::VectorComponentDetail componentDetailForLayerId( const QString &layerId ) override
68  {
69  return mLayerDetails.value( layerId );
70  }
71 
72  QMap< QString, VectorComponentDetail > mLayerDetails;
73 };
74 
75 
76 class QgsMapRendererTaskRenderedFeatureHandler : public QgsRenderedFeatureHandlerInterface
77 {
78  public:
79 
80  QgsMapRendererTaskRenderedFeatureHandler( QgsMapRendererTaskGeoPdfExporter *exporter, const QgsMapSettings &settings )
81  : mExporter( exporter )
82  , mMapSettings( settings )
83  {
84  // PDF coordinate space uses a hardcoded DPI of 72, also vertical dimension is flipped from QGIS dimension
85  const double pageHeightPdfUnits = settings.outputSize().height() * 72.0 / settings.outputDpi();
86  mTransform = QTransform::fromTranslate( 0, pageHeightPdfUnits ).scale( 72.0 / mMapSettings.outputDpi(), -72.0 / mMapSettings.outputDpi() );
87  }
88 
89  void handleRenderedFeature( const QgsFeature &feature, const QgsGeometry &renderedBounds, const QgsRenderedFeatureHandlerInterface::RenderedFeatureContext &context ) override
90  {
91  // is it a hack retrieving the layer ID from an expression context like this? possibly... BUT
92  // the alternative is adding a layer ID member to QgsRenderContext, and that's just asking for people to abuse it
93  // and use it to retrieve QgsMapLayers mid-way through a render operation. Lesser of two evils it is!
94  const QString layerId = context.renderContext.expressionContext().variable( QStringLiteral( "layer_id" ) ).toString();
95 
96  QgsGeometry transformed = renderedBounds;
97  transformed.transform( mTransform );
98 
99  // always convert to multitype, to make things consistent
100  transformed.convertToMultiType();
101 
102  mExporter->pushRenderedFeature( layerId, QgsAbstractGeoPdfExporter::RenderedFeature( feature, transformed ) );
103  }
104 
105  QSet<QString> usedAttributes( QgsVectorLayer *, const QgsRenderContext & ) const override
106  {
107  return QSet< QString >() << QgsFeatureRequest::ALL_ATTRIBUTES;
108  }
109 
110  private:
111 
112  QgsMapRendererTaskGeoPdfExporter *mExporter = nullptr;
113  QgsMapSettings mMapSettings;
115  QTransform mTransform;
116 
117 };
118 
120 
121 QgsMapRendererTask::QgsMapRendererTask( const QgsMapSettings &ms, const QString &fileName, const QString &fileFormat, const bool forceRaster, QgsTask::Flags flags,
122  const bool geoPDF, const QgsAbstractGeoPdfExporter::ExportDetails &geoPdfExportDetails )
123  : QgsTask( fileFormat == QLatin1String( "PDF" ) ? tr( "Saving as PDF" ) : tr( "Saving as image" ), flags )
124  , mMapSettings( ms )
125  , mFileName( fileName )
126  , mFileFormat( fileFormat )
127  , mForceRaster( forceRaster )
128  , mGeoPDF( geoPDF && mFileFormat == QLatin1String( "PDF" ) && QgsAbstractGeoPdfExporter::geoPDFCreationAvailable() )
129  , mGeoPdfExportDetails( geoPdfExportDetails )
130 {
131  prepare();
132 }
133 
135  : QgsTask( tr( "Rendering to painter" ) )
136  , mMapSettings( ms )
137  , mPainter( p )
138 {
139  prepare();
140 }
141 
143 
144 void QgsMapRendererTask::addAnnotations( const QList< QgsAnnotation * > &annotations )
145 {
146  qDeleteAll( mAnnotations );
147  mAnnotations.clear();
148 
149  const auto constAnnotations = annotations;
150  for ( const QgsAnnotation *a : constAnnotations )
151  {
152  mAnnotations << a->clone();
153  }
154 }
155 
156 void QgsMapRendererTask::addDecorations( const QList< QgsMapDecoration * > &decorations )
157 {
158  mDecorations = decorations;
159 }
160 
161 
163 {
164  mJobMutex.lock();
165  if ( mJob )
166  mJob->cancelWithoutBlocking();
167  mJobMutex.unlock();
168 
169  QgsTask::cancel();
170 }
171 
173 {
174  if ( mErrored )
175  return false;
176 
177  if ( mGeoPDF )
178  {
179 #ifdef QT_NO_PRINTER
180  return false;
181 #else
182  QList< QgsAbstractGeoPdfExporter::ComponentLayerDetail > pdfComponents;
183 
184  QgsMapRendererStagedRenderJob *job = static_cast< QgsMapRendererStagedRenderJob * >( mJob.get() );
185  int outputLayer = 1;
186  while ( !job->isFinished() )
187  {
189 
190  component.name = QStringLiteral( "layer_%1" ).arg( outputLayer );
191  component.mapLayerId = job->currentLayerId();
192  component.opacity = job->currentLayerOpacity();
193  component.compositionMode = job->currentLayerCompositionMode();
194  component.sourcePdfPath = mGeoPdfExporter->generateTemporaryFilepath( QStringLiteral( "layer_%1.pdf" ).arg( outputLayer ) );
195  pdfComponents << component;
196 
197  QPrinter printer;
198  printer.setOutputFileName( component.sourcePdfPath );
199  printer.setOutputFormat( QPrinter::PdfFormat );
200 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
201  printer.setOrientation( QPrinter::Portrait );
202  // paper size needs to be given in millimeters in order to be able to set a resolution to pass onto the map renderer
203  QSizeF outputSize = mMapSettings.outputSize();
204  printer.setPaperSize( outputSize * 25.4 / mMapSettings.outputDpi(), QPrinter::Millimeter );
205  printer.setPageMargins( 0, 0, 0, 0, QPrinter::Millimeter );
206 #else
207  printer.setPageOrientation( QPageLayout::Orientation::Portrait );
208  // paper size needs to be given in millimeters in order to be able to set a resolution to pass onto the map renderer
209  const QSizeF outputSize = mMapSettings.outputSize();
210  const QPageSize pageSize( outputSize * 25.4 / mMapSettings.outputDpi(), QPageSize::Unit::Millimeter );
211  printer.setPageSize( pageSize );
212  printer.setPageMargins( QMarginsF( 0, 0, 0, 0 ) );
213 #endif
214  printer.setResolution( mMapSettings.outputDpi() );
215 
216  QPainter p( &printer );
217  job->renderCurrentPart( &p );
218  p.end();
219 
220  outputLayer++;
221  job->nextPart();
222  }
223  QgsAbstractGeoPdfExporter::ExportDetails exportDetails = mGeoPdfExportDetails;
224  const double pageWidthMM = mMapSettings.outputSize().width() * 25.4 / mMapSettings.outputDpi();
225  const double pageHeightMM = mMapSettings.outputSize().height() * 25.4 / mMapSettings.outputDpi();
226  exportDetails.pageSizeMm = QSizeF( pageWidthMM, pageHeightMM );
227  exportDetails.dpi = mMapSettings.outputDpi();
228 
229  exportDetails.layerIdToPdfLayerTreeNameMap = mLayerIdToLayerNameMap;
230  exportDetails.layerOrder = mMapLayerOrder;
231 
232  if ( mSaveWorldFile )
233  {
234  // setup georeferencing
236  georef.crs = mMapSettings.destinationCrs();
237  georef.pageBoundsMm = QgsRectangle( 0, 0, pageWidthMM, pageHeightMM );
238  georef.controlPoints.reserve( 4 );
240  georef.controlPoints << QgsAbstractGeoPdfExporter::ControlPoint( QgsPointXY( pageWidthMM, 0 ), mMapSettings.mapToPixel().toMapCoordinates( mMapSettings.outputSize().width(), 0 ) );
241  georef.controlPoints << QgsAbstractGeoPdfExporter::ControlPoint( QgsPointXY( pageWidthMM, pageHeightMM ), mMapSettings.mapToPixel().toMapCoordinates( mMapSettings.outputSize().width(), mMapSettings.outputSize().height() ) );
242  georef.controlPoints << QgsAbstractGeoPdfExporter::ControlPoint( QgsPointXY( 0, pageHeightMM ), mMapSettings.mapToPixel().toMapCoordinates( 0, mMapSettings.outputSize().height() ) );
243  exportDetails.georeferencedSections << georef;
244  }
245 
246  const bool res = mGeoPdfExporter->finalize( pdfComponents, mFileName, exportDetails );
247  mGeoPdfExporter.reset();
248  mTempPainter.reset();
249  mPrinter.reset();
250  return res;
251 #endif
252  }
253  else
254  static_cast< QgsMapRendererCustomPainterJob *>( mJob.get() )->renderPrepared();
255 
256  mJobMutex.lock();
257  mJob.reset( nullptr );
258  mJobMutex.unlock();
259 
260  if ( isCanceled() )
261  return false;
262 
263  QgsRenderContext context = QgsRenderContext::fromMapSettings( mMapSettings );
264  context.setPainter( mDestPainter );
265 
266  const auto constMDecorations = mDecorations;
267  for ( QgsMapDecoration *decoration : constMDecorations )
268  {
269  decoration->render( mMapSettings, context );
270  }
271 
272  const auto constMAnnotations = mAnnotations;
273  for ( QgsAnnotation *annotation : constMAnnotations )
274  {
275  if ( isCanceled() )
276  return false;
277 
278  if ( !annotation || !annotation->isVisible() )
279  {
280  continue;
281  }
282  if ( annotation->mapLayer() && !mMapSettings.layers().contains( annotation->mapLayer() ) )
283  {
284  continue;
285  }
286 
287  const QgsScopedQPainterState painterState( context.painter() );
288  context.setPainterFlagsUsingContext();
289 
290  double itemX, itemY;
291  if ( annotation->hasFixedMapPosition() )
292  {
293  itemX = mMapSettings.outputSize().width() * ( annotation->mapPosition().x() - mMapSettings.extent().xMinimum() ) / mMapSettings.extent().width();
294  itemY = mMapSettings.outputSize().height() * ( 1 - ( annotation->mapPosition().y() - mMapSettings.extent().yMinimum() ) / mMapSettings.extent().height() );
295  }
296  else
297  {
298  itemX = annotation->relativePosition().x() * mMapSettings.outputSize().width();
299  itemY = annotation->relativePosition().y() * mMapSettings.outputSize().height();
300  }
301 
302  context.painter()->translate( itemX, itemY );
303 
304  annotation->render( context );
305  }
306 
307  if ( !mFileName.isEmpty() )
308  {
309  mDestPainter->end();
310 
311  if ( mFileFormat == QLatin1String( "PDF" ) )
312  {
313 #ifndef QT_NO_PRINTER
314  if ( mForceRaster )
315  {
316  QPainter pp;
317  pp.begin( mPrinter.get() );
318  const QRectF rect( 0, 0, mImage.width(), mImage.height() );
319  pp.drawImage( rect, mImage, rect );
320  pp.end();
321  }
322 
323  if ( mSaveWorldFile || mExportMetadata )
324  {
325  CPLSetThreadLocalConfigOption( "GDAL_PDF_DPI", QString::number( mMapSettings.outputDpi() ).toLocal8Bit().constData() );
326  const gdal::dataset_unique_ptr outputDS( GDALOpen( mFileName.toLocal8Bit().constData(), GA_Update ) );
327  if ( outputDS )
328  {
329  if ( mSaveWorldFile )
330  {
331  double a, b, c, d, e, f;
332  QgsMapSettingsUtils::worldFileParameters( mMapSettings, a, b, c, d, e, f );
333  c -= 0.5 * a;
334  c -= 0.5 * b;
335  f -= 0.5 * d;
336  f -= 0.5 * e;
337  double geoTransform[6] = { c, a, b, f, d, e };
338  GDALSetGeoTransform( outputDS.get(), geoTransform );
339  GDALSetProjection( outputDS.get(), mMapSettings.destinationCrs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED_GDAL ).toLocal8Bit().constData() );
340  }
341 
342  if ( mExportMetadata )
343  {
344  QString creationDateString;
345  const QDateTime creationDateTime = mGeoPdfExportDetails.creationDateTime;
346  if ( creationDateTime.isValid() )
347  {
348  creationDateString = QStringLiteral( "D:%1" ).arg( mGeoPdfExportDetails.creationDateTime.toString( QStringLiteral( "yyyyMMddHHmmss" ) ) );
349  if ( creationDateTime.timeZone().isValid() )
350  {
351  int offsetFromUtc = creationDateTime.timeZone().offsetFromUtc( creationDateTime );
352  creationDateString += ( offsetFromUtc >= 0 ) ? '+' : '-';
353  offsetFromUtc = std::abs( offsetFromUtc );
354  const int offsetHours = offsetFromUtc / 3600;
355  const int offsetMins = ( offsetFromUtc % 3600 ) / 60;
356  creationDateString += QStringLiteral( "%1'%2'" ).arg( offsetHours ).arg( offsetMins );
357  }
358  }
359  GDALSetMetadataItem( outputDS.get(), "CREATION_DATE", creationDateString.toUtf8().constData(), nullptr );
360 
361  GDALSetMetadataItem( outputDS.get(), "AUTHOR", mGeoPdfExportDetails.author.toUtf8().constData(), nullptr );
362  const QString creator = QStringLiteral( "QGIS %1" ).arg( Qgis::version() );
363  GDALSetMetadataItem( outputDS.get(), "CREATOR", creator.toUtf8().constData(), nullptr );
364  GDALSetMetadataItem( outputDS.get(), "PRODUCER", creator.toUtf8().constData(), nullptr );
365  GDALSetMetadataItem( outputDS.get(), "SUBJECT", mGeoPdfExportDetails.subject.toUtf8().constData(), nullptr );
366  GDALSetMetadataItem( outputDS.get(), "TITLE", mGeoPdfExportDetails.title.toUtf8().constData(), nullptr );
367 
368  const QgsAbstractMetadataBase::KeywordMap keywords = mGeoPdfExportDetails.keywords;
369  QStringList allKeywords;
370  for ( auto it = keywords.constBegin(); it != keywords.constEnd(); ++it )
371  {
372  allKeywords.append( QStringLiteral( "%1: %2" ).arg( it.key(), it.value().join( ',' ) ) );
373  }
374  const QString keywordString = allKeywords.join( ';' );
375  GDALSetMetadataItem( outputDS.get(), "KEYWORDS", keywordString.toUtf8().constData(), nullptr );
376  }
377  }
378  CPLSetThreadLocalConfigOption( "GDAL_PDF_DPI", nullptr );
379  }
380 #else
381  mError = ImageUnsupportedFormat;
382  return false;
383 #endif // !QT_NO_PRINTER
384  }
385  else if ( mFileFormat != QLatin1String( "PDF" ) )
386  {
387  QImageWriter writer( mFileName, mFileFormat.toLocal8Bit().data() );
388  if ( mFileFormat == QLatin1String( "TIF" ) || mFileFormat == QLatin1String( "TIFF" ) )
389  {
390  // Enable LZW compression
391  writer.setCompression( 1 );
392  }
393  const bool success = writer.write( mImage );
394  if ( !success )
395  {
396  mError = ImageSaveFail;
397  return false;
398  }
399 
400  if ( mSaveWorldFile )
401  {
402  const QFileInfo info = QFileInfo( mFileName );
403 
404  // build the world file name
405  const QString outputSuffix = info.suffix();
406  bool skipWorldFile = false;
407  if ( outputSuffix == QLatin1String( "tif" ) || outputSuffix == QLatin1String( "tiff" ) )
408  {
409  const gdal::dataset_unique_ptr outputDS( GDALOpen( mFileName.toLocal8Bit().constData(), GA_Update ) );
410  if ( outputDS )
411  {
412  skipWorldFile = true;
413  double a, b, c, d, e, f;
414  QgsMapSettingsUtils::worldFileParameters( mMapSettings, a, b, c, d, e, f );
415  c -= 0.5 * a;
416  c -= 0.5 * b;
417  f -= 0.5 * d;
418  f -= 0.5 * e;
419  double geoTransform[] = { c, a, b, f, d, e };
420  GDALSetGeoTransform( outputDS.get(), geoTransform );
421  GDALSetProjection( outputDS.get(), mMapSettings.destinationCrs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED_GDAL ).toLocal8Bit().constData() );
422  }
423  }
424 
425  if ( !skipWorldFile )
426  {
427  const QString worldFileName = info.absolutePath() + '/' + info.completeBaseName() + '.'
428  + outputSuffix.at( 0 ) + outputSuffix.at( info.suffix().size() - 1 ) + 'w';
429  QFile worldFile( worldFileName );
430 
431  if ( worldFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) //don't use QIODevice::Text
432  {
433  QTextStream stream( &worldFile );
434  stream << QgsMapSettingsUtils::worldFileContent( mMapSettings );
435  }
436  }
437  }
438  }
439  }
440 
441  mTempPainter.reset();
442 #ifndef QT_NO_PRINTER
443  mPrinter.reset();
444 #endif
445 
446  return true;
447 }
448 
449 void QgsMapRendererTask::finished( bool result )
450 {
451  qDeleteAll( mAnnotations );
452  mAnnotations.clear();
453 
454  if ( result )
455  emit renderingComplete();
456  else
457  emit errorOccurred( mError );
458 }
459 
460 void QgsMapRendererTask::prepare()
461 {
462  if ( mGeoPDF )
463  {
464  mGeoPdfExporter = std::make_unique< QgsMapRendererTaskGeoPdfExporter >( mMapSettings );
465  if ( mGeoPdfExportDetails.includeFeatures )
466  {
467  mRenderedFeatureHandler = std::make_unique< QgsMapRendererTaskRenderedFeatureHandler >( static_cast< QgsMapRendererTaskGeoPdfExporter * >( mGeoPdfExporter.get() ), mMapSettings );
468  mMapSettings.addRenderedFeatureHandler( mRenderedFeatureHandler.get() );
469  }
470 
471  const QList< QgsMapLayer * > layers = mMapSettings.layers();
472  for ( const QgsMapLayer *layer : layers )
473  {
474  mLayerIdToLayerNameMap.insert( layer->id(), layer->name() );
475  mMapLayerOrder << layer->id();
476  }
477 
479  mJob->start();
480  return;
481  }
482 
483  mDestPainter = mPainter;
484 
485  if ( mFileFormat == QLatin1String( "PDF" ) )
486  {
487 #ifndef QT_NO_PRINTER
488  mPrinter.reset( new QPrinter() );
489  mPrinter->setOutputFileName( mFileName );
490  mPrinter->setOutputFormat( QPrinter::PdfFormat );
491 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
492  mPrinter->setOrientation( QPrinter::Portrait );
493  // paper size needs to be given in millimeters in order to be able to set a resolution to pass onto the map renderer
494  QSizeF outputSize = mMapSettings.outputSize();
495  mPrinter->setPaperSize( outputSize * 25.4 / mMapSettings.outputDpi(), QPrinter::Millimeter );
496  mPrinter->setPageMargins( 0, 0, 0, 0, QPrinter::Millimeter );
497 #else
498  mPrinter->setPageOrientation( QPageLayout::Orientation::Portrait );
499  // paper size needs to be given in millimeters in order to be able to set a resolution to pass onto the map renderer
500  const QSizeF outputSize = mMapSettings.outputSize();
501  const QPageSize pageSize( outputSize * 25.4 / mMapSettings.outputDpi(), QPageSize::Unit::Millimeter );
502  mPrinter->setPageSize( pageSize );
503  mPrinter->setPageMargins( QMarginsF( 0, 0, 0, 0 ) );
504 #endif
505  mPrinter->setResolution( mMapSettings.outputDpi() );
506 
507  if ( !mForceRaster )
508  {
509  mTempPainter.reset( new QPainter( mPrinter.get() ) );
510  mDestPainter = mTempPainter.get();
511  }
512 #else
513  mError = ImageUnsupportedFormat;
514 #endif // ! QT_NO_PRINTER
515  }
516 
517  if ( !mDestPainter )
518  {
519  // save rendered map to an image file
520  mImage = QImage( mMapSettings.outputSize(), QImage::Format_ARGB32 );
521  if ( mImage.isNull() )
522  {
523  mErrored = true;
524  mError = ImageAllocationFail;
525  return;
526  }
527 
528  mImage.setDotsPerMeterX( 1000 * mMapSettings.outputDpi() / 25.4 );
529  mImage.setDotsPerMeterY( 1000 * mMapSettings.outputDpi() / 25.4 );
530 
531  mTempPainter.reset( new QPainter( &mImage ) );
532  mDestPainter = mTempPainter.get();
533  }
534 
535  if ( !mDestPainter )
536  {
537  mErrored = true;
538  return;
539  }
540 
541  mJob.reset( new QgsMapRendererCustomPainterJob( mMapSettings, mDestPainter ) );
542  static_cast< QgsMapRendererCustomPainterJob *>( mJob.get() )->prepare();
543 }
QgsAbstractGeoPdfExporter::ExportDetails::layerOrder
QStringList layerOrder
Optional list of layer IDs, in the order desired to appear in the generated GeoPDF file.
Definition: qgsabstractgeopdfexporter.h:286
QgsRectangle::height
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
QgsAbstractGeoPdfExporter::ControlPoint
Contains details of a control point used during georeferencing GeoPDF outputs.
Definition: qgsabstractgeopdfexporter.h:145
QgsRenderContext::setPainterFlagsUsingContext
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
Definition: qgsrendercontext.cpp:169
Qgis::version
static QString version()
Version string.
Definition: qgis.cpp:277
qgsfeaturerequest.h
QgsRenderContext::expressionContext
QgsExpressionContext & expressionContext()
Gets the expression context.
Definition: qgsrendercontext.h:625
QgsMapSettings::outputSize
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
Definition: qgsmapsettings.cpp:239
QgsRenderContext::fromMapSettings
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
Definition: qgsrendercontext.cpp:234
QgsRenderedFeatureHandlerInterface::handleRenderedFeature
virtual void handleRenderedFeature(const QgsFeature &feature, const QgsGeometry &renderedBounds, const QgsRenderedFeatureHandlerInterface::RenderedFeatureContext &context)=0
Called whenever a feature is rendered during a map render job.
qgsannotation.h
QgsGeometry::transform
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
Definition: qgsgeometry.cpp:3128
QgsCoordinateReferenceSystem::WKT_PREFERRED_GDAL
@ WKT_PREFERRED_GDAL
Preferred format for conversion of CRS to WKT for use with the GDAL library.
Definition: qgscoordinatereferencesystem.h:682
QgsMapRendererStagedRenderJob::currentLayerOpacity
double currentLayerOpacity() const
Returns the opacity for the current layer about to be rendered in the next render operation.
Definition: qgsmaprendererstagedrenderjob.cpp:244
QgsMapRendererTask::run
bool run() override
Performs the task's operation.
Definition: qgsmaprenderertask.cpp:172
QgsRenderContext::setPainter
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
Definition: qgsrendercontext.h:512
QgsRectangle::yMinimum
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
QgsAbstractGeoPdfExporter::ComponentLayerDetail::mapLayerId
QString mapLayerId
Associated map layer ID, or an empty string if this component layer is not associated with a map laye...
Definition: qgsabstractgeopdfexporter.h:124
QgsMapRendererTask::renderingComplete
void renderingComplete()
Emitted when the map rendering is successfully completed.
QgsMapRendererStagedRenderJob::currentLayerCompositionMode
QPainter::CompositionMode currentLayerCompositionMode() const
Returns the composition mode for the current layer about to be rendered in the next render operation.
Definition: qgsmaprendererstagedrenderjob.cpp:254
qgsrenderedfeaturehandlerinterface.h
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsMapRendererTask::addDecorations
void addDecorations(const QList< QgsMapDecoration * > &decorations)
Adds decorations to be rendered on the map.
Definition: qgsmaprenderertask.cpp:156
qgsogrutils.h
QgsAbstractGeoPdfExporter::ExportDetails
Definition: qgsabstractgeopdfexporter.h:198
qgsmaprendererstagedrenderjob.h
QgsAbstractGeoPdfExporter::GeoReferencedSection
Definition: qgsabstractgeopdfexporter.h:164
QgsMapToPixel::toMapCoordinates
QgsPointXY toMapCoordinates(int x, int y) const
Transforms device coordinates to map (world) coordinates.
Definition: qgsmaptopixel.h:173
QgsAbstractGeoPdfExporter::ComponentLayerDetail::opacity
double opacity
Component opacity.
Definition: qgsabstractgeopdfexporter.h:136
QgsAbstractGeoPdfExporter::ExportDetails::layerIdToPdfLayerTreeNameMap
QMap< QString, QString > layerIdToPdfLayerTreeNameMap
Optional map of map layer ID to custom layer tree name to show in the created PDF file.
Definition: qgsabstractgeopdfexporter.h:269
QgsAbstractGeoPdfExporter::ExportDetails::title
QString title
Metadata title tag.
Definition: qgsabstractgeopdfexporter.h:225
QgsRenderedFeatureHandlerInterface::RenderedFeatureContext::renderContext
const QgsRenderContext & renderContext
The render context which was used while rendering feature.
Definition: qgsrenderedfeaturehandlerinterface.h:65
QgsExpressionContext::variable
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
Definition: qgsexpressioncontext.cpp:300
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsAbstractGeoPdfExporter::ExportDetails::keywords
QgsAbstractMetadataBase::KeywordMap keywords
Metadata keyword map.
Definition: qgsabstractgeopdfexporter.h:228
QgsRenderedFeatureHandlerInterface
An interface for classes which provider custom handlers for features rendered as part of a map render...
Definition: qgsrenderedfeaturehandlerinterface.h:46
QgsAbstractGeoPdfExporter::ExportDetails::georeferencedSections
QList< QgsAbstractGeoPdfExporter::GeoReferencedSection > georeferencedSections
List of georeferenced sections.
Definition: qgsabstractgeopdfexporter.h:207
QgsMapRendererTask::ImageAllocationFail
@ ImageAllocationFail
Image allocation failure.
Definition: qgsmaprenderertask.h:55
QgsMapSettings::extent
QgsRectangle extent() const
Returns geographical coordinates of the rectangle that should be rendered.
Definition: qgsmapsettings.cpp:75
QgsAbstractGeoPdfExporter::ComponentLayerDetail::compositionMode
QPainter::CompositionMode compositionMode
Component composition mode.
Definition: qgsabstractgeopdfexporter.h:133
QgsMapRendererTask::addAnnotations
void addAnnotations(const QList< QgsAnnotation * > &annotations)
Adds annotations to be rendered on the map.
Definition: qgsmaprenderertask.cpp:144
QgsTask::cancel
virtual void cancel()
Notifies the task that it should terminate.
Definition: qgstaskmanager.cpp:91
QgsFeatureRequest::ALL_ATTRIBUTES
static const QString ALL_ATTRIBUTES
A special attribute that if set matches all attributes.
Definition: qgsfeaturerequest.h:317
QgsMapSettings::addRenderedFeatureHandler
void addRenderedFeatureHandler(QgsRenderedFeatureHandlerInterface *handler)
Adds a rendered feature handler to use while rendering the map settings.
Definition: qgsmapsettings.cpp:838
QgsAnnotation
Abstract base class for annotation items which are drawn over a map.
Definition: qgsannotation.h:53
QgsAbstractGeoPdfExporter::VectorComponentDetail
Contains information relating to a single PDF layer in the GeoPDF export.
Definition: qgsabstractgeopdfexporter.h:328
QgsMapRendererTask::finished
void finished(bool result) override
If the task is managed by a QgsTaskManager, this will be called after the task has finished (whether ...
Definition: qgsmaprenderertask.cpp:449
qgsmapsettingsutils.h
QgsAbstractGeoPdfExporter::RenderedFeature
Contains information about a feature rendered inside the PDF.
Definition: qgsabstractgeopdfexporter.h:85
gdal::dataset_unique_ptr
std::unique_ptr< std::remove_pointer< GDALDatasetH >::type, GDALDatasetCloser > dataset_unique_ptr
Scoped GDAL dataset.
Definition: qgsogrutils.h:139
QgsAbstractGeoPdfExporter::ComponentLayerDetail::sourcePdfPath
QString sourcePdfPath
File path to the (already created) PDF to use as the source for this component layer.
Definition: qgsabstractgeopdfexporter.h:130
QgsMapRendererTask::ImageUnsupportedFormat
@ ImageUnsupportedFormat
Format is unsupported on the platform.
Definition: qgsmaprenderertask.h:57
QgsCoordinateReferenceSystem::toWkt
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
Definition: qgscoordinatereferencesystem.cpp:1810
QgsMapRendererTask::errorOccurred
void errorOccurred(int error)
Emitted when map rendering failed.
QgsMapRendererStagedRenderJob::nextPart
bool nextPart()
Iterates to the next part to render.
Definition: qgsmaprendererstagedrenderjob.cpp:167
qgsannotationmanager.h
QgsRectangle::xMinimum
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
QgsScopedQPainterState
Scoped object for saving and restoring a QPainter object's state.
Definition: qgsrendercontext.h:1336
QgsMapRendererStagedRenderJob::currentLayerId
QString currentLayerId() const
Returns the ID of the current layer about to be rendered in the next render operation.
Definition: qgsmaprendererstagedrenderjob.cpp:229
QgsMapSettingsUtils::worldFileContent
static QString worldFileContent(const QgsMapSettings &mapSettings)
Creates the content of a world file.
Definition: qgsmapsettingsutils.cpp:130
QgsMapRendererStagedRenderJob::RenderLabelsByMapLayer
@ RenderLabelsByMapLayer
Labels should be rendered in individual stages by map layer. This allows separation of labels belongi...
Definition: qgsmaprendererstagedrenderjob.h:42
qgsvectorlayer.h
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
QgsMapSettings::destinationCrs
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
Definition: qgsmapsettings.cpp:358
QgsMapRendererCustomPainterJob
Job implementation that renders everything sequentially using a custom painter.
Definition: qgsmaprenderercustompainterjob.h:63
QgsRenderedFeatureHandlerInterface::RenderedFeatureContext
Definition: qgsrenderedfeaturehandlerinterface.h:51
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
QgsAbstractGeoPdfExporter::ExportDetails::includeFeatures
bool includeFeatures
true if feature vector information (such as attributes) should be exported.
Definition: qgsabstractgeopdfexporter.h:250
QgsAbstractGeoPdfExporter::ComponentLayerDetail
Contains details of a particular input component to be used during PDF composition.
Definition: qgsabstractgeopdfexporter.h:117
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
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsAbstractGeoPdfExporter::GeoReferencedSection::pageBoundsMm
QgsRectangle pageBoundsMm
Bounds of the georeferenced section on the page, in millimeters.
Definition: qgsabstractgeopdfexporter.h:172
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsRectangle::width
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
QgsMapRendererStagedRenderJob::isFinished
bool isFinished() const
Returns true if the job is finished, and nothing remains to render.
Definition: qgsmaprendererstagedrenderjob.cpp:224
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
QgsAbstractGeoPdfExporter::GeoReferencedSection::controlPoints
QList< QgsAbstractGeoPdfExporter::ControlPoint > controlPoints
List of control points corresponding to this georeferenced section.
Definition: qgsabstractgeopdfexporter.h:185
qgsabstractgeopdfexporter.h
QgsGeometry::convertToMultiType
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
Definition: qgsgeometry.cpp:1571
QgsMapRendererTask::QgsMapRendererTask
QgsMapRendererTask(const QgsMapSettings &ms, const QString &fileName, const QString &fileFormat=QString("PNG"), bool forceRaster=false, QgsTask::Flags flags=QgsTask::CanCancel, bool geoPdf=false, const QgsAbstractGeoPdfExporter::ExportDetails &geoPdfExportDetails=QgsAbstractGeoPdfExporter::ExportDetails())
Constructor for QgsMapRendererTask to render a map to an image file.
Definition: qgsmaprenderertask.cpp:121
QgsAbstractGeoPdfExporter::ExportDetails::author
QString author
Metadata author tag.
Definition: qgsabstractgeopdfexporter.h:210
QgsAbstractGeoPdfExporter::GeoReferencedSection::crs
QgsCoordinateReferenceSystem crs
Coordinate reference system for georeferenced section.
Definition: qgsabstractgeopdfexporter.h:182
QgsMapRendererStagedRenderJob
Render job implementation that renders maps in stages, allowing different stages (e....
Definition: qgsmaprendererstagedrenderjob.h:32
QgsMapRendererStagedRenderJob::renderCurrentPart
bool renderCurrentPart(QPainter *painter)
Renders the current part of the map to the specified painter.
Definition: qgsmaprendererstagedrenderjob.cpp:96
QgsAbstractMetadataBase::KeywordMap
QMap< QString, QStringList > KeywordMap
Map of vocabulary string to keyword list.
Definition: qgsabstractmetadatabase.h:78
QgsAbstractGeoPdfExporter::ExportDetails::subject
QString subject
Metadata subject tag.
Definition: qgsabstractgeopdfexporter.h:222
QgsAbstractGeoPdfExporter::ExportDetails::creationDateTime
QDateTime creationDateTime
Metadata creation datetime.
Definition: qgsabstractgeopdfexporter.h:219
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsMapDecoration
Interface for map decorations.
Definition: qgsmapdecoration.h:34
QgsMapRendererTask::~QgsMapRendererTask
~QgsMapRendererTask() override
qgslogger.h
QgsMapSettings::outputDpi
double outputDpi() const
Returns the DPI (dots per inch) used for conversion between real world units (e.g.
Definition: qgsmapsettings.cpp:267
QgsRenderContext::painter
QPainter * painter()
Returns the destination QPainter for the render operation.
Definition: qgsrendercontext.h:112
QgsMapRendererTask::ImageSaveFail
@ ImageSaveFail
Image save failure.
Definition: qgsmaprenderertask.h:56
QgsAbstractGeoPdfExporter::ComponentLayerDetail::name
QString name
User-friendly name for the generated PDF layer.
Definition: qgsabstractgeopdfexporter.h:121
QgsMapSettings
The QgsMapSettings class contains configuration for rendering of the map. The rendering itself is don...
Definition: qgsmapsettings.h:88
qgsmaprenderertask.h
QgsMapRendererTask::cancel
void cancel() override
Notifies the task that it should terminate.
Definition: qgsmaprenderertask.cpp:162
QgsRenderedFeatureHandlerInterface::usedAttributes
virtual QSet< QString > usedAttributes(QgsVectorLayer *layer, const QgsRenderContext &context) const
Returns a list of attributes required by this handler, for the specified layer.
Definition: qgsrenderedfeaturehandlerinterface.h:93
QgsAbstractGeoPdfExporter
Abstract base class for GeoPDF exporters.
Definition: qgsabstractgeopdfexporter.h:55
QgsMapSettings::mapToPixel
const QgsMapToPixel & mapToPixel() const
Definition: qgsmapsettings.h:527
QgsAbstractGeoPdfExporter::ExportDetails::dpi
double dpi
Output DPI.
Definition: qgsabstractgeopdfexporter.h:204
QgsAbstractGeoPdfExporter::ExportDetails::pageSizeMm
QSizeF pageSizeMm
Page size, in millimeters.
Definition: qgsabstractgeopdfexporter.h:201
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
QgsTask::isCanceled
bool isCanceled() const
Will return true if task should terminate ASAP.
Definition: qgstaskmanager.cpp:118
QgsTask
Abstract base class for long running background tasks. Tasks can be controlled directly,...
Definition: qgstaskmanager.h:54