QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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  , mTextureSize( QSize( mMap.mapTileResolution(), mMap.mapTileResolution() ) )
34 {
35 }
36 
37 int QgsTerrainTextureGenerator::render( const QgsRectangle &extent, QgsChunkNodeId tileId, const QString &debugText )
38 {
39  QgsMapSettings mapSettings( baseMapSettings() );
40  mapSettings.setExtent( extent );
41 
42  QList<QgsMapLayer *> layers = mMap.layers();
43  QList<QgsMapLayer *> toBeRenderedLayers;
44  for ( QgsMapLayer *l : layers )
45  {
46  if ( l->renderer3D() == nullptr )
47  toBeRenderedLayers.push_back( l );
48  }
49  mapSettings.setLayers( toBeRenderedLayers );
50 
51  QgsEventTracing::addEvent( QgsEventTracing::AsyncBegin, QStringLiteral( "3D" ), QStringLiteral( "Texture" ), tileId.text() );
52 
54  connect( job, &QgsMapRendererJob::finished, this, &QgsTerrainTextureGenerator::onRenderingFinished );
55 
56  JobData jobData;
57  jobData.jobId = ++mLastJobId;
58  jobData.tileId = tileId;
59  jobData.job = job;
60  jobData.extent = extent;
61  jobData.debugText = debugText;
62 
63  mJobs.insert( job, jobData ); //store job data just before launching the job
64  job->start();
65 
66  // QgsDebugMsgLevel( QStringLiteral("added job: %1 .... in queue: %2").arg( jobData.jobId ).arg( jobs.count() ), 2);
67  return jobData.jobId;
68 }
69 
70 void QgsTerrainTextureGenerator::cancelJob( int jobId )
71 {
72  for ( const JobData &jd : std::as_const( mJobs ) )
73  {
74  if ( jd.jobId == jobId )
75  {
76  // QgsDebugMsgLevel( QStringLiteral("canceling job %1").arg( jobId ), 2 );
77  jd.job->cancelWithoutBlocking();
78  disconnect( jd.job, &QgsMapRendererJob::finished, this, &QgsTerrainTextureGenerator::onRenderingFinished );
79  jd.job->deleteLater();
80  mJobs.remove( jd.job );
81  return;
82  }
83  }
84  Q_ASSERT( false && "requested job ID does not exist!" );
85 }
86 
87 void QgsTerrainTextureGenerator::waitForFinished()
88 {
89  for ( QgsMapRendererSequentialJob *job : mJobs.keys() )
90  disconnect( job, &QgsMapRendererJob::finished, this, &QgsTerrainTextureGenerator::onRenderingFinished );
91  QVector<QgsMapRendererSequentialJob *> toBeDeleted;
92  for ( QgsMapRendererSequentialJob *mapJob : mJobs.keys() )
93  {
94  mapJob->waitForFinished();
95  JobData jobData = mJobs.value( mapJob );
96  toBeDeleted.push_back( mapJob );
97 
98  QImage img = mapJob->renderedImage();
99 
100  if ( mMap.showTerrainTilesInfo() )
101  {
102  // extra tile information for debugging
103  QPainter p( &img );
104  p.setPen( Qt::white );
105  p.drawRect( 0, 0, img.width() - 1, img.height() - 1 );
106  p.drawText( img.rect(), jobData.debugText, QTextOption( Qt::AlignCenter ) );
107  p.end();
108  }
109 
110  // pass QImage further
111  emit tileReady( jobData.jobId, img );
112  }
113 
114  for ( QgsMapRendererSequentialJob *mapJob : toBeDeleted )
115  {
116  mJobs.remove( mapJob );
117  mapJob->deleteLater();
118  }
119 }
120 
121 void QgsTerrainTextureGenerator::onRenderingFinished()
122 {
123  QgsMapRendererSequentialJob *mapJob = static_cast<QgsMapRendererSequentialJob *>( sender() );
124 
125  Q_ASSERT( mJobs.contains( mapJob ) );
126  JobData jobData = mJobs.value( mapJob );
127 
128  QImage img = mapJob->renderedImage();
129 
130  if ( mMap.showTerrainTilesInfo() )
131  {
132  // extra tile information for debugging
133  QPainter p( &img );
134  p.setPen( Qt::white );
135  p.drawRect( 0, 0, img.width() - 1, img.height() - 1 );
136  p.drawText( img.rect(), jobData.debugText, QTextOption( Qt::AlignCenter ) );
137  p.end();
138  }
139 
140  mapJob->deleteLater();
141  mJobs.remove( mapJob );
142 
143  // QgsDebugMsgLevel( QStringLiteral("finished job %1 ... in queue: %2").arg( jobData.jobId).arg( jobs.count() ), 2 );
144 
145  QgsEventTracing::addEvent( QgsEventTracing::AsyncEnd, QStringLiteral( "3D" ), QStringLiteral( "Texture" ), jobData.tileId.text() );
146 
147  // pass QImage further
148  emit tileReady( jobData.jobId, img );
149 }
150 
151 QgsMapSettings QgsTerrainTextureGenerator::baseMapSettings()
152 {
153  QgsMapSettings mapSettings;
154 
155  mapSettings.setOutputSize( mTextureSize );
156  mapSettings.setDestinationCrs( mMap.crs() );
157  mapSettings.setBackgroundColor( mMap.backgroundColor() );
158  mapSettings.setFlag( Qgis::MapSettingsFlag::DrawLabeling, mMap.showLabels() );
160  mapSettings.setTransformContext( mMap.transformContext() );
161  mapSettings.setPathResolver( mMap.pathResolver() );
162  mapSettings.setRendererUsage( mMap.rendererUsage() );
163 
164  QgsMapThemeCollection *mapThemes = mMap.mapThemeCollection();
165  QString mapThemeName = mMap.terrainMapTheme();
166  if ( mapThemeName.isEmpty() || !mapThemes || !mapThemes->hasMapTheme( mapThemeName ) )
167  {
168  mapSettings.setLayers( mMap.layers() );
169  }
170  else
171  {
172  mapSettings.setLayers( mapThemes->mapThemeVisibleLayers( mapThemeName ) );
173  mapSettings.setLayerStyleOverrides( mapThemes->mapThemeStyleOverrides( mapThemeName ) );
174  }
175 
176  return mapSettings;
177 }
178 
QgsMapSettings::setDestinationCrs
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination crs (coordinate reference system) for the map render.
Definition: qgsmapsettings.cpp:350
QgsMapSettings::setFlag
void setFlag(Qgis::MapSettingsFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
Definition: qgsmapsettings.cpp:382
qgsmapthemecollection.h
Qgis::MapSettingsFlag::DrawLabeling
@ DrawLabeling
Enable drawing of labels on top of the map.
qgsmaprenderercustompainterjob.h
qgsmapsettings.h
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsMapThemeCollection::mapThemeVisibleLayers
QList< QgsMapLayer * > mapThemeVisibleLayers(const QString &name) const
Returns the list of layers that are visible for the specified map theme.
Definition: qgsmapthemecollection.cpp:331
QgsMapThemeCollection::mapThemeStyleOverrides
QMap< QString, QString > mapThemeStyleOverrides(const QString &name)
Gets layer style overrides (for QgsMapSettings) of the visible layers for given map theme.
Definition: qgsmapthemecollection.cpp:385
qgseventtracing.h
QgsMapRendererJob::start
void start()
Start the rendering job and immediately return.
QgsMapSettings::setBackgroundColor
void setBackgroundColor(const QColor &color)
Sets the background color of the map.
Definition: qgsmapsettings.h:381
QgsMapRendererSequentialJob
Job implementation that renders everything sequentially in one thread.
Definition: qgsmaprenderersequentialjob.h:33
Qgs3DMapSettings
Definition of the world.
Definition: qgs3dmapsettings.h:57
Qgis::MapSettingsFlag::Render3DMap
@ Render3DMap
Render is for a 3D map.
QgsMapSettings::setTransformContext
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
Definition: qgsmapsettings.cpp:473
QgsMapSettings::setLayers
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
Definition: qgsmapsettings.cpp:327
qgsmaprenderersequentialjob.h
qgs3dmapsettings.h
QgsMapSettings::setLayerStyleOverrides
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the map of map layer style overrides (key: layer ID, value: style name) where a different style ...
Definition: qgsmapsettings.cpp:345
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
QgsMapThemeCollection::hasMapTheme
bool hasMapTheme(const QString &name) const
Returns whether a map theme with a matching name exists.
Definition: qgsmapthemecollection.cpp:257
QgsMapThemeCollection
Container class that allows storage of map themes consisting of visible map layers and layer styles.
Definition: qgsmapthemecollection.h:44
qgsterraintexturegenerator_p.h
QgsMapSettings::setOutputSize
void setOutputSize(QSize size)
Sets the size of the resulting map image, in pixels.
Definition: qgsmapsettings.cpp:244
QgsMapSettings::setPathResolver
void setPathResolver(const QgsPathResolver &resolver)
Sets the path resolver for conversion between relative and absolute paths during rendering operations...
Definition: qgsmapsettings.h:525
QgsMapSettings
The QgsMapSettings class contains configuration for rendering of the map. The rendering itself is don...
Definition: qgsmapsettings.h:88
QgsMapSettings::setRendererUsage
void setRendererUsage(Qgis::RendererUsage rendererUsage)
Sets the rendering usage.
Definition: qgsmapsettings.cpp:863
qgsproject.h
QgsMapRendererSequentialJob::renderedImage
QImage renderedImage() override
Gets a preview/resulting image.
Definition: qgsmaprenderersequentialjob.cpp:124
QgsMapRendererJob::finished
void finished()
emitted when asynchronous rendering is finished (or canceled).