QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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 <qgsmapthemecollection.h>
22 #include <qgsproject.h>
23 
24 #include "qgs3dmapsettings.h"
25 
27 
28 QgsTerrainTextureGenerator::QgsTerrainTextureGenerator( const Qgs3DMapSettings &map )
29  : mMap( map )
30  , mLastJobId( 0 )
31 {
32 }
33 
34 int QgsTerrainTextureGenerator::render( const QgsRectangle &extent, const QString &debugText )
35 {
36  QgsMapSettings mapSettings( baseMapSettings() );
37  mapSettings.setExtent( extent );
38 
40  connect( job, &QgsMapRendererJob::finished, this, &QgsTerrainTextureGenerator::onRenderingFinished );
41  job->start();
42 
43  JobData jobData;
44  jobData.jobId = ++mLastJobId;
45  jobData.job = job;
46  jobData.extent = extent;
47  jobData.debugText = debugText;
48 
49  mJobs.insert( job, jobData );
50  //qDebug() << "added job: " << jobData.jobId << " .... in queue: " << jobs.count();
51  return jobData.jobId;
52 }
53 
54 void QgsTerrainTextureGenerator::cancelJob( int jobId )
55 {
56  Q_FOREACH ( const JobData &jd, mJobs )
57  {
58  if ( jd.jobId == jobId )
59  {
60  //qDebug() << "canceling job " << jobId;
61  jd.job->cancelWithoutBlocking();
62  disconnect( jd.job, &QgsMapRendererJob::finished, this, &QgsTerrainTextureGenerator::onRenderingFinished );
63  jd.job->deleteLater();
64  mJobs.remove( jd.job );
65  return;
66  }
67  }
68  Q_ASSERT( false && "requested job ID does not exist!" );
69 }
70 
71 QImage QgsTerrainTextureGenerator::renderSynchronously( const QgsRectangle &extent, const QString &debugText )
72 {
73  QgsMapSettings mapSettings( baseMapSettings() );
74  mapSettings.setExtent( extent );
75 
76  QImage img = QImage( mapSettings.outputSize(), mapSettings.outputImageFormat() );
77  img.setDotsPerMeterX( 1000 * mapSettings.outputDpi() / 25.4 );
78  img.setDotsPerMeterY( 1000 * mapSettings.outputDpi() / 25.4 );
79  img.fill( Qt::transparent );
80 
81  QPainter p( &img );
82 
83  QgsMapRendererCustomPainterJob job( mapSettings, &p );
84  job.renderSynchronously();
85 
86  if ( mMap.showTerrainTilesInfo() )
87  {
88  // extra tile information for debugging
89  p.setPen( Qt::white );
90  p.drawRect( 0, 0, img.width() - 1, img.height() - 1 );
91  p.drawText( img.rect(), debugText, QTextOption( Qt::AlignCenter ) );
92  }
93 
94  p.end();
95 
96  return img;
97 }
98 
99 
100 void QgsTerrainTextureGenerator::onRenderingFinished()
101 {
102  QgsMapRendererSequentialJob *mapJob = static_cast<QgsMapRendererSequentialJob *>( sender() );
103 
104  Q_ASSERT( mJobs.contains( mapJob ) );
105  JobData jobData = mJobs.value( mapJob );
106 
107  QImage img = mapJob->renderedImage();
108 
109  if ( mMap.showTerrainTilesInfo() )
110  {
111  // extra tile information for debugging
112  QPainter p( &img );
113  p.setPen( Qt::white );
114  p.drawRect( 0, 0, img.width() - 1, img.height() - 1 );
115  p.drawText( img.rect(), jobData.debugText, QTextOption( Qt::AlignCenter ) );
116  p.end();
117  }
118 
119  mapJob->deleteLater();
120  mJobs.remove( mapJob );
121 
122  //qDebug() << "finished job " << jobData.jobId << " ... in queue: " << jobs.count();
123 
124  // pass QImage further
125  emit tileReady( jobData.jobId, img );
126 }
127 
128 QgsMapSettings QgsTerrainTextureGenerator::baseMapSettings()
129 {
130  QgsMapSettings mapSettings;
131 
132  mapSettings.setOutputSize( QSize( mMap.mapTileResolution(), mMap.mapTileResolution() ) );
133  mapSettings.setDestinationCrs( mMap.crs() );
134  mapSettings.setBackgroundColor( mMap.backgroundColor() );
135  mapSettings.setFlag( QgsMapSettings::DrawLabeling, mMap.showLabels() );
136  mapSettings.setTransformContext( mMap.transformContext() );
137  mapSettings.setPathResolver( mMap.pathResolver() );
138 
139  QgsMapThemeCollection *mapThemes = mMap.mapThemeCollection();
140  QString mapThemeName = mMap.terrainMapTheme();
141  if ( mapThemeName.isEmpty() || !mapThemes || !mapThemes->hasMapTheme( mapThemeName ) )
142  {
143  mapSettings.setLayers( mMap.layers() );
144  }
145  else
146  {
147  mapSettings.setLayers( mapThemes->mapThemeVisibleLayers( mapThemeName ) );
148  mapSettings.setLayerStyleOverrides( mapThemes->mapThemeStyleOverrides( mapThemeName ) );
149  }
150 
151  return mapSettings;
152 }
153 
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:41
Job implementation that renders everything sequentially using a custom painter.
void start() override
Start the rendering job and immediately return.
bool hasMapTheme(const QString &name) const
Returns whether a map theme with a matching name exists.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
QList< QgsMapLayer * > mapThemeVisibleLayers(const QString &name) const
Returns the list of layers that are visible for the specified map theme.
QMap< QString, QString > mapThemeStyleOverrides(const QString &name)
Gets layer style overrides (for QgsMapSettings) of the visible layers for given map theme...
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Set map of map layer style overrides (key: layer ID, value: style name) where a different style shoul...
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.
void setLayers(const QList< QgsMapLayer *> &layers)
Set list of layers for map rendering.
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...
Container class that allows storage of map themes consisting of visible map layers and layer styles...