QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgs3dmapsettings.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgs3dmapsettings.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 
16 #include "qgs3dmapsettings.h"
17 
18 #include "qgs3dutils.h"
20 #include "qgsdemterraingenerator.h"
21 #include "qgsmeshterraingenerator.h"
24 #include "qgsmeshlayer3drenderer.h"
26 
27 #include <QDomDocument>
28 #include <QDomElement>
29 
30 #include "qgssymbollayerutils.h"
31 #include "qgsrasterlayer.h"
32 
34  : QObject( nullptr )
35  , QgsTemporalRangeObject( other )
36  , mOrigin( other.mOrigin )
37  , mCrs( other.mCrs )
38  , mBackgroundColor( other.mBackgroundColor )
39  , mSelectionColor( other.mSelectionColor )
40  , mTerrainVerticalScale( other.mTerrainVerticalScale )
41  , mTerrainGenerator( other.mTerrainGenerator ? other.mTerrainGenerator->clone() : nullptr )
42  , mMapTileResolution( other.mMapTileResolution )
43  , mMaxTerrainScreenError( other.mMaxTerrainScreenError )
44  , mMaxTerrainGroundError( other.mMaxTerrainGroundError )
45  , mTerrainElevationOffset( other.mTerrainElevationOffset )
46  , mTerrainShadingEnabled( other.mTerrainShadingEnabled )
47  , mTerrainShadingMaterial( other.mTerrainShadingMaterial )
48  , mTerrainMapTheme( other.mTerrainMapTheme )
49  , mShowTerrainBoundingBoxes( other.mShowTerrainBoundingBoxes )
50  , mShowTerrainTileInfo( other.mShowTerrainTileInfo )
51  , mShowCameraViewCenter( other.mShowCameraViewCenter )
52  , mShowLightSources( other.mShowLightSources )
53  , mShowLabels( other.mShowLabels )
54  , mPointLights( other.mPointLights )
55  , mDirectionalLights( other.mDirectionalLights )
56  , mFieldOfView( other.mFieldOfView )
57  , mProjectionType( other.mProjectionType )
58  , mCameraNavigationMode( other.mCameraNavigationMode )
59  , mCameraMovementSpeed( other.mCameraMovementSpeed )
60  , mLayers( other.mLayers )
61  , mTerrainLayers( other.mTerrainLayers )
62  , mRenderers() // initialized in body
63  , mTransformContext( other.mTransformContext )
64  , mPathResolver( other.mPathResolver )
65  , mMapThemes( other.mMapThemes )
66  , mDpi( other.mDpi )
67  , mIsFpsCounterEnabled( other.mIsFpsCounterEnabled )
68  , mIsSkyboxEnabled( other.mIsSkyboxEnabled )
69  , mSkyboxSettings( other.mSkyboxSettings )
70  , mShadowSettings( other.mShadowSettings )
71  , mEyeDomeLightingEnabled( other.mEyeDomeLightingEnabled )
72  , mEyeDomeLightingStrength( other.mEyeDomeLightingStrength )
73  , mEyeDomeLightingDistance( other.mEyeDomeLightingDistance )
74  , mDebugShadowMapEnabled( other.mDebugShadowMapEnabled )
75  , mDebugShadowMapCorner( other.mDebugShadowMapCorner )
76  , mDebugShadowMapSize( other.mDebugShadowMapSize )
77  , mDebugDepthMapEnabled( other.mDebugDepthMapEnabled )
78  , mDebugDepthMapCorner( other.mDebugDepthMapCorner )
79  , mDebugDepthMapSize( other.mDebugDepthMapSize )
80 {
81  for ( QgsAbstract3DRenderer *renderer : std::as_const( other.mRenderers ) )
82  {
83  mRenderers << renderer->clone();
84  }
85 }
86 
88 {
89  qDeleteAll( mRenderers );
90 }
91 
92 void Qgs3DMapSettings::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
93 {
94  QDomElement elemOrigin = elem.firstChildElement( QStringLiteral( "origin" ) );
95  mOrigin = QgsVector3D(
96  elemOrigin.attribute( QStringLiteral( "x" ) ).toDouble(),
97  elemOrigin.attribute( QStringLiteral( "y" ) ).toDouble(),
98  elemOrigin.attribute( QStringLiteral( "z" ) ).toDouble() );
99 
100  QDomElement elemCamera = elem.firstChildElement( QStringLiteral( "camera" ) );
101  if ( !elemCamera.isNull() )
102  {
103  mFieldOfView = elemCamera.attribute( QStringLiteral( "field-of-view" ), QStringLiteral( "45" ) ).toFloat();
104  mProjectionType = static_cast< Qt3DRender::QCameraLens::ProjectionType >( elemCamera.attribute( QStringLiteral( "projection-type" ), QStringLiteral( "1" ) ).toInt() );
105  QString cameraNavigationMode = elemCamera.attribute( QStringLiteral( "camera-navigation-mode" ), QStringLiteral( "basic-navigation" ) );
106  if ( cameraNavigationMode == QLatin1String( "terrain-based-navigation" ) )
107  mCameraNavigationMode = QgsCameraController::NavigationMode::TerrainBasedNavigation;
108  else if ( cameraNavigationMode == QLatin1String( "walk-navigation" ) )
109  mCameraNavigationMode = QgsCameraController::NavigationMode::WalkNavigation;
110  mCameraMovementSpeed = elemCamera.attribute( QStringLiteral( "camera-movement-speed" ), QStringLiteral( "5.0" ) ).toDouble();
111  }
112 
113  QDomElement elemColor = elem.firstChildElement( QStringLiteral( "color" ) );
114  if ( !elemColor.isNull() )
115  {
116  mBackgroundColor = QgsSymbolLayerUtils::decodeColor( elemColor.attribute( QStringLiteral( "background" ) ) );
117  mSelectionColor = QgsSymbolLayerUtils::decodeColor( elemColor.attribute( QStringLiteral( "selection" ) ) );
118  }
119 
120  QDomElement elemCrs = elem.firstChildElement( QStringLiteral( "crs" ) );
121  mCrs.readXml( elemCrs );
122 
123  QDomElement elemTerrain = elem.firstChildElement( QStringLiteral( "terrain" ) );
124  mTerrainVerticalScale = elemTerrain.attribute( QStringLiteral( "exaggeration" ), QStringLiteral( "1" ) ).toFloat();
125  mMapTileResolution = elemTerrain.attribute( QStringLiteral( "texture-size" ), QStringLiteral( "512" ) ).toInt();
126  mMaxTerrainScreenError = elemTerrain.attribute( QStringLiteral( "max-terrain-error" ), QStringLiteral( "3" ) ).toFloat();
127  mMaxTerrainGroundError = elemTerrain.attribute( QStringLiteral( "max-ground-error" ), QStringLiteral( "1" ) ).toFloat();
128  mTerrainShadingEnabled = elemTerrain.attribute( QStringLiteral( "shading-enabled" ), QStringLiteral( "0" ) ).toInt();
129  mTerrainElevationOffset = elemTerrain.attribute( QStringLiteral( "elevation-offset" ), QStringLiteral( "0.0" ) ).toFloat();
130 
131  QDomElement elemTerrainShadingMaterial = elemTerrain.firstChildElement( QStringLiteral( "shading-material" ) );
132  if ( !elemTerrainShadingMaterial.isNull() )
133  mTerrainShadingMaterial.readXml( elemTerrainShadingMaterial, context );
134  mTerrainMapTheme = elemTerrain.attribute( QStringLiteral( "map-theme" ) );
135  mShowLabels = elemTerrain.attribute( QStringLiteral( "show-labels" ), QStringLiteral( "0" ) ).toInt();
136 
137  mPointLights.clear();
138  QDomElement elemPointLights = elem.firstChildElement( QStringLiteral( "point-lights" ) );
139  if ( !elemPointLights.isNull() )
140  {
141  QDomElement elemPointLight = elemPointLights.firstChildElement( QStringLiteral( "point-light" ) );
142  while ( !elemPointLight.isNull() )
143  {
144  QgsPointLightSettings pointLight;
145  pointLight.readXml( elemPointLight );
146  mPointLights << pointLight;
147  elemPointLight = elemPointLight.nextSiblingElement( QStringLiteral( "point-light" ) );
148  }
149  }
150  else
151  {
152  // QGIS <= 3.4 did not have light configuration
153  QgsPointLightSettings defaultLight;
154  defaultLight.setPosition( QgsVector3D( 0, 1000, 0 ) );
155  mPointLights << defaultLight;
156  }
157 
158  mDirectionalLights.clear();
159  QDomElement elemDirectionalLights = elem.firstChildElement( QStringLiteral( "directional-lights" ) );
160  if ( !elemDirectionalLights.isNull() )
161  {
162  QDomElement elemDirectionalLight = elemDirectionalLights.firstChildElement( QStringLiteral( "directional-light" ) );
163  while ( !elemDirectionalLight.isNull() )
164  {
165  QgsDirectionalLightSettings directionalLight;
166  directionalLight.readXml( elemDirectionalLight );
167  mDirectionalLights << directionalLight;
168  elemDirectionalLight = elemDirectionalLight.nextSiblingElement( QStringLiteral( "directional-light" ) );
169  }
170  }
171 
172  QDomElement elemMapLayers = elemTerrain.firstChildElement( QStringLiteral( "layers" ) );
173  QDomElement elemMapLayer = elemMapLayers.firstChildElement( QStringLiteral( "layer" ) );
174  QList<QgsMapLayerRef> mapLayers;
175  while ( !elemMapLayer.isNull() )
176  {
177  mapLayers << QgsMapLayerRef( elemMapLayer.attribute( QStringLiteral( "id" ) ) );
178  elemMapLayer = elemMapLayer.nextSiblingElement( QStringLiteral( "layer" ) );
179  }
180  mLayers = mapLayers; // needs to resolve refs afterwards
181 
182  QDomElement elemTerrainLayers = elemTerrain.firstChildElement( QStringLiteral( "terrainLayers" ) );
183  if ( elemTerrainLayers.isNull() )
184  {
185  mTerrainLayers = mLayers;
186  }
187  else
188  {
189  QDomElement elemTerrainMapLayer = elemTerrainLayers.firstChildElement( QStringLiteral( "layer" ) );
190  QList<QgsMapLayerRef> terrainMapLayers;
191  while ( !elemTerrainMapLayer.isNull() )
192  {
193  terrainMapLayers << QgsMapLayerRef( elemTerrainMapLayer.attribute( QStringLiteral( "id" ) ) );
194  elemTerrainMapLayer = elemTerrainMapLayer.nextSiblingElement( QStringLiteral( "layer" ) );
195  }
196  mTerrainLayers = mapLayers; // needs to resolve refs afterwards
197  }
198 
199  QDomElement elemTerrainGenerator = elemTerrain.firstChildElement( QStringLiteral( "generator" ) );
200  QString terrainGenType = elemTerrainGenerator.attribute( QStringLiteral( "type" ) );
201  if ( terrainGenType == QLatin1String( "dem" ) )
202  {
203  QgsDemTerrainGenerator *demTerrainGenerator = new QgsDemTerrainGenerator;
204  demTerrainGenerator->setCrs( mCrs, mTransformContext );
205  mTerrainGenerator.reset( demTerrainGenerator );
206  }
207  else if ( terrainGenType == QLatin1String( "online" ) )
208  {
209  QgsOnlineTerrainGenerator *onlineTerrainGenerator = new QgsOnlineTerrainGenerator;
210  onlineTerrainGenerator->setCrs( mCrs, mTransformContext );
211  mTerrainGenerator.reset( onlineTerrainGenerator );
212  }
213  else if ( terrainGenType == QLatin1String( "mesh" ) )
214  {
215  QgsMeshTerrainGenerator *meshTerrainGenerator = new QgsMeshTerrainGenerator;
216  meshTerrainGenerator->setCrs( mCrs, mTransformContext );
217  mTerrainGenerator.reset( meshTerrainGenerator );
218  }
219  else // "flat"
220  {
222  flatGen->setCrs( mCrs );
223  mTerrainGenerator.reset( flatGen );
224  }
225  mTerrainGenerator->readXml( elemTerrainGenerator );
226 
227  qDeleteAll( mRenderers );
228  mRenderers.clear();
229 
230  QDomElement elemRenderers = elem.firstChildElement( QStringLiteral( "renderers" ) );
231  QDomElement elemRenderer = elemRenderers.firstChildElement( QStringLiteral( "renderer" ) );
232  while ( !elemRenderer.isNull() )
233  {
234  QgsAbstract3DRenderer *renderer = nullptr;
235  QString type = elemRenderer.attribute( QStringLiteral( "type" ) );
236  if ( type == QLatin1String( "vector" ) )
237  {
238  renderer = new QgsVectorLayer3DRenderer;
239  }
240  else if ( type == QLatin1String( "mesh" ) )
241  {
242  renderer = new QgsMeshLayer3DRenderer;
243  }
244  else if ( type == QLatin1String( "pointcloud" ) )
245  {
246  renderer = new QgsPointCloudLayer3DRenderer;
247  }
248 
249  if ( renderer )
250  {
251  renderer->readXml( elemRenderer, context );
252  mRenderers.append( renderer );
253  }
254  elemRenderer = elemRenderer.nextSiblingElement( QStringLiteral( "renderer" ) );
255  }
256 
257  QDomElement elemSkybox = elem.firstChildElement( QStringLiteral( "skybox" ) );
258  mIsSkyboxEnabled = elemSkybox.attribute( QStringLiteral( "skybox-enabled" ) ).toInt();
259  mSkyboxSettings.readXml( elemSkybox, context );
260 
261  QDomElement elemShadows = elem.firstChildElement( QStringLiteral( "shadow-rendering" ) );
262  mShadowSettings.readXml( elemShadows, context );
263 
264  QDomElement elemEyeDomeLighting = elem.firstChildElement( QStringLiteral( "eye-dome-lighting" ) );
265  mEyeDomeLightingEnabled = elemEyeDomeLighting.attribute( "enabled", QStringLiteral( "0" ) ).toInt();
266  mEyeDomeLightingStrength = elemEyeDomeLighting.attribute( "eye-dome-lighting-strength", QStringLiteral( "1000.0" ) ).toDouble();
267  mEyeDomeLightingDistance = elemEyeDomeLighting.attribute( "eye-dome-lighting-distance", QStringLiteral( "1" ) ).toInt();
268 
269  QDomElement elemDebugSettings = elem.firstChildElement( QStringLiteral( "debug-settings" ) );
270  mDebugShadowMapEnabled = elemDebugSettings.attribute( QStringLiteral( "shadowmap-enabled" ), QStringLiteral( "0" ) ).toInt();
271  mDebugShadowMapCorner = static_cast<Qt::Corner>( elemDebugSettings.attribute( QStringLiteral( "shadowmap-corner" ), "0" ).toInt() );
272  mDebugShadowMapSize = elemDebugSettings.attribute( QStringLiteral( "shadowmap-size" ), QStringLiteral( "0.2" ) ).toDouble();
273 
274  mDebugDepthMapEnabled = elemDebugSettings.attribute( QStringLiteral( "depthmap-enabled" ), QStringLiteral( "0" ) ).toInt();
275  mDebugDepthMapCorner = static_cast<Qt::Corner>( elemDebugSettings.attribute( QStringLiteral( "depthmap-corner" ), QStringLiteral( "1" ) ).toInt() );
276  mDebugDepthMapSize = elemDebugSettings.attribute( QStringLiteral( "depthmap-size" ), QStringLiteral( "0.2" ) ).toDouble();
277 
278  QDomElement elemDebug = elem.firstChildElement( QStringLiteral( "debug" ) );
279  mShowTerrainBoundingBoxes = elemDebug.attribute( QStringLiteral( "bounding-boxes" ), QStringLiteral( "0" ) ).toInt();
280  mShowTerrainTileInfo = elemDebug.attribute( QStringLiteral( "terrain-tile-info" ), QStringLiteral( "0" ) ).toInt();
281  mShowCameraViewCenter = elemDebug.attribute( QStringLiteral( "camera-view-center" ), QStringLiteral( "0" ) ).toInt();
282  mShowLightSources = elemDebug.attribute( QStringLiteral( "show-light-sources" ), QStringLiteral( "0" ) ).toInt();
283  mIsFpsCounterEnabled = elemDebug.attribute( QStringLiteral( "show-fps-counter" ), QStringLiteral( "0" ) ).toInt();
284 
285  QDomElement elemTemporalRange = elem.firstChildElement( QStringLiteral( "temporal-range" ) );
286  QDateTime start = QDateTime::fromString( elemTemporalRange.attribute( QStringLiteral( "start" ) ), Qt::ISODate );
287  QDateTime end = QDateTime::fromString( elemTemporalRange.attribute( QStringLiteral( "end" ) ), Qt::ISODate );
288  setTemporalRange( QgsDateTimeRange( start, end ) );
289 }
290 
291 QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
292 {
293  QDomElement elem = doc.createElement( QStringLiteral( "qgis3d" ) );
294 
295  QDomElement elemOrigin = doc.createElement( QStringLiteral( "origin" ) );
296  elemOrigin.setAttribute( QStringLiteral( "x" ), QString::number( mOrigin.x() ) );
297  elemOrigin.setAttribute( QStringLiteral( "y" ), QString::number( mOrigin.y() ) );
298  elemOrigin.setAttribute( QStringLiteral( "z" ), QString::number( mOrigin.z() ) );
299  elem.appendChild( elemOrigin );
300 
301  QDomElement elemCamera = doc.createElement( QStringLiteral( "camera" ) );
302  elemCamera.setAttribute( QStringLiteral( "field-of-view" ), mFieldOfView );
303  elemCamera.setAttribute( QStringLiteral( "projection-type" ), static_cast< int >( mProjectionType ) );
304  switch ( mCameraNavigationMode )
305  {
307  elemCamera.setAttribute( QStringLiteral( "camera-navigation-mode" ), QStringLiteral( "terrain-based-navigation" ) );
308  break;
310  elemCamera.setAttribute( QStringLiteral( "camera-navigation-mode" ), QStringLiteral( "walk-navigation" ) );
311  break;
312  }
313  elemCamera.setAttribute( QStringLiteral( "camera-movement-speed" ), mCameraMovementSpeed );
314  elem.appendChild( elemCamera );
315 
316  QDomElement elemColor = doc.createElement( QStringLiteral( "color" ) );
317  elemColor.setAttribute( QStringLiteral( "background" ), QgsSymbolLayerUtils::encodeColor( mBackgroundColor ) );
318  elemColor.setAttribute( QStringLiteral( "selection" ), QgsSymbolLayerUtils::encodeColor( mSelectionColor ) );
319  elem.appendChild( elemColor );
320 
321  QDomElement elemCrs = doc.createElement( QStringLiteral( "crs" ) );
322  mCrs.writeXml( elemCrs, doc );
323  elem.appendChild( elemCrs );
324 
325  QDomElement elemTerrain = doc.createElement( QStringLiteral( "terrain" ) );
326  elemTerrain.setAttribute( QStringLiteral( "exaggeration" ), QString::number( mTerrainVerticalScale ) );
327  elemTerrain.setAttribute( QStringLiteral( "texture-size" ), mMapTileResolution );
328  elemTerrain.setAttribute( QStringLiteral( "max-terrain-error" ), QString::number( mMaxTerrainScreenError ) );
329  elemTerrain.setAttribute( QStringLiteral( "max-ground-error" ), QString::number( mMaxTerrainGroundError ) );
330  elemTerrain.setAttribute( QStringLiteral( "shading-enabled" ), mTerrainShadingEnabled ? 1 : 0 );
331  elemTerrain.setAttribute( QStringLiteral( "elevation-offset" ), mTerrainElevationOffset );
332 
333  QDomElement elemTerrainShadingMaterial = doc.createElement( QStringLiteral( "shading-material" ) );
334  mTerrainShadingMaterial.writeXml( elemTerrainShadingMaterial, context );
335  elemTerrain.appendChild( elemTerrainShadingMaterial );
336  elemTerrain.setAttribute( QStringLiteral( "map-theme" ), mTerrainMapTheme );
337  elemTerrain.setAttribute( QStringLiteral( "show-labels" ), mShowLabels ? 1 : 0 );
338 
339  QDomElement elemPointLights = doc.createElement( QStringLiteral( "point-lights" ) );
340  for ( const QgsPointLightSettings &pointLight : std::as_const( mPointLights ) )
341  {
342  QDomElement elemPointLight = pointLight.writeXml( doc );
343  elemPointLights.appendChild( elemPointLight );
344  }
345  elem.appendChild( elemPointLights );
346 
347  QDomElement elemDirectionalLights = doc.createElement( QStringLiteral( "directional-lights" ) );
348  for ( const QgsDirectionalLightSettings &directionalLight : std::as_const( mDirectionalLights ) )
349  {
350  QDomElement elemDirectionalLight = directionalLight.writeXml( doc );
351  elemDirectionalLights.appendChild( elemDirectionalLight );
352  }
353  elem.appendChild( elemDirectionalLights );
354 
355  QDomElement elemMapLayers = doc.createElement( QStringLiteral( "layers" ) );
356  for ( const QgsMapLayerRef &layerRef : mLayers )
357  {
358  QDomElement elemMapLayer = doc.createElement( QStringLiteral( "layer" ) );
359  elemMapLayer.setAttribute( QStringLiteral( "id" ), layerRef.layerId );
360  elemMapLayers.appendChild( elemMapLayer );
361  }
362  elemTerrain.appendChild( elemMapLayers );
363 
364  QDomElement elemTerrainMapLayers = doc.createElement( QStringLiteral( "terrainLayers" ) );
365  for ( const QgsMapLayerRef &layerRef : mTerrainLayers )
366  {
367  QDomElement elemMapLayer = doc.createElement( QStringLiteral( "layer" ) );
368  elemMapLayer.setAttribute( QStringLiteral( "id" ), layerRef.layerId );
369  elemTerrainMapLayers.appendChild( elemMapLayer );
370  }
371  elemTerrain.appendChild( elemTerrainMapLayers );
372 
373  QDomElement elemTerrainGenerator = doc.createElement( QStringLiteral( "generator" ) );
374  elemTerrainGenerator.setAttribute( QStringLiteral( "type" ), QgsTerrainGenerator::typeToString( mTerrainGenerator->type() ) );
375  mTerrainGenerator->writeXml( elemTerrainGenerator );
376  elemTerrain.appendChild( elemTerrainGenerator );
377  elem.appendChild( elemTerrain );
378 
379  QDomElement elemRenderers = doc.createElement( QStringLiteral( "renderers" ) );
380  for ( const QgsAbstract3DRenderer *renderer : mRenderers )
381  {
382  QDomElement elemRenderer = doc.createElement( QStringLiteral( "renderer" ) );
383  elemRenderer.setAttribute( QStringLiteral( "type" ), renderer->type() );
384  renderer->writeXml( elemRenderer, context );
385  elemRenderers.appendChild( elemRenderer );
386  }
387  elem.appendChild( elemRenderers );
388 
389  QDomElement elemSkybox = doc.createElement( QStringLiteral( "skybox" ) );
390  elemSkybox.setAttribute( QStringLiteral( "skybox-enabled" ), mIsSkyboxEnabled );
391  mSkyboxSettings.writeXml( elemSkybox, context );
392  elem.appendChild( elemSkybox );
393 
394  QDomElement elemShadows = doc.createElement( QStringLiteral( "shadow-rendering" ) );
395  mShadowSettings.writeXml( elemShadows, context );
396  elem.appendChild( elemShadows );
397 
398  QDomElement elemDebug = doc.createElement( QStringLiteral( "debug" ) );
399  elemDebug.setAttribute( QStringLiteral( "bounding-boxes" ), mShowTerrainBoundingBoxes ? 1 : 0 );
400  elemDebug.setAttribute( QStringLiteral( "terrain-tile-info" ), mShowTerrainTileInfo ? 1 : 0 );
401  elemDebug.setAttribute( QStringLiteral( "camera-view-center" ), mShowCameraViewCenter ? 1 : 0 );
402  elemDebug.setAttribute( QStringLiteral( "show-light-sources" ), mShowLightSources ? 1 : 0 );
403  elemDebug.setAttribute( QStringLiteral( "show-fps-counter" ), mIsFpsCounterEnabled ? 1 : 0 );
404  elem.appendChild( elemDebug );
405 
406  QDomElement elemEyeDomeLighting = doc.createElement( QStringLiteral( "eye-dome-lighting" ) );
407  elemEyeDomeLighting.setAttribute( "enabled", mEyeDomeLightingEnabled ? 1 : 0 );
408  elemEyeDomeLighting.setAttribute( "eye-dome-lighting-strength", mEyeDomeLightingStrength );
409  elemEyeDomeLighting.setAttribute( "eye-dome-lighting-distance", mEyeDomeLightingDistance );
410  elem.appendChild( elemEyeDomeLighting );
411 
412 
413  QDomElement elemDebugSettings = doc.createElement( QStringLiteral( "debug-settings" ) );
414  elemDebugSettings.setAttribute( QStringLiteral( "shadowmap-enabled" ), mDebugShadowMapEnabled );
415  elemDebugSettings.setAttribute( QStringLiteral( "shadowmap-corner" ), mDebugShadowMapCorner );
416  elemDebugSettings.setAttribute( QStringLiteral( "shadowmap-size" ), mDebugShadowMapSize );
417  elemDebugSettings.setAttribute( QStringLiteral( "depthmap-enabled" ), mDebugDepthMapEnabled );
418  elemDebugSettings.setAttribute( QStringLiteral( "depthmap-corner" ), mDebugDepthMapCorner );
419  elemDebugSettings.setAttribute( QStringLiteral( "depthmap-size" ), mDebugDepthMapSize );
420  elem.appendChild( elemDebugSettings );
421 
422  QDomElement elemTemporalRange = doc.createElement( QStringLiteral( "temporal-range" ) );
423  elemTemporalRange.setAttribute( QStringLiteral( "start" ), temporalRange().begin().toString( Qt::ISODate ) );
424  elemTemporalRange.setAttribute( QStringLiteral( "end" ), temporalRange().end().toString( Qt::ISODate ) );
425 
426  return elem;
427 }
428 
430 {
431  for ( int i = 0; i < mLayers.count(); ++i )
432  {
433  QgsMapLayerRef &layerRef = mLayers[i];
434  layerRef.setLayer( project.mapLayer( layerRef.layerId ) );
435  }
436  for ( int i = 0; i < mTerrainLayers.count(); ++i )
437  {
438  QgsMapLayerRef &layerRef = mTerrainLayers[i];
439  layerRef.setLayer( project.mapLayer( layerRef.layerId ) );
440  }
441 
442  mTerrainGenerator->resolveReferences( project );
443 
444  for ( int i = 0; i < mRenderers.count(); ++i )
445  {
446  QgsAbstract3DRenderer *renderer = mRenderers[i];
447  renderer->resolveReferences( project );
448  }
449 }
450 
452 {
453  return Qgs3DUtils::mapToWorldCoordinates( mapCoords, mOrigin );
454 }
455 
457 {
458  return Qgs3DUtils::worldToMapCoordinates( worldCoords, mOrigin );
459 }
460 
462 {
463  mCrs = crs;
464 }
465 
467 {
468  return mTransformContext;
469 }
470 
472 {
473  mTransformContext = context;
474 }
475 
476 void Qgs3DMapSettings::setBackgroundColor( const QColor &color )
477 {
478  if ( color == mBackgroundColor )
479  return;
480 
481  mBackgroundColor = color;
482  emit backgroundColorChanged();
483 }
484 
486 {
487  return mBackgroundColor;
488 }
489 
490 void Qgs3DMapSettings::setSelectionColor( const QColor &color )
491 {
492  if ( color == mSelectionColor )
493  return;
494 
495  mSelectionColor = color;
496  emit selectionColorChanged();
497 }
498 
500 {
501  return mSelectionColor;
502 }
503 
505 {
506  if ( zScale == mTerrainVerticalScale )
507  return;
508 
509  mTerrainVerticalScale = zScale;
511 }
512 
514 {
515  return mTerrainVerticalScale;
516 }
517 
518 void Qgs3DMapSettings::setLayers( const QList<QgsMapLayer *> &layers )
519 {
520  QList<QgsMapLayerRef> lst;
521  lst.reserve( layers.count() );
522  for ( QgsMapLayer *layer : layers )
523  {
524  lst.append( layer );
525  }
526 
527  if ( mLayers == lst )
528  return;
529 
530  mLayers = lst;
531  emit layersChanged();
532 }
533 
534 QList<QgsMapLayer *> Qgs3DMapSettings::layers() const
535 {
536  QList<QgsMapLayer *> lst;
537  lst.reserve( mLayers.count() );
538  for ( const QgsMapLayerRef &layerRef : mLayers )
539  {
540  if ( layerRef.layer )
541  lst.append( layerRef.layer );
542  }
543  return lst;
544 }
545 
546 void Qgs3DMapSettings::setTerrainLayers( const QList<QgsMapLayer *> &layers )
547 {
548  QList<QgsMapLayerRef> lst;
549  lst.reserve( layers.count() );
550  for ( QgsMapLayer *layer : layers )
551  {
552  lst.append( layer );
553  }
554 
555  if ( mTerrainLayers == lst )
556  return;
557 
558  mTerrainLayers = lst;
559  emit terrainLayersChanged();
560 }
561 
562 QList<QgsMapLayer *> Qgs3DMapSettings::terrainLayers() const
563 {
564  QList<QgsMapLayer *> lst;
565  lst.reserve( mTerrainLayers.count() );
566  for ( const QgsMapLayerRef &layerRef : mTerrainLayers )
567  {
568  if ( layerRef.layer )
569  lst.append( layerRef.layer );
570  }
571  return lst;
572 }
573 
575 {
576  if ( mMapTileResolution == res )
577  return;
578 
579  mMapTileResolution = res;
581 }
582 
584 {
585  return mMapTileResolution;
586 }
587 
589 {
590  if ( mMaxTerrainScreenError == error )
591  return;
592 
593  mMaxTerrainScreenError = error;
595 }
596 
598 {
599  return mMaxTerrainScreenError;
600 }
601 
603 {
604  if ( mMaxTerrainGroundError == error )
605  return;
606 
607  mMaxTerrainGroundError = error;
609 }
610 
612 {
613  if ( mTerrainElevationOffset == offset )
614  return;
615  mTerrainElevationOffset = offset;
616  emit terrainElevationOffsetChanged( mTerrainElevationOffset );
617 }
618 
620 {
621  return mMaxTerrainGroundError;
622 }
623 
625 {
626  if ( mTerrainGenerator )
627  {
628  disconnect( mTerrainGenerator.get(), &QgsTerrainGenerator::extentChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );
629  }
630 
631  mTerrainGenerator.reset( gen );
632  connect( mTerrainGenerator.get(), &QgsTerrainGenerator::extentChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );
633 
635 }
636 
638 {
639  if ( mTerrainShadingEnabled == enabled )
640  return;
641 
642  mTerrainShadingEnabled = enabled;
643  emit terrainShadingChanged();
644 }
645 
647 {
648  if ( mTerrainShadingMaterial == material )
649  return;
650 
651  mTerrainShadingMaterial = material;
652  emit terrainShadingChanged();
653 }
654 
655 void Qgs3DMapSettings::setTerrainMapTheme( const QString &theme )
656 {
657  if ( mTerrainMapTheme == theme )
658  return;
659 
660  mTerrainMapTheme = theme;
661  emit terrainMapThemeChanged();
662 }
663 
664 void Qgs3DMapSettings::setRenderers( const QList<QgsAbstract3DRenderer *> &renderers )
665 {
666  qDeleteAll( mRenderers );
667 
668  mRenderers = renderers;
669 
670  emit renderersChanged();
671 }
672 
674 {
675  if ( mShowTerrainBoundingBoxes == enabled )
676  return;
677 
678  mShowTerrainBoundingBoxes = enabled;
680 }
681 
683 {
684  if ( mShowTerrainTileInfo == enabled )
685  return;
686 
687  mShowTerrainTileInfo = enabled;
689 }
690 
692 {
693  if ( mShowCameraViewCenter == enabled )
694  return;
695 
696  mShowCameraViewCenter = enabled;
698 }
699 
701 {
702  if ( mShowLightSources == enabled )
703  return;
704 
705  mShowLightSources = enabled;
707 }
708 
710 {
711  if ( mShowLabels == enabled )
712  return;
713 
714  mShowLabels = enabled;
715  emit showLabelsChanged();
716 }
717 
719 {
720  if ( mEyeDomeLightingEnabled == enabled )
721  return;
722  mEyeDomeLightingEnabled = enabled;
724 }
725 
727 {
728  if ( mEyeDomeLightingStrength == strength )
729  return;
730  mEyeDomeLightingStrength = strength;
732 }
733 
735 {
736  if ( mEyeDomeLightingDistance == distance )
737  return;
738  mEyeDomeLightingDistance = distance;
740 }
741 
742 void Qgs3DMapSettings::setPointLights( const QList<QgsPointLightSettings> &pointLights )
743 {
744  if ( mPointLights == pointLights )
745  return;
746 
747  mPointLights = pointLights;
748  emit pointLightsChanged();
749 }
750 
751 void Qgs3DMapSettings::setDirectionalLights( const QList<QgsDirectionalLightSettings> &directionalLights )
752 {
753  if ( mDirectionalLights == directionalLights )
754  return;
755 
756  mDirectionalLights = directionalLights;
758 }
759 
760 void Qgs3DMapSettings::setFieldOfView( const float fieldOfView )
761 {
762  if ( mFieldOfView == fieldOfView )
763  return;
764 
765  mFieldOfView = fieldOfView;
766  emit fieldOfViewChanged();
767 }
768 
769 void Qgs3DMapSettings::setProjectionType( const Qt3DRender::QCameraLens::ProjectionType projectionType )
770 {
771  if ( mProjectionType == projectionType )
772  return;
773 
774  mProjectionType = projectionType;
775  emit projectionTypeChanged();
776 }
777 
779 {
780  if ( mCameraNavigationMode == navigationMode )
781  return;
782 
783  mCameraNavigationMode = navigationMode;
785 }
786 
787 void Qgs3DMapSettings::setCameraMovementSpeed( double movementSpeed )
788 {
789  if ( mCameraMovementSpeed == movementSpeed )
790  return;
791 
792  mCameraMovementSpeed = movementSpeed;
794 }
795 
797 {
798  mSkyboxSettings = skyboxSettings;
799  emit skyboxSettingsChanged();
800 }
801 
803 {
804  mShadowSettings = shadowSettings;
805  emit shadowSettingsChanged();
806 }
807 
808 void Qgs3DMapSettings::setDebugShadowMapSettings( bool enabled, Qt::Corner corner, double size )
809 {
810  mDebugShadowMapEnabled = enabled;
811  mDebugShadowMapCorner = corner;
812  mDebugShadowMapSize = size;
814 }
815 
816 void Qgs3DMapSettings::setDebugDepthMapSettings( bool enabled, Qt::Corner corner, double size )
817 {
818  mDebugDepthMapEnabled = enabled;
819  mDebugDepthMapCorner = corner;
820  mDebugDepthMapSize = size;
822 }
823 
824 void Qgs3DMapSettings::setIsFpsCounterEnabled( bool fpsCounterEnabled )
825 {
826  if ( fpsCounterEnabled == mIsFpsCounterEnabled )
827  return;
828  mIsFpsCounterEnabled = fpsCounterEnabled;
829  emit fpsCounterEnabledChanged( mIsFpsCounterEnabled );
830 }
void setEyeDomeLightingStrength(double strength)
Sets the eye dome lighting strength value.
void mapTileResolutionChanged()
Emitted when the map tile resoulution has changed.
void terrainVerticalScaleChanged()
Emitted when the vertical scale of the terrain has changed.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context, which stores various information regarding which datum transfo...
void renderersChanged()
Emitted when the list of map's extra renderers have been modified.
QList< QgsAbstract3DRenderer * > renderers() const
Returns list of extra 3D renderers.
void eyeDomeLightingDistanceChanged()
Emitted when the eye dome lighting distance has changed.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Reads configuration from a DOM element previously written by writeXml()
void terrainShadingChanged()
Emitted when terrain shading enabled flag or terrain shading material has changed.
void setShowTerrainTilesInfo(bool enabled)
Sets whether to display extra tile info on top of terrain tiles (for debugging)
QgsVector3D mapToWorldCoordinates(const QgsVector3D &mapCoords) const
Converts map coordinates to 3D world coordinates (applies offset and turns (x,y,z) into (x,...
void setRenderers(const QList< QgsAbstract3DRenderer * > &renderers)
Sets list of extra 3D renderers to use in the scene. Takes ownership of the objects.
Qt3DRender::QCameraLens::ProjectionType projectionType() const
Returns the camera lens' projection type.
void setEyeDomeLightingEnabled(bool enabled)
Sets whether eye dome lighting will be used.
void setFieldOfView(const float fieldOfView)
Sets the camera lens' field of view.
void debugDepthMapSettingsChanged()
Emitted when depth map debugging has changed.
QList< QgsDirectionalLightSettings > directionalLights() const
Returns list of directional lights defined in the scene.
void setPointLights(const QList< QgsPointLightSettings > &pointLights)
Sets list of point lights defined in the scene.
void backgroundColorChanged()
Emitted when the background color has changed.
void showTerrainBoundingBoxesChanged()
Emitted when the flag whether terrain's bounding boxes are shown has changed.
void setDirectionalLights(const QList< QgsDirectionalLightSettings > &directionalLights)
Sets list of directional lights defined in the scene.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Writes configuration to a DOM element, to be used later with readXml()
void setDebugDepthMapSettings(bool enabled, Qt::Corner corner, double size)
Sets the debugging settings of the depth map.
QColor selectionColor() const
Returns color used for selected features.
void directionalLightsChanged()
Emitted when the list of directional lights changes.
void setTerrainShadingMaterial(const QgsPhongMaterialSettings &material)
Sets terrain shading material.
void cameraNavigationModeChanged()
Emitted when the camera navigation mode was changed.
void shadowSettingsChanged()
Emitted when shadow rendering settings are changed.
void terrainLayersChanged()
Emitted when the list of map layers for terrain texture has changed.
float maxTerrainGroundError() const
Returns maximum ground error of terrain tiles in world units.
void eyeDomeLightingEnabledChanged()
Emitted when the flag whether eye dome lighting is used has changed.
void setTerrainVerticalScale(double zScale)
Sets vertical scale (exaggeration) of terrain (1 = true scale, > 1 = hills get more pronounced)
void setShowLabels(bool enabled)
Sets whether to display labels on terrain tiles.
double terrainVerticalScale() const
Returns vertical scale (exaggeration) of terrain.
void setMaxTerrainGroundError(float error)
Returns maximum ground error of terrain tiles in world units.
void setSkyboxSettings(const QgsSkyboxSettings &skyboxSettings)
Sets the current configuration of the skybox.
void skyboxSettingsChanged()
Emitted when skybox settings are changed.
void setMapTileResolution(int res)
Sets resolution (in pixels) of the texture of a terrain tile.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of 3D map layers to be rendered in the scene.
QgsShadowSettings shadowSettings() const
Returns the current configuration of shadows.
void terrainMapThemeChanged()
Emitted when terrain's map theme has changed.
void setShadowSettings(const QgsShadowSettings &shadowSettings)
Sets the current configuration of shadow rendering.
void pointLightsChanged()
Emitted when the list of point lights changes.
void setTerrainElevationOffset(float offset)
Sets the terrain elevation offset (used to move the terrain up or down)
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets coordinate reference system used in the 3D scene.
void setEyeDomeLightingDistance(int distance)
Sets the eye dome lighting distance value (contributes to the contrast of the image.
void setShowLightSourceOrigins(bool enabled)
Sets whether to show light source origins as a sphere (for debugging)
void projectionTypeChanged()
Emitted when the camera lens projection type changes.
float fieldOfView() const
Returns the camera lens' field of view.
void selectionColorChanged()
Emitted when the selection color has changed.
void setTerrainShadingEnabled(bool enabled)
Sets whether terrain shading is enabled.
void setDebugShadowMapSettings(bool enabled, Qt::Corner corner, double size)
Sets the debugging settings of the shadow map.
void setSelectionColor(const QColor &color)
Sets color used for selected features.
void showLightSourceOriginsChanged()
Emitted when the flag whether light source origins are shown has changed.
QColor backgroundColor() const
Returns background color of the 3D map view.
void resolveReferences(const QgsProject &project)
Resolves references to other objects (map layers) after the call to readXml()
QgsVector3D worldToMapCoordinates(const QgsVector3D &worldCoords) const
Converts 3D world coordinates to map coordinates (applies offset and turns (x,y,z) into (x,...
Qgs3DMapSettings()=default
Constructor for Qgs3DMapSettings.
~Qgs3DMapSettings() override
void showLabelsChanged()
Emitted when the flag whether labels are displayed on terrain tiles has changed.
void maxTerrainScreenErrorChanged()
Emitted when the maximum terrain screen error has changed.
void setShowCameraViewCenter(bool enabled)
Sets whether to show camera's view center as a sphere (for debugging)
int mapTileResolution() const
Returns resolution (in pixels) of the texture of a terrain tile.
void setCameraMovementSpeed(double movementSpeed)
Sets the camera movement speed.
void terrainElevationOffsetChanged(float newElevation)
Emitted when the terrain elevation offset is changed.
void setBackgroundColor(const QColor &color)
Sets background color of the 3D map view.
void fpsCounterEnabledChanged(bool fpsCounterEnabled)
Emitted when the FPS counter is enabled or disabled.
void setProjectionType(const Qt3DRender::QCameraLens::ProjectionType projectionType)
Sets the camera lens' projection type.
void setCameraNavigationMode(QgsCameraController::NavigationMode navigationMode)
Sets the navigation mode for the camera.
void layersChanged()
Emitted when the list of map layers for 3d rendering has changed.
void showTerrainTilesInfoChanged()
Emitted when the flag whether terrain's tile info is shown has changed.
void eyeDomeLightingStrengthChanged()
Emitted when the eye dome lighting strength has changed.
QgsSkyboxSettings skyboxSettings() const
Returns the current configuration of the skybox.
void setMaxTerrainScreenError(float error)
Sets maximum allowed screen error of terrain tiles in pixels.
void cameraMovementSpeedChanged()
Emitted when the camera movement speed was changed.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used in the 3D scene.
float maxTerrainScreenError() const
Returns maximum allowed screen error of terrain tiles in pixels.
void setShowTerrainBoundingBoxes(bool enabled)
Sets whether to display bounding boxes of terrain tiles (for debugging)
void fieldOfViewChanged()
Emitted when the camera lens field of view changes.
void setIsFpsCounterEnabled(bool fpsCounterEnabled)
Sets whether FPS counter label is enabled.
QList< QgsPointLightSettings > pointLights() const
Returns list of point lights defined in the scene.
QList< QgsMapLayer * > layers() const
Returns the list of 3D map layers to be rendered in the scene.
void setTerrainMapTheme(const QString &theme)
Sets name of the map theme.
QgsCameraController::NavigationMode cameraNavigationMode() const
Returns the navigation mode used by the camera.
void terrainGeneratorChanged()
Emitted when the terrain generator has changed.
void setTerrainGenerator(QgsTerrainGenerator *gen)
Sets terrain generator.
void debugShadowMapSettingsChanged()
Emitted when shadow map debugging has changed.
QList< QgsMapLayer * > terrainLayers() const
Returns the list of map layers to be rendered as a texture of the terrain.
void showCameraViewCenterChanged()
Emitted when the flag whether camera's view center is shown has changed.
void maxTerrainGroundErrorChanged()
Emitted when the maximum terrain ground error has changed.
void setTerrainLayers(const QList< QgsMapLayer * > &layers)
Sets the list of 2d map layers to be rendered in the terrain.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
static QgsVector3D worldToMapCoordinates(const QgsVector3D &worldCoords, const QgsVector3D &origin)
Converts 3D world coordinates to map coordinates (applies offset and turns (x,y,z) into (x,...
Definition: qgs3dutils.cpp:441
static QgsVector3D mapToWorldCoordinates(const QgsVector3D &mapCoords, const QgsVector3D &origin)
Converts map coordinates to 3D world coordinates (applies offset and turns (x,y,z) into (x,...
Definition: qgs3dutils.cpp:433
Base class for all renderers that may to participate in 3D view.
virtual void readXml(const QDomElement &elem, const QgsReadWriteContext &context)=0
Reads renderer's properties from given XML element.
virtual void resolveReferences(const QgsProject &project)
Resolves references to other objects - second phase of loading - after readXml()
NavigationMode
The navigation mode used by the camera.
@ WalkNavigation
Uses WASD keys or arrows to navigate in walking (first person) manner.
@ TerrainBasedNavigation
The default navigation based on the terrain.
This class represents a coordinate reference system (CRS).
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
Contains information about the context in which a coordinate transform is executed.
void setCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets CRS of the terrain.
void readXml(const QDomElement &elem)
Reads configuration from a DOM element previously written using writeXml()
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets CRS of the terrain.
Base class for all map layer types.
Definition: qgsmaplayer.h:70
3D renderer that renders all mesh triangles of a mesh layer.
void setCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets CRS of the terrain.
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const override
Writes settings to a DOM element.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads settings from a DOM element.
3D renderer that renders all points from a point cloud layer
void setPosition(const QgsVector3D &pos)
Sets position of the light (in 3D world coordinates)
void readXml(const QDomElement &elem)
Reads configuration from a DOM element previously written using writeXml()
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:99
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
The class is used as a container of context for various read/write operations on other objects.
class containing the configuration of shadows rendering 3
void writeXml(QDomElement &element, const QgsReadWriteContext &context) const
Writes settings to a DOM element.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads settings from a DOM element.
Contains the configuration of a skybox entity.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads settings from a DOM element.
void writeXml(QDomElement &element, const QgsReadWriteContext &context) const
Writes settings to a DOM element.
static QColor decodeColor(const QString &str)
static QString encodeColor(const QColor &color)
Base class for objects with an associated (optional) temporal range.
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
void setTemporalRange(const QgsDateTimeRange &range)
Sets the temporal range for the object.
void extentChanged()
Emitted when the terrain extent has changed.
static QString typeToString(Type type)
Converts terrain generator type enumeration into a string.
double y() const
Returns Y coordinate.
Definition: qgsvector3d.h:51
double z() const
Returns Z coordinate.
Definition: qgsvector3d.h:53
double x() const
Returns X coordinate.
Definition: qgsvector3d.h:49
3D renderer that renders all features of a vector layer with the same 3D symbol.
_LayerRef< QgsMapLayer > QgsMapLayerRef
const QgsCoordinateReferenceSystem & crs
void setLayer(TYPE *l)
Sets the reference to point to a specified layer.
QString layerId
Original layer ID.