QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgsterraintexturegenerator_p.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsterraintexturegenerator_p.cpp
3  --------------------------------------
4  Date : July 2017
5  Copyright : (C) 2017 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 
17 
20 #include <qgsmapsettings.h>
21 #include <qgsproject.h>
22 
23 #include "qgs3dmapsettings.h"
24 
26 
27 QgsTerrainTextureGenerator::QgsTerrainTextureGenerator( const Qgs3DMapSettings &map )
28  : mMap( map )
29  , mLastJobId( 0 )
30 {
31 }
32 
33 int QgsTerrainTextureGenerator::render( const QgsRectangle &extent, const QString &debugText )
34 {
35  QgsMapSettings mapSettings( baseMapSettings() );
36  mapSettings.setExtent( extent );
37 
39  connect( job, &QgsMapRendererJob::finished, this, &QgsTerrainTextureGenerator::onRenderingFinished );
40  job->start();
41 
42  JobData jobData;
43  jobData.jobId = ++mLastJobId;
44  jobData.job = job;
45  jobData.extent = extent;
46  jobData.debugText = debugText;
47 
48  mJobs.insert( job, jobData );
49  //qDebug() << "added job: " << jobData.jobId << " .... in queue: " << jobs.count();
50  return jobData.jobId;
51 }
52 
53 void QgsTerrainTextureGenerator::cancelJob( int jobId )
54 {
55  Q_FOREACH ( const JobData &jd, mJobs )
56  {
57  if ( jd.jobId == jobId )
58  {
59  //qDebug() << "canceling job " << jobId;
60  jd.job->cancelWithoutBlocking();
61  disconnect( jd.job, &QgsMapRendererJob::finished, this, &QgsTerrainTextureGenerator::onRenderingFinished );
62  jd.job->deleteLater();
63  mJobs.remove( jd.job );
64  return;
65  }
66  }
67  Q_ASSERT( false && "requested job ID does not exist!" );
68 }
69 
70 QImage QgsTerrainTextureGenerator::renderSynchronously( const QgsRectangle &extent, const QString &debugText )
71 {
72  QgsMapSettings mapSettings( baseMapSettings() );
73  mapSettings.setExtent( extent );
74 
75  QImage img = QImage( mapSettings.outputSize(), mapSettings.outputImageFormat() );
76  img.setDotsPerMeterX( 1000 * mapSettings.outputDpi() / 25.4 );
77  img.setDotsPerMeterY( 1000 * mapSettings.outputDpi() / 25.4 );
78  img.fill( Qt::transparent );
79 
80  QPainter p( &img );
81 
82  QgsMapRendererCustomPainterJob job( mapSettings, &p );
83  job.renderSynchronously();
84 
85  if ( mMap.showTerrainTilesInfo() )
86  {
87  // extra tile information for debugging
88  p.setPen( Qt::white );
89  p.drawRect( 0, 0, img.width() - 1, img.height() - 1 );
90  p.drawText( img.rect(), debugText, QTextOption( Qt::AlignCenter ) );
91  }
92 
93  p.end();
94 
95  return img;
96 }
97 
98 
99 void QgsTerrainTextureGenerator::onRenderingFinished()
100 {
101  QgsMapRendererSequentialJob *mapJob = static_cast<QgsMapRendererSequentialJob *>( sender() );
102 
103  Q_ASSERT( mJobs.contains( mapJob ) );
104  JobData jobData = mJobs.value( mapJob );
105 
106  QImage img = mapJob->renderedImage();
107 
108  if ( mMap.showTerrainTilesInfo() )
109  {
110  // extra tile information for debugging
111  QPainter p( &img );
112  p.setPen( Qt::white );
113  p.drawRect( 0, 0, img.width() - 1, img.height() - 1 );
114  p.drawText( img.rect(), jobData.debugText, QTextOption( Qt::AlignCenter ) );
115  p.end();
116  }
117 
118  mapJob->deleteLater();
119  mJobs.remove( mapJob );
120 
121  //qDebug() << "finished job " << jobData.jobId << " ... in queue: " << jobs.count();
122 
123  // pass QImage further
124  emit tileReady( jobData.jobId, img );
125 }
126 
127 QgsMapSettings QgsTerrainTextureGenerator::baseMapSettings()
128 {
129  QgsMapSettings mapSettings;
130  mapSettings.setLayers( mMap.layers() );
131  mapSettings.setOutputSize( QSize( mMap.mapTileResolution(), mMap.mapTileResolution() ) );
132  mapSettings.setDestinationCrs( mMap.crs() );
133  mapSettings.setBackgroundColor( mMap.backgroundColor() );
134  mapSettings.setFlag( QgsMapSettings::DrawLabeling, mMap.showLabels() );
135  mapSettings.setTransformContext( mMap.transformContext() );
136  mapSettings.setPathResolver( mMap.pathResolver() );
137  return mapSettings;
138 }
139 
void finished()
emitted when asynchronous rendering is finished (or canceled).
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
A rectangle specified with double values.
Definition: qgsrectangle.h:40
Job implementation that renders everything sequentially using a custom painter.
void start() override
Start the rendering job and immediately return.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
3 Definition of the world
Enable drawing of labels on top of the map.
void setFlag(Flag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
The QgsMapSettings class contains configuration for rendering of the map.
void setOutputSize(QSize size)
Sets the size of the resulting map image.
Job implementation that renders everything sequentially in one thread.
void setBackgroundColor(const QColor &color)
Sets the background color of the map.
QImage renderedImage() override
Gets a preview/resulting image.
virtual QgsRectangle extent() const =0
extent of the terrain in terrain&#39;s CRS
void setPathResolver(const QgsPathResolver &resolver)
Sets the path resolver for conversion between relative and absolute paths during rendering operations...
void setLayers(const QList< QgsMapLayer * > &layers)
Set list of layers for map rendering.