QGIS API Documentation  3.12.1-BucureČ™ti (121cc00ff0)
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 
26 #include "qgseventtracing.h"
27 
29 
30 QgsTerrainTextureGenerator::QgsTerrainTextureGenerator( const Qgs3DMapSettings &map )
31  : mMap( map )
32  , mLastJobId( 0 )
33 {
34 }
35 
36 int QgsTerrainTextureGenerator::render( const QgsRectangle &extent, QgsChunkNodeId tileId, const QString &debugText )
37 {
38  QgsMapSettings mapSettings( baseMapSettings() );
39  mapSettings.setExtent( extent );
40 
41  QgsEventTracing::addEvent( QgsEventTracing::AsyncBegin, QStringLiteral( "3D" ), QStringLiteral( "Texture" ), tileId.text() );
42 
44  connect( job, &QgsMapRendererJob::finished, this, &QgsTerrainTextureGenerator::onRenderingFinished );
45  job->start();
46 
47  JobData jobData;
48  jobData.jobId = ++mLastJobId;
49  jobData.tileId = tileId;
50  jobData.job = job;
51  jobData.extent = extent;
52  jobData.debugText = debugText;
53 
54  mJobs.insert( job, jobData );
55  //qDebug() << "added job: " << jobData.jobId << " .... in queue: " << jobs.count();
56  return jobData.jobId;
57 }
58 
59 void QgsTerrainTextureGenerator::cancelJob( int jobId )
60 {
61  Q_FOREACH ( const JobData &jd, mJobs )
62  {
63  if ( jd.jobId == jobId )
64  {
65  //qDebug() << "canceling job " << jobId;
66  jd.job->cancelWithoutBlocking();
67  disconnect( jd.job, &QgsMapRendererJob::finished, this, &QgsTerrainTextureGenerator::onRenderingFinished );
68  jd.job->deleteLater();
69  mJobs.remove( jd.job );
70  return;
71  }
72  }
73  Q_ASSERT( false && "requested job ID does not exist!" );
74 }
75 
76 QImage QgsTerrainTextureGenerator::renderSynchronously( const QgsRectangle &extent, const QString &debugText )
77 {
78  QgsMapSettings mapSettings( baseMapSettings() );
79  mapSettings.setExtent( extent );
80 
81  QImage img = QImage( mapSettings.outputSize(), mapSettings.outputImageFormat() );
82  img.setDotsPerMeterX( 1000 * mapSettings.outputDpi() / 25.4 );
83  img.setDotsPerMeterY( 1000 * mapSettings.outputDpi() / 25.4 );
84  img.fill( Qt::transparent );
85 
86  QPainter p( &img );
87 
88  QgsMapRendererCustomPainterJob job( mapSettings, &p );
89  job.renderSynchronously();
90 
91  if ( mMap.showTerrainTilesInfo() )
92  {
93  // extra tile information for debugging
94  p.setPen( Qt::white );
95  p.drawRect( 0, 0, img.width() - 1, img.height() - 1 );
96  p.drawText( img.rect(), debugText, QTextOption( Qt::AlignCenter ) );
97  }
98 
99  p.end();
100 
101  return img;
102 }
103 
104 
105 void QgsTerrainTextureGenerator::onRenderingFinished()
106 {
107  QgsMapRendererSequentialJob *mapJob = static_cast<QgsMapRendererSequentialJob *>( sender() );
108 
109  Q_ASSERT( mJobs.contains( mapJob ) );
110  JobData jobData = mJobs.value( mapJob );
111 
112  QImage img = mapJob->renderedImage();
113 
114  if ( mMap.showTerrainTilesInfo() )
115  {
116  // extra tile information for debugging
117  QPainter p( &img );
118  p.setPen( Qt::white );
119  p.drawRect( 0, 0, img.width() - 1, img.height() - 1 );
120  p.drawText( img.rect(), jobData.debugText, QTextOption( Qt::AlignCenter ) );
121  p.end();
122  }
123 
124  mapJob->deleteLater();
125  mJobs.remove( mapJob );
126 
127  //qDebug() << "finished job " << jobData.jobId << " ... in queue: " << jobs.count();
128 
129  QgsEventTracing::addEvent( QgsEventTracing::AsyncEnd, QStringLiteral( "3D" ), QStringLiteral( "Texture" ), jobData.tileId.text() );
130 
131  // pass QImage further
132  emit tileReady( jobData.jobId, img );
133 }
134 
135 QgsMapSettings QgsTerrainTextureGenerator::baseMapSettings()
136 {
137  QgsMapSettings mapSettings;
138 
139  mapSettings.setOutputSize( QSize( mMap.mapTileResolution(), mMap.mapTileResolution() ) );
140  mapSettings.setDestinationCrs( mMap.crs() );
141  mapSettings.setBackgroundColor( mMap.backgroundColor() );
142  mapSettings.setFlag( QgsMapSettings::DrawLabeling, mMap.showLabels() );
143  mapSettings.setTransformContext( mMap.transformContext() );
144  mapSettings.setPathResolver( mMap.pathResolver() );
145 
146  QgsMapThemeCollection *mapThemes = mMap.mapThemeCollection();
147  QString mapThemeName = mMap.terrainMapTheme();
148  if ( mapThemeName.isEmpty() || !mapThemes || !mapThemes->hasMapTheme( mapThemeName ) )
149  {
150  mapSettings.setLayers( mMap.layers() );
151  }
152  else
153  {
154  mapSettings.setLayers( mapThemes->mapThemeVisibleLayers( mapThemeName ) );
155  mapSettings.setLayerStyleOverrides( mapThemes->mapThemeStyleOverrides( mapThemeName ) );
156  }
157 
158  return mapSettings;
159 }
160 
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.
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...