QGIS API Documentation  3.23.0-Master (b5237dafc3)
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 {
36  connect( this, &Qgs3DMapSettings::settingsChanged, [&]()
37  {
39  } );
40  connectChangedSignalsToSettingsChanged();
41 }
42 
44  : QObject( nullptr )
45  , QgsTemporalRangeObject( other )
46  , mOrigin( other.mOrigin )
47  , mCrs( other.mCrs )
48  , mBackgroundColor( other.mBackgroundColor )
49  , mSelectionColor( other.mSelectionColor )
50  , mTerrainVerticalScale( other.mTerrainVerticalScale )
51  , mTerrainGenerator( other.mTerrainGenerator ? other.mTerrainGenerator->clone() : nullptr )
52  , mMapTileResolution( other.mMapTileResolution )
53  , mMaxTerrainScreenError( other.mMaxTerrainScreenError )
54  , mMaxTerrainGroundError( other.mMaxTerrainGroundError )
55  , mTerrainElevationOffset( other.mTerrainElevationOffset )
56  , mTerrainShadingEnabled( other.mTerrainShadingEnabled )
57  , mTerrainShadingMaterial( other.mTerrainShadingMaterial )
58  , mTerrainMapTheme( other.mTerrainMapTheme )
59  , mShowTerrainBoundingBoxes( other.mShowTerrainBoundingBoxes )
60  , mShowTerrainTileInfo( other.mShowTerrainTileInfo )
61  , mShowCameraViewCenter( other.mShowCameraViewCenter )
62  , mShowCameraRotationCenter( other.mShowCameraRotationCenter )
63  , mShowLightSources( other.mShowLightSources )
64  , mShowLabels( other.mShowLabels )
65  , mPointLights( other.mPointLights )
66  , mDirectionalLights( other.mDirectionalLights )
67  , mFieldOfView( other.mFieldOfView )
68  , mProjectionType( other.mProjectionType )
69  , mCameraNavigationMode( other.mCameraNavigationMode )
70  , mCameraMovementSpeed( other.mCameraMovementSpeed )
71  , mLayers( other.mLayers )
72  , mRenderers() // initialized in body
73  , mTransformContext( other.mTransformContext )
74  , mPathResolver( other.mPathResolver )
75  , mMapThemes( other.mMapThemes )
76  , mDpi( other.mDpi )
77  , mIsFpsCounterEnabled( other.mIsFpsCounterEnabled )
78  , mIsSkyboxEnabled( other.mIsSkyboxEnabled )
79  , mSkyboxSettings( other.mSkyboxSettings )
80  , mShadowSettings( other.mShadowSettings )
81  , mEyeDomeLightingEnabled( other.mEyeDomeLightingEnabled )
82  , mEyeDomeLightingStrength( other.mEyeDomeLightingStrength )
83  , mEyeDomeLightingDistance( other.mEyeDomeLightingDistance )
84  , mDebugShadowMapEnabled( other.mDebugShadowMapEnabled )
85  , mDebugShadowMapCorner( other.mDebugShadowMapCorner )
86  , mDebugShadowMapSize( other.mDebugShadowMapSize )
87  , mDebugDepthMapEnabled( other.mDebugDepthMapEnabled )
88  , mDebugDepthMapCorner( other.mDebugDepthMapCorner )
89  , mDebugDepthMapSize( other.mDebugDepthMapSize )
90  , mTerrainRenderingEnabled( other.mTerrainRenderingEnabled )
91 {
92  for ( QgsAbstract3DRenderer *renderer : std::as_const( other.mRenderers ) )
93  {
94  mRenderers << renderer->clone();
95  }
96 
97  connect( this, &Qgs3DMapSettings::settingsChanged, [&]()
98  {
100  } );
101  connectChangedSignalsToSettingsChanged();
102 }
103 
105 {
106  qDeleteAll( mRenderers );
107 }
108 
109 void Qgs3DMapSettings::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
110 {
112  QDomElement elemOrigin = elem.firstChildElement( QStringLiteral( "origin" ) );
113  mOrigin = QgsVector3D(
114  elemOrigin.attribute( QStringLiteral( "x" ) ).toDouble(),
115  elemOrigin.attribute( QStringLiteral( "y" ) ).toDouble(),
116  elemOrigin.attribute( QStringLiteral( "z" ) ).toDouble() );
117 
118  QDomElement elemCamera = elem.firstChildElement( QStringLiteral( "camera" ) );
119  if ( !elemCamera.isNull() )
120  {
121  mFieldOfView = elemCamera.attribute( QStringLiteral( "field-of-view" ), QStringLiteral( "45" ) ).toFloat();
122  mProjectionType = static_cast< Qt3DRender::QCameraLens::ProjectionType >( elemCamera.attribute( QStringLiteral( "projection-type" ), QStringLiteral( "1" ) ).toInt() );
123  QString cameraNavigationMode = elemCamera.attribute( QStringLiteral( "camera-navigation-mode" ), QStringLiteral( "basic-navigation" ) );
124  if ( cameraNavigationMode == QLatin1String( "terrain-based-navigation" ) )
125  mCameraNavigationMode = QgsCameraController::NavigationMode::TerrainBasedNavigation;
126  else if ( cameraNavigationMode == QLatin1String( "walk-navigation" ) )
127  mCameraNavigationMode = QgsCameraController::NavigationMode::WalkNavigation;
128  mCameraMovementSpeed = elemCamera.attribute( QStringLiteral( "camera-movement-speed" ), QStringLiteral( "5.0" ) ).toDouble();
129  }
130 
131  QDomElement elemColor = elem.firstChildElement( QStringLiteral( "color" ) );
132  if ( !elemColor.isNull() )
133  {
134  mBackgroundColor = QgsSymbolLayerUtils::decodeColor( elemColor.attribute( QStringLiteral( "background" ) ) );
135  mSelectionColor = QgsSymbolLayerUtils::decodeColor( elemColor.attribute( QStringLiteral( "selection" ) ) );
136  }
137 
138  QDomElement elemCrs = elem.firstChildElement( QStringLiteral( "crs" ) );
139  mCrs.readXml( elemCrs );
140 
141  QDomElement elemTerrain = elem.firstChildElement( QStringLiteral( "terrain" ) );
142  mTerrainRenderingEnabled = elemTerrain.attribute( QStringLiteral( "terrain-rendering-enabled" ), QStringLiteral( "1" ) ).toInt();
143  mTerrainVerticalScale = elemTerrain.attribute( QStringLiteral( "exaggeration" ), QStringLiteral( "1" ) ).toFloat();
144  mMapTileResolution = elemTerrain.attribute( QStringLiteral( "texture-size" ), QStringLiteral( "512" ) ).toInt();
145  mMaxTerrainScreenError = elemTerrain.attribute( QStringLiteral( "max-terrain-error" ), QStringLiteral( "3" ) ).toFloat();
146  mMaxTerrainGroundError = elemTerrain.attribute( QStringLiteral( "max-ground-error" ), QStringLiteral( "1" ) ).toFloat();
147  mTerrainShadingEnabled = elemTerrain.attribute( QStringLiteral( "shading-enabled" ), QStringLiteral( "0" ) ).toInt();
148  mTerrainElevationOffset = elemTerrain.attribute( QStringLiteral( "elevation-offset" ), QStringLiteral( "0.0" ) ).toFloat();
149 
150  QDomElement elemTerrainShadingMaterial = elemTerrain.firstChildElement( QStringLiteral( "shading-material" ) );
151  if ( !elemTerrainShadingMaterial.isNull() )
152  mTerrainShadingMaterial.readXml( elemTerrainShadingMaterial, context );
153  mTerrainMapTheme = elemTerrain.attribute( QStringLiteral( "map-theme" ) );
154  mShowLabels = elemTerrain.attribute( QStringLiteral( "show-labels" ), QStringLiteral( "0" ) ).toInt();
155 
156  mPointLights.clear();
157  QDomElement elemPointLights = elem.firstChildElement( QStringLiteral( "point-lights" ) );
158  if ( !elemPointLights.isNull() )
159  {
160  QDomElement elemPointLight = elemPointLights.firstChildElement( QStringLiteral( "point-light" ) );
161  while ( !elemPointLight.isNull() )
162  {
163  QgsPointLightSettings pointLight;
164  pointLight.readXml( elemPointLight );
165  mPointLights << pointLight;
166  elemPointLight = elemPointLight.nextSiblingElement( QStringLiteral( "point-light" ) );
167  }
168  }
169  else
170  {
171  // QGIS <= 3.4 did not have light configuration
172  QgsPointLightSettings defaultLight;
173  defaultLight.setPosition( QgsVector3D( 0, 1000, 0 ) );
174  mPointLights << defaultLight;
175  }
176 
177  mDirectionalLights.clear();
178  QDomElement elemDirectionalLights = elem.firstChildElement( QStringLiteral( "directional-lights" ) );
179  if ( !elemDirectionalLights.isNull() )
180  {
181  QDomElement elemDirectionalLight = elemDirectionalLights.firstChildElement( QStringLiteral( "directional-light" ) );
182  while ( !elemDirectionalLight.isNull() )
183  {
184  QgsDirectionalLightSettings directionalLight;
185  directionalLight.readXml( elemDirectionalLight );
186  mDirectionalLights << directionalLight;
187  elemDirectionalLight = elemDirectionalLight.nextSiblingElement( QStringLiteral( "directional-light" ) );
188  }
189  }
190 
191  QDomElement elemMapLayers = elemTerrain.firstChildElement( QStringLiteral( "layers" ) );
192  QDomElement elemMapLayer = elemMapLayers.firstChildElement( QStringLiteral( "layer" ) );
193  QList<QgsMapLayerRef> mapLayers;
194  while ( !elemMapLayer.isNull() )
195  {
196  mapLayers << QgsMapLayerRef( elemMapLayer.attribute( QStringLiteral( "id" ) ) );
197  elemMapLayer = elemMapLayer.nextSiblingElement( QStringLiteral( "layer" ) );
198  }
199  mLayers = mapLayers; // needs to resolve refs afterwards
200 
201  QDomElement elemTerrainGenerator = elemTerrain.firstChildElement( QStringLiteral( "generator" ) );
202  QString terrainGenType = elemTerrainGenerator.attribute( QStringLiteral( "type" ) );
203  if ( terrainGenType == QLatin1String( "dem" ) )
204  {
205  QgsDemTerrainGenerator *demTerrainGenerator = new QgsDemTerrainGenerator;
206  demTerrainGenerator->setCrs( mCrs, mTransformContext );
207  setTerrainGenerator( demTerrainGenerator );
208  }
209  else if ( terrainGenType == QLatin1String( "online" ) )
210  {
211  QgsOnlineTerrainGenerator *onlineTerrainGenerator = new QgsOnlineTerrainGenerator;
212  onlineTerrainGenerator->setCrs( mCrs, mTransformContext );
213  setTerrainGenerator( onlineTerrainGenerator );
214  }
215  else if ( terrainGenType == QLatin1String( "mesh" ) )
216  {
217  QgsMeshTerrainGenerator *meshTerrainGenerator = new QgsMeshTerrainGenerator;
218  meshTerrainGenerator->setCrs( mCrs, mTransformContext );
219  setTerrainGenerator( meshTerrainGenerator );
220  }
221  else // "flat"
222  {
224  flatGen->setCrs( mCrs );
225  setTerrainGenerator( flatGen );
226  }
227  mTerrainGenerator->readXml( elemTerrainGenerator );
228 
229  qDeleteAll( mRenderers );
230  mRenderers.clear();
231 
232  QDomElement elemRenderers = elem.firstChildElement( QStringLiteral( "renderers" ) );
233  QDomElement elemRenderer = elemRenderers.firstChildElement( QStringLiteral( "renderer" ) );
234  while ( !elemRenderer.isNull() )
235  {
236  QgsAbstract3DRenderer *renderer = nullptr;
237  QString type = elemRenderer.attribute( QStringLiteral( "type" ) );
238  if ( type == QLatin1String( "vector" ) )
239  {
240  renderer = new QgsVectorLayer3DRenderer;
241  }
242  else if ( type == QLatin1String( "mesh" ) )
243  {
244  renderer = new QgsMeshLayer3DRenderer;
245  }
246  else if ( type == QLatin1String( "pointcloud" ) )
247  {
248  renderer = new QgsPointCloudLayer3DRenderer;
249  }
250 
251  if ( renderer )
252  {
253  renderer->readXml( elemRenderer, context );
254  mRenderers.append( renderer );
255  }
256  elemRenderer = elemRenderer.nextSiblingElement( QStringLiteral( "renderer" ) );
257  }
258 
259  QDomElement elemSkybox = elem.firstChildElement( QStringLiteral( "skybox" ) );
260  mIsSkyboxEnabled = elemSkybox.attribute( QStringLiteral( "skybox-enabled" ) ).toInt();
261  mSkyboxSettings.readXml( elemSkybox, context );
262 
263  QDomElement elemShadows = elem.firstChildElement( QStringLiteral( "shadow-rendering" ) );
264  mShadowSettings.readXml( elemShadows, context );
265 
266  QDomElement elemEyeDomeLighting = elem.firstChildElement( QStringLiteral( "eye-dome-lighting" ) );
267  mEyeDomeLightingEnabled = elemEyeDomeLighting.attribute( "enabled", QStringLiteral( "0" ) ).toInt();
268  mEyeDomeLightingStrength = elemEyeDomeLighting.attribute( "eye-dome-lighting-strength", QStringLiteral( "1000.0" ) ).toDouble();
269  mEyeDomeLightingDistance = elemEyeDomeLighting.attribute( "eye-dome-lighting-distance", QStringLiteral( "1" ) ).toInt();
270 
271  QDomElement elemDebugSettings = elem.firstChildElement( QStringLiteral( "debug-settings" ) );
272  mDebugShadowMapEnabled = elemDebugSettings.attribute( QStringLiteral( "shadowmap-enabled" ), QStringLiteral( "0" ) ).toInt();
273  mDebugShadowMapCorner = static_cast<Qt::Corner>( elemDebugSettings.attribute( QStringLiteral( "shadowmap-corner" ), "0" ).toInt() );
274  mDebugShadowMapSize = elemDebugSettings.attribute( QStringLiteral( "shadowmap-size" ), QStringLiteral( "0.2" ) ).toDouble();
275 
276  mDebugDepthMapEnabled = elemDebugSettings.attribute( QStringLiteral( "depthmap-enabled" ), QStringLiteral( "0" ) ).toInt();
277  mDebugDepthMapCorner = static_cast<Qt::Corner>( elemDebugSettings.attribute( QStringLiteral( "depthmap-corner" ), QStringLiteral( "1" ) ).toInt() );
278  mDebugDepthMapSize = elemDebugSettings.attribute( QStringLiteral( "depthmap-size" ), QStringLiteral( "0.2" ) ).toDouble();
279 
280  QDomElement elemDebug = elem.firstChildElement( QStringLiteral( "debug" ) );
281  mShowTerrainBoundingBoxes = elemDebug.attribute( QStringLiteral( "bounding-boxes" ), QStringLiteral( "0" ) ).toInt();
282  mShowTerrainTileInfo = elemDebug.attribute( QStringLiteral( "terrain-tile-info" ), QStringLiteral( "0" ) ).toInt();
283  mShowCameraViewCenter = elemDebug.attribute( QStringLiteral( "camera-view-center" ), QStringLiteral( "0" ) ).toInt();
284  mShowCameraRotationCenter = elemDebug.attribute( QStringLiteral( "camera-rotation-center" ), QStringLiteral( "0" ) ).toInt();
285  mShowLightSources = elemDebug.attribute( QStringLiteral( "show-light-sources" ), QStringLiteral( "0" ) ).toInt();
286  mIsFpsCounterEnabled = elemDebug.attribute( QStringLiteral( "show-fps-counter" ), QStringLiteral( "0" ) ).toInt();
287 
288  QDomElement elemTemporalRange = elem.firstChildElement( QStringLiteral( "temporal-range" ) );
289  QDateTime start = QDateTime::fromString( elemTemporalRange.attribute( QStringLiteral( "start" ) ), Qt::ISODate );
290  QDateTime end = QDateTime::fromString( elemTemporalRange.attribute( QStringLiteral( "end" ) ), Qt::ISODate );
291  setTemporalRange( QgsDateTimeRange( start, end ) );
292 }
293 
294 QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
295 {
296  QDomElement elem = doc.createElement( QStringLiteral( "qgis3d" ) );
297 
298  QDomElement elemOrigin = doc.createElement( QStringLiteral( "origin" ) );
299  elemOrigin.setAttribute( QStringLiteral( "x" ), QString::number( mOrigin.x() ) );
300  elemOrigin.setAttribute( QStringLiteral( "y" ), QString::number( mOrigin.y() ) );
301  elemOrigin.setAttribute( QStringLiteral( "z" ), QString::number( mOrigin.z() ) );
302  elem.appendChild( elemOrigin );
303 
304  QDomElement elemCamera = doc.createElement( QStringLiteral( "camera" ) );
305  elemCamera.setAttribute( QStringLiteral( "field-of-view" ), mFieldOfView );
306  elemCamera.setAttribute( QStringLiteral( "projection-type" ), static_cast< int >( mProjectionType ) );
307  switch ( mCameraNavigationMode )
308  {
310  elemCamera.setAttribute( QStringLiteral( "camera-navigation-mode" ), QStringLiteral( "terrain-based-navigation" ) );
311  break;
313  elemCamera.setAttribute( QStringLiteral( "camera-navigation-mode" ), QStringLiteral( "walk-navigation" ) );
314  break;
315  }
316  elemCamera.setAttribute( QStringLiteral( "camera-movement-speed" ), mCameraMovementSpeed );
317  elem.appendChild( elemCamera );
318 
319  QDomElement elemColor = doc.createElement( QStringLiteral( "color" ) );
320  elemColor.setAttribute( QStringLiteral( "background" ), QgsSymbolLayerUtils::encodeColor( mBackgroundColor ) );
321  elemColor.setAttribute( QStringLiteral( "selection" ), QgsSymbolLayerUtils::encodeColor( mSelectionColor ) );
322  elem.appendChild( elemColor );
323 
324  QDomElement elemCrs = doc.createElement( QStringLiteral( "crs" ) );
325  mCrs.writeXml( elemCrs, doc );
326  elem.appendChild( elemCrs );
327 
328  QDomElement elemTerrain = doc.createElement( QStringLiteral( "terrain" ) );
329  elemTerrain.setAttribute( QStringLiteral( "terrain-rendering-enabled" ), mTerrainRenderingEnabled ? 1 : 0 );
330  elemTerrain.setAttribute( QStringLiteral( "exaggeration" ), QString::number( mTerrainVerticalScale ) );
331  elemTerrain.setAttribute( QStringLiteral( "texture-size" ), mMapTileResolution );
332  elemTerrain.setAttribute( QStringLiteral( "max-terrain-error" ), QString::number( mMaxTerrainScreenError ) );
333  elemTerrain.setAttribute( QStringLiteral( "max-ground-error" ), QString::number( mMaxTerrainGroundError ) );
334  elemTerrain.setAttribute( QStringLiteral( "shading-enabled" ), mTerrainShadingEnabled ? 1 : 0 );
335  elemTerrain.setAttribute( QStringLiteral( "elevation-offset" ), mTerrainElevationOffset );
336 
337  QDomElement elemTerrainShadingMaterial = doc.createElement( QStringLiteral( "shading-material" ) );
338  mTerrainShadingMaterial.writeXml( elemTerrainShadingMaterial, context );
339  elemTerrain.appendChild( elemTerrainShadingMaterial );
340  elemTerrain.setAttribute( QStringLiteral( "map-theme" ), mTerrainMapTheme );
341  elemTerrain.setAttribute( QStringLiteral( "show-labels" ), mShowLabels ? 1 : 0 );
342 
343  QDomElement elemPointLights = doc.createElement( QStringLiteral( "point-lights" ) );
344  for ( const QgsPointLightSettings &pointLight : std::as_const( mPointLights ) )
345  {
346  QDomElement elemPointLight = pointLight.writeXml( doc );
347  elemPointLights.appendChild( elemPointLight );
348  }
349  elem.appendChild( elemPointLights );
350 
351  QDomElement elemDirectionalLights = doc.createElement( QStringLiteral( "directional-lights" ) );
352  for ( const QgsDirectionalLightSettings &directionalLight : std::as_const( mDirectionalLights ) )
353  {
354  QDomElement elemDirectionalLight = directionalLight.writeXml( doc );
355  elemDirectionalLights.appendChild( elemDirectionalLight );
356  }
357  elem.appendChild( elemDirectionalLights );
358 
359  QDomElement elemMapLayers = doc.createElement( QStringLiteral( "layers" ) );
360  for ( const QgsMapLayerRef &layerRef : mLayers )
361  {
362  QDomElement elemMapLayer = doc.createElement( QStringLiteral( "layer" ) );
363  elemMapLayer.setAttribute( QStringLiteral( "id" ), layerRef.layerId );
364  elemMapLayers.appendChild( elemMapLayer );
365  }
366  elemTerrain.appendChild( elemMapLayers );
367 
368  QDomElement elemTerrainGenerator = doc.createElement( QStringLiteral( "generator" ) );
369  elemTerrainGenerator.setAttribute( QStringLiteral( "type" ), QgsTerrainGenerator::typeToString( mTerrainGenerator->type() ) );
370  mTerrainGenerator->writeXml( elemTerrainGenerator );
371  elemTerrain.appendChild( elemTerrainGenerator );
372  elem.appendChild( elemTerrain );
373 
374  QDomElement elemRenderers = doc.createElement( QStringLiteral( "renderers" ) );
375  for ( const QgsAbstract3DRenderer *renderer : mRenderers )
376  {
377  QDomElement elemRenderer = doc.createElement( QStringLiteral( "renderer" ) );
378  elemRenderer.setAttribute( QStringLiteral( "type" ), renderer->type() );
379  renderer->writeXml( elemRenderer, context );
380  elemRenderers.appendChild( elemRenderer );
381  }
382  elem.appendChild( elemRenderers );
383 
384  QDomElement elemSkybox = doc.createElement( QStringLiteral( "skybox" ) );
385  elemSkybox.setAttribute( QStringLiteral( "skybox-enabled" ), mIsSkyboxEnabled );
386  mSkyboxSettings.writeXml( elemSkybox, context );
387  elem.appendChild( elemSkybox );
388 
389  QDomElement elemShadows = doc.createElement( QStringLiteral( "shadow-rendering" ) );
390  mShadowSettings.writeXml( elemShadows, context );
391  elem.appendChild( elemShadows );
392 
393  QDomElement elemDebug = doc.createElement( QStringLiteral( "debug" ) );
394  elemDebug.setAttribute( QStringLiteral( "bounding-boxes" ), mShowTerrainBoundingBoxes ? 1 : 0 );
395  elemDebug.setAttribute( QStringLiteral( "terrain-tile-info" ), mShowTerrainTileInfo ? 1 : 0 );
396  elemDebug.setAttribute( QStringLiteral( "camera-view-center" ), mShowCameraViewCenter ? 1 : 0 );
397  elemDebug.setAttribute( QStringLiteral( "camera-rotation-center" ), mShowCameraRotationCenter ? 1 : 0 );
398  elemDebug.setAttribute( QStringLiteral( "show-light-sources" ), mShowLightSources ? 1 : 0 );
399  elemDebug.setAttribute( QStringLiteral( "show-fps-counter" ), mIsFpsCounterEnabled ? 1 : 0 );
400  elem.appendChild( elemDebug );
401 
402  QDomElement elemEyeDomeLighting = doc.createElement( QStringLiteral( "eye-dome-lighting" ) );
403  elemEyeDomeLighting.setAttribute( "enabled", mEyeDomeLightingEnabled ? 1 : 0 );
404  elemEyeDomeLighting.setAttribute( "eye-dome-lighting-strength", mEyeDomeLightingStrength );
405  elemEyeDomeLighting.setAttribute( "eye-dome-lighting-distance", mEyeDomeLightingDistance );
406  elem.appendChild( elemEyeDomeLighting );
407 
408 
409  QDomElement elemDebugSettings = doc.createElement( QStringLiteral( "debug-settings" ) );
410  elemDebugSettings.setAttribute( QStringLiteral( "shadowmap-enabled" ), mDebugShadowMapEnabled );
411  elemDebugSettings.setAttribute( QStringLiteral( "shadowmap-corner" ), mDebugShadowMapCorner );
412  elemDebugSettings.setAttribute( QStringLiteral( "shadowmap-size" ), mDebugShadowMapSize );
413  elemDebugSettings.setAttribute( QStringLiteral( "depthmap-enabled" ), mDebugDepthMapEnabled );
414  elemDebugSettings.setAttribute( QStringLiteral( "depthmap-corner" ), mDebugDepthMapCorner );
415  elemDebugSettings.setAttribute( QStringLiteral( "depthmap-size" ), mDebugDepthMapSize );
416  elem.appendChild( elemDebugSettings );
417 
418  QDomElement elemTemporalRange = doc.createElement( QStringLiteral( "temporal-range" ) );
419  elemTemporalRange.setAttribute( QStringLiteral( "start" ), temporalRange().begin().toString( Qt::ISODate ) );
420  elemTemporalRange.setAttribute( QStringLiteral( "end" ), temporalRange().end().toString( Qt::ISODate ) );
421 
422  return elem;
423 }
424 
426 {
427  for ( int i = 0; i < mLayers.count(); ++i )
428  {
429  QgsMapLayerRef &layerRef = mLayers[i];
430  layerRef.setLayer( project.mapLayer( layerRef.layerId ) );
431  }
432 
433  mTerrainGenerator->resolveReferences( project );
434 
435  for ( int i = 0; i < mRenderers.count(); ++i )
436  {
437  QgsAbstract3DRenderer *renderer = mRenderers[i];
438  renderer->resolveReferences( project );
439  }
440 }
441 
443 {
444  return Qgs3DUtils::mapToWorldCoordinates( mapCoords, mOrigin );
445 }
446 
448 {
449  return Qgs3DUtils::worldToMapCoordinates( worldCoords, mOrigin );
450 }
451 
453 {
454  mCrs = crs;
455 }
456 
458 {
459  return mTransformContext;
460 }
461 
463 {
464  mTransformContext = context;
465 }
466 
467 void Qgs3DMapSettings::setBackgroundColor( const QColor &color )
468 {
469  if ( color == mBackgroundColor )
470  return;
471 
472  mBackgroundColor = color;
473  emit backgroundColorChanged();
474 }
475 
477 {
478  return mBackgroundColor;
479 }
480 
481 void Qgs3DMapSettings::setSelectionColor( const QColor &color )
482 {
483  if ( color == mSelectionColor )
484  return;
485 
486  mSelectionColor = color;
487  emit selectionColorChanged();
488 }
489 
491 {
492  return mSelectionColor;
493 }
494 
496 {
497  if ( zScale == mTerrainVerticalScale )
498  return;
499 
500  mTerrainVerticalScale = zScale;
502 }
503 
505 {
506  return mTerrainVerticalScale;
507 }
508 
509 void Qgs3DMapSettings::setLayers( const QList<QgsMapLayer *> &layers )
510 {
511  QList<QgsMapLayerRef> lst;
512  lst.reserve( layers.count() );
513  for ( QgsMapLayer *layer : layers )
514  {
515  lst.append( layer );
516  }
517 
518  if ( mLayers == lst )
519  return;
520 
521  mLayers = lst;
522  emit layersChanged();
523 }
524 
525 QList<QgsMapLayer *> Qgs3DMapSettings::layers() const
526 {
527  QList<QgsMapLayer *> lst;
528  lst.reserve( mLayers.count() );
529  for ( const QgsMapLayerRef &layerRef : mLayers )
530  {
531  if ( layerRef.layer )
532  lst.append( layerRef.layer );
533  }
534  return lst;
535 }
536 
538 {
539  if ( mMapTileResolution == res )
540  return;
541 
542  mMapTileResolution = res;
544 }
545 
547 {
548  return mMapTileResolution;
549 }
550 
552 {
553  if ( mMaxTerrainScreenError == error )
554  return;
555 
556  mMaxTerrainScreenError = error;
558 }
559 
561 {
562  return mMaxTerrainScreenError;
563 }
564 
566 {
567  if ( mMaxTerrainGroundError == error )
568  return;
569 
570  mMaxTerrainGroundError = error;
572 }
573 
575 {
576  if ( mTerrainElevationOffset == offset )
577  return;
578  mTerrainElevationOffset = offset;
579  emit terrainElevationOffsetChanged( mTerrainElevationOffset );
580 }
581 
583 {
584  return mMaxTerrainGroundError;
585 }
586 
588 {
589  if ( mTerrainGenerator )
590  {
591  disconnect( mTerrainGenerator.get(), &QgsTerrainGenerator::extentChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );
592  disconnect( mTerrainGenerator.get(), &QgsTerrainGenerator::terrainChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );
593  }
594 
595  mTerrainGenerator.reset( gen );
596  connect( mTerrainGenerator.get(), &QgsTerrainGenerator::extentChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );
597  connect( mTerrainGenerator.get(), &QgsTerrainGenerator::terrainChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );
598 
600 }
601 
603 {
604  if ( mTerrainShadingEnabled == enabled )
605  return;
606 
607  mTerrainShadingEnabled = enabled;
608  emit terrainShadingChanged();
609 }
610 
612 {
613  if ( mTerrainShadingMaterial == material )
614  return;
615 
616  mTerrainShadingMaterial = material;
617  emit terrainShadingChanged();
618 }
619 
620 void Qgs3DMapSettings::setTerrainMapTheme( const QString &theme )
621 {
622  if ( mTerrainMapTheme == theme )
623  return;
624 
625  mTerrainMapTheme = theme;
626  emit terrainMapThemeChanged();
627 }
628 
629 void Qgs3DMapSettings::setRenderers( const QList<QgsAbstract3DRenderer *> &renderers )
630 {
631  qDeleteAll( mRenderers );
632 
633  mRenderers = renderers;
634 
635  emit renderersChanged();
636 }
637 
639 {
640  if ( mShowTerrainBoundingBoxes == enabled )
641  return;
642 
643  mShowTerrainBoundingBoxes = enabled;
645 }
646 
648 {
649  if ( mShowTerrainTileInfo == enabled )
650  return;
651 
652  mShowTerrainTileInfo = enabled;
654 }
655 
657 {
658  if ( mShowCameraViewCenter == enabled )
659  return;
660 
661  mShowCameraViewCenter = enabled;
663 }
664 
666 {
667  if ( mShowCameraRotationCenter == enabled )
668  return;
669 
670  mShowCameraRotationCenter = enabled;
672 }
673 
674 
676 {
677  if ( mShowLightSources == enabled )
678  return;
679 
680  mShowLightSources = enabled;
682 }
683 
685 {
686  if ( mShowLabels == enabled )
687  return;
688 
689  mShowLabels = enabled;
690  emit showLabelsChanged();
691 }
692 
694 {
695  if ( mEyeDomeLightingEnabled == enabled )
696  return;
697  mEyeDomeLightingEnabled = enabled;
699 }
700 
702 {
703  if ( mEyeDomeLightingStrength == strength )
704  return;
705  mEyeDomeLightingStrength = strength;
707 }
708 
710 {
711  if ( mEyeDomeLightingDistance == distance )
712  return;
713  mEyeDomeLightingDistance = distance;
715 }
716 
717 void Qgs3DMapSettings::setPointLights( const QList<QgsPointLightSettings> &pointLights )
718 {
719  if ( mPointLights == pointLights )
720  return;
721 
722  mPointLights = pointLights;
723  emit pointLightsChanged();
724 }
725 
726 void Qgs3DMapSettings::setDirectionalLights( const QList<QgsDirectionalLightSettings> &directionalLights )
727 {
728  if ( mDirectionalLights == directionalLights )
729  return;
730 
731  mDirectionalLights = directionalLights;
733 }
734 
735 void Qgs3DMapSettings::setFieldOfView( const float fieldOfView )
736 {
737  if ( mFieldOfView == fieldOfView )
738  return;
739 
740  mFieldOfView = fieldOfView;
741  emit fieldOfViewChanged();
742 }
743 
744 void Qgs3DMapSettings::setProjectionType( const Qt3DRender::QCameraLens::ProjectionType projectionType )
745 {
746  if ( mProjectionType == projectionType )
747  return;
748 
749  mProjectionType = projectionType;
750  emit projectionTypeChanged();
751 }
752 
754 {
755  if ( mCameraNavigationMode == navigationMode )
756  return;
757 
758  mCameraNavigationMode = navigationMode;
760 }
761 
762 void Qgs3DMapSettings::setCameraMovementSpeed( double movementSpeed )
763 {
764  if ( mCameraMovementSpeed == movementSpeed )
765  return;
766 
767  mCameraMovementSpeed = movementSpeed;
769 }
770 
772 {
773  mSkyboxSettings = skyboxSettings;
774  emit skyboxSettingsChanged();
775 }
776 
778 {
779  mShadowSettings = shadowSettings;
780  emit shadowSettingsChanged();
781 }
782 
783 void Qgs3DMapSettings::setDebugShadowMapSettings( bool enabled, Qt::Corner corner, double size )
784 {
785  mDebugShadowMapEnabled = enabled;
786  mDebugShadowMapCorner = corner;
787  mDebugShadowMapSize = size;
789 }
790 
791 void Qgs3DMapSettings::setDebugDepthMapSettings( bool enabled, Qt::Corner corner, double size )
792 {
793  mDebugDepthMapEnabled = enabled;
794  mDebugDepthMapCorner = corner;
795  mDebugDepthMapSize = size;
797 }
798 
799 void Qgs3DMapSettings::setIsFpsCounterEnabled( bool fpsCounterEnabled )
800 {
801  if ( fpsCounterEnabled == mIsFpsCounterEnabled )
802  return;
803  mIsFpsCounterEnabled = fpsCounterEnabled;
804  emit fpsCounterEnabledChanged( mIsFpsCounterEnabled );
805 }
806 
807 void Qgs3DMapSettings::setTerrainRenderingEnabled( bool terrainRenderingEnabled )
808 {
809  if ( terrainRenderingEnabled == mTerrainRenderingEnabled )
810  return;
811  mTerrainRenderingEnabled = terrainRenderingEnabled;
813 }
814 
815 void Qgs3DMapSettings::connectChangedSignalsToSettingsChanged()
816 {
847 }
848 
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 settingsChanged()
Emitted when one of the configuration settings has changed.
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.
void showCameraRotationCenterChanged()
Emitted when the flag whether camera's rotation center is shown has changed.
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 setShowCameraRotationCenter(bool enabled)
Sets whether to show camera's rotation center as a sphere (for debugging)
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() 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.
bool terrainRenderingEnabled()
Returns whether the 2D terrain surface will be rendered.
void setCameraMovementSpeed(double movementSpeed)
Sets the camera movement speed.
void terrainElevationOffsetChanged(float newElevation)
Emitted when the terrain elevation offset is changed.
void setTerrainRenderingEnabled(bool terrainRenderingEnabled)
Sets whether the 2D terrain surface will be rendered in.
Qgs3DMapSettings()
Constructor for Qgs3DMapSettings.
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.
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.
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:488
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:480
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:73
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()
Temporarily blocks QgsProject "dirtying" for the lifetime of the object.
Definition: qgsproject.h:2170
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:101
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:469
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
void setDirty(bool b=true)
Flag the project as dirty (modified).
Definition: qgsproject.cpp:520
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 terrainChanged()
Emitted when the terrain changed (for example, raster DEM or mesh have data changed)
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.