QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
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  , mRenderers() // initialized in body
62  , mTransformContext( other.mTransformContext )
63  , mPathResolver( other.mPathResolver )
64  , mMapThemes( other.mMapThemes )
65  , mDpi( other.mDpi )
66  , mIsFpsCounterEnabled( other.mIsFpsCounterEnabled )
67  , mIsSkyboxEnabled( other.mIsSkyboxEnabled )
68  , mSkyboxSettings( other.mSkyboxSettings )
69  , mShadowSettings( other.mShadowSettings )
70  , mEyeDomeLightingEnabled( other.mEyeDomeLightingEnabled )
71  , mEyeDomeLightingStrength( other.mEyeDomeLightingStrength )
72  , mEyeDomeLightingDistance( other.mEyeDomeLightingDistance )
73  , mDebugShadowMapEnabled( other.mDebugShadowMapEnabled )
74  , mDebugShadowMapCorner( other.mDebugShadowMapCorner )
75  , mDebugShadowMapSize( other.mDebugShadowMapSize )
76  , mDebugDepthMapEnabled( other.mDebugDepthMapEnabled )
77  , mDebugDepthMapCorner( other.mDebugDepthMapCorner )
78  , mDebugDepthMapSize( other.mDebugDepthMapSize )
79  , mTerrainRenderingEnabled( other.mTerrainRenderingEnabled )
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  mTerrainRenderingEnabled = elemTerrain.attribute( QStringLiteral( "terrain-rendering-enabled" ), QStringLiteral( "1" ) ).toInt();
125  mTerrainVerticalScale = elemTerrain.attribute( QStringLiteral( "exaggeration" ), QStringLiteral( "1" ) ).toFloat();
126  mMapTileResolution = elemTerrain.attribute( QStringLiteral( "texture-size" ), QStringLiteral( "512" ) ).toInt();
127  mMaxTerrainScreenError = elemTerrain.attribute( QStringLiteral( "max-terrain-error" ), QStringLiteral( "3" ) ).toFloat();
128  mMaxTerrainGroundError = elemTerrain.attribute( QStringLiteral( "max-ground-error" ), QStringLiteral( "1" ) ).toFloat();
129  mTerrainShadingEnabled = elemTerrain.attribute( QStringLiteral( "shading-enabled" ), QStringLiteral( "0" ) ).toInt();
130  mTerrainElevationOffset = elemTerrain.attribute( QStringLiteral( "elevation-offset" ), QStringLiteral( "0.0" ) ).toFloat();
131 
132  QDomElement elemTerrainShadingMaterial = elemTerrain.firstChildElement( QStringLiteral( "shading-material" ) );
133  if ( !elemTerrainShadingMaterial.isNull() )
134  mTerrainShadingMaterial.readXml( elemTerrainShadingMaterial, context );
135  mTerrainMapTheme = elemTerrain.attribute( QStringLiteral( "map-theme" ) );
136  mShowLabels = elemTerrain.attribute( QStringLiteral( "show-labels" ), QStringLiteral( "0" ) ).toInt();
137 
138  mPointLights.clear();
139  QDomElement elemPointLights = elem.firstChildElement( QStringLiteral( "point-lights" ) );
140  if ( !elemPointLights.isNull() )
141  {
142  QDomElement elemPointLight = elemPointLights.firstChildElement( QStringLiteral( "point-light" ) );
143  while ( !elemPointLight.isNull() )
144  {
145  QgsPointLightSettings pointLight;
146  pointLight.readXml( elemPointLight );
147  mPointLights << pointLight;
148  elemPointLight = elemPointLight.nextSiblingElement( QStringLiteral( "point-light" ) );
149  }
150  }
151  else
152  {
153  // QGIS <= 3.4 did not have light configuration
154  QgsPointLightSettings defaultLight;
155  defaultLight.setPosition( QgsVector3D( 0, 1000, 0 ) );
156  mPointLights << defaultLight;
157  }
158 
159  mDirectionalLights.clear();
160  QDomElement elemDirectionalLights = elem.firstChildElement( QStringLiteral( "directional-lights" ) );
161  if ( !elemDirectionalLights.isNull() )
162  {
163  QDomElement elemDirectionalLight = elemDirectionalLights.firstChildElement( QStringLiteral( "directional-light" ) );
164  while ( !elemDirectionalLight.isNull() )
165  {
166  QgsDirectionalLightSettings directionalLight;
167  directionalLight.readXml( elemDirectionalLight );
168  mDirectionalLights << directionalLight;
169  elemDirectionalLight = elemDirectionalLight.nextSiblingElement( QStringLiteral( "directional-light" ) );
170  }
171  }
172 
173  QDomElement elemMapLayers = elemTerrain.firstChildElement( QStringLiteral( "layers" ) );
174  QDomElement elemMapLayer = elemMapLayers.firstChildElement( QStringLiteral( "layer" ) );
175  QList<QgsMapLayerRef> mapLayers;
176  while ( !elemMapLayer.isNull() )
177  {
178  mapLayers << QgsMapLayerRef( elemMapLayer.attribute( QStringLiteral( "id" ) ) );
179  elemMapLayer = elemMapLayer.nextSiblingElement( QStringLiteral( "layer" ) );
180  }
181  mLayers = mapLayers; // needs to resolve refs afterwards
182 
183  QDomElement elemTerrainGenerator = elemTerrain.firstChildElement( QStringLiteral( "generator" ) );
184  QString terrainGenType = elemTerrainGenerator.attribute( QStringLiteral( "type" ) );
185  if ( terrainGenType == QLatin1String( "dem" ) )
186  {
187  QgsDemTerrainGenerator *demTerrainGenerator = new QgsDemTerrainGenerator;
188  demTerrainGenerator->setCrs( mCrs, mTransformContext );
189  setTerrainGenerator( demTerrainGenerator );
190  }
191  else if ( terrainGenType == QLatin1String( "online" ) )
192  {
193  QgsOnlineTerrainGenerator *onlineTerrainGenerator = new QgsOnlineTerrainGenerator;
194  onlineTerrainGenerator->setCrs( mCrs, mTransformContext );
195  setTerrainGenerator( onlineTerrainGenerator );
196  }
197  else if ( terrainGenType == QLatin1String( "mesh" ) )
198  {
199  QgsMeshTerrainGenerator *meshTerrainGenerator = new QgsMeshTerrainGenerator;
200  meshTerrainGenerator->setCrs( mCrs, mTransformContext );
201  setTerrainGenerator( meshTerrainGenerator );
202  }
203  else // "flat"
204  {
206  flatGen->setCrs( mCrs );
207  setTerrainGenerator( flatGen );
208  }
209  mTerrainGenerator->readXml( elemTerrainGenerator );
210 
211  qDeleteAll( mRenderers );
212  mRenderers.clear();
213 
214  QDomElement elemRenderers = elem.firstChildElement( QStringLiteral( "renderers" ) );
215  QDomElement elemRenderer = elemRenderers.firstChildElement( QStringLiteral( "renderer" ) );
216  while ( !elemRenderer.isNull() )
217  {
218  QgsAbstract3DRenderer *renderer = nullptr;
219  QString type = elemRenderer.attribute( QStringLiteral( "type" ) );
220  if ( type == QLatin1String( "vector" ) )
221  {
222  renderer = new QgsVectorLayer3DRenderer;
223  }
224  else if ( type == QLatin1String( "mesh" ) )
225  {
226  renderer = new QgsMeshLayer3DRenderer;
227  }
228  else if ( type == QLatin1String( "pointcloud" ) )
229  {
230  renderer = new QgsPointCloudLayer3DRenderer;
231  }
232 
233  if ( renderer )
234  {
235  renderer->readXml( elemRenderer, context );
236  mRenderers.append( renderer );
237  }
238  elemRenderer = elemRenderer.nextSiblingElement( QStringLiteral( "renderer" ) );
239  }
240 
241  QDomElement elemSkybox = elem.firstChildElement( QStringLiteral( "skybox" ) );
242  mIsSkyboxEnabled = elemSkybox.attribute( QStringLiteral( "skybox-enabled" ) ).toInt();
243  mSkyboxSettings.readXml( elemSkybox, context );
244 
245  QDomElement elemShadows = elem.firstChildElement( QStringLiteral( "shadow-rendering" ) );
246  mShadowSettings.readXml( elemShadows, context );
247 
248  QDomElement elemEyeDomeLighting = elem.firstChildElement( QStringLiteral( "eye-dome-lighting" ) );
249  mEyeDomeLightingEnabled = elemEyeDomeLighting.attribute( "enabled", QStringLiteral( "0" ) ).toInt();
250  mEyeDomeLightingStrength = elemEyeDomeLighting.attribute( "eye-dome-lighting-strength", QStringLiteral( "1000.0" ) ).toDouble();
251  mEyeDomeLightingDistance = elemEyeDomeLighting.attribute( "eye-dome-lighting-distance", QStringLiteral( "1" ) ).toInt();
252 
253  QDomElement elemDebugSettings = elem.firstChildElement( QStringLiteral( "debug-settings" ) );
254  mDebugShadowMapEnabled = elemDebugSettings.attribute( QStringLiteral( "shadowmap-enabled" ), QStringLiteral( "0" ) ).toInt();
255  mDebugShadowMapCorner = static_cast<Qt::Corner>( elemDebugSettings.attribute( QStringLiteral( "shadowmap-corner" ), "0" ).toInt() );
256  mDebugShadowMapSize = elemDebugSettings.attribute( QStringLiteral( "shadowmap-size" ), QStringLiteral( "0.2" ) ).toDouble();
257 
258  mDebugDepthMapEnabled = elemDebugSettings.attribute( QStringLiteral( "depthmap-enabled" ), QStringLiteral( "0" ) ).toInt();
259  mDebugDepthMapCorner = static_cast<Qt::Corner>( elemDebugSettings.attribute( QStringLiteral( "depthmap-corner" ), QStringLiteral( "1" ) ).toInt() );
260  mDebugDepthMapSize = elemDebugSettings.attribute( QStringLiteral( "depthmap-size" ), QStringLiteral( "0.2" ) ).toDouble();
261 
262  QDomElement elemDebug = elem.firstChildElement( QStringLiteral( "debug" ) );
263  mShowTerrainBoundingBoxes = elemDebug.attribute( QStringLiteral( "bounding-boxes" ), QStringLiteral( "0" ) ).toInt();
264  mShowTerrainTileInfo = elemDebug.attribute( QStringLiteral( "terrain-tile-info" ), QStringLiteral( "0" ) ).toInt();
265  mShowCameraViewCenter = elemDebug.attribute( QStringLiteral( "camera-view-center" ), QStringLiteral( "0" ) ).toInt();
266  mShowLightSources = elemDebug.attribute( QStringLiteral( "show-light-sources" ), QStringLiteral( "0" ) ).toInt();
267  mIsFpsCounterEnabled = elemDebug.attribute( QStringLiteral( "show-fps-counter" ), QStringLiteral( "0" ) ).toInt();
268 
269  QDomElement elemTemporalRange = elem.firstChildElement( QStringLiteral( "temporal-range" ) );
270  QDateTime start = QDateTime::fromString( elemTemporalRange.attribute( QStringLiteral( "start" ) ), Qt::ISODate );
271  QDateTime end = QDateTime::fromString( elemTemporalRange.attribute( QStringLiteral( "end" ) ), Qt::ISODate );
272  setTemporalRange( QgsDateTimeRange( start, end ) );
273 }
274 
275 QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
276 {
277  QDomElement elem = doc.createElement( QStringLiteral( "qgis3d" ) );
278 
279  QDomElement elemOrigin = doc.createElement( QStringLiteral( "origin" ) );
280  elemOrigin.setAttribute( QStringLiteral( "x" ), QString::number( mOrigin.x() ) );
281  elemOrigin.setAttribute( QStringLiteral( "y" ), QString::number( mOrigin.y() ) );
282  elemOrigin.setAttribute( QStringLiteral( "z" ), QString::number( mOrigin.z() ) );
283  elem.appendChild( elemOrigin );
284 
285  QDomElement elemCamera = doc.createElement( QStringLiteral( "camera" ) );
286  elemCamera.setAttribute( QStringLiteral( "field-of-view" ), mFieldOfView );
287  elemCamera.setAttribute( QStringLiteral( "projection-type" ), static_cast< int >( mProjectionType ) );
288  switch ( mCameraNavigationMode )
289  {
291  elemCamera.setAttribute( QStringLiteral( "camera-navigation-mode" ), QStringLiteral( "terrain-based-navigation" ) );
292  break;
294  elemCamera.setAttribute( QStringLiteral( "camera-navigation-mode" ), QStringLiteral( "walk-navigation" ) );
295  break;
296  }
297  elemCamera.setAttribute( QStringLiteral( "camera-movement-speed" ), mCameraMovementSpeed );
298  elem.appendChild( elemCamera );
299 
300  QDomElement elemColor = doc.createElement( QStringLiteral( "color" ) );
301  elemColor.setAttribute( QStringLiteral( "background" ), QgsSymbolLayerUtils::encodeColor( mBackgroundColor ) );
302  elemColor.setAttribute( QStringLiteral( "selection" ), QgsSymbolLayerUtils::encodeColor( mSelectionColor ) );
303  elem.appendChild( elemColor );
304 
305  QDomElement elemCrs = doc.createElement( QStringLiteral( "crs" ) );
306  mCrs.writeXml( elemCrs, doc );
307  elem.appendChild( elemCrs );
308 
309  QDomElement elemTerrain = doc.createElement( QStringLiteral( "terrain" ) );
310  elemTerrain.setAttribute( QStringLiteral( "terrain-rendering-enabled" ), mTerrainRenderingEnabled ? 1 : 0 );
311  elemTerrain.setAttribute( QStringLiteral( "exaggeration" ), QString::number( mTerrainVerticalScale ) );
312  elemTerrain.setAttribute( QStringLiteral( "texture-size" ), mMapTileResolution );
313  elemTerrain.setAttribute( QStringLiteral( "max-terrain-error" ), QString::number( mMaxTerrainScreenError ) );
314  elemTerrain.setAttribute( QStringLiteral( "max-ground-error" ), QString::number( mMaxTerrainGroundError ) );
315  elemTerrain.setAttribute( QStringLiteral( "shading-enabled" ), mTerrainShadingEnabled ? 1 : 0 );
316  elemTerrain.setAttribute( QStringLiteral( "elevation-offset" ), mTerrainElevationOffset );
317 
318  QDomElement elemTerrainShadingMaterial = doc.createElement( QStringLiteral( "shading-material" ) );
319  mTerrainShadingMaterial.writeXml( elemTerrainShadingMaterial, context );
320  elemTerrain.appendChild( elemTerrainShadingMaterial );
321  elemTerrain.setAttribute( QStringLiteral( "map-theme" ), mTerrainMapTheme );
322  elemTerrain.setAttribute( QStringLiteral( "show-labels" ), mShowLabels ? 1 : 0 );
323 
324  QDomElement elemPointLights = doc.createElement( QStringLiteral( "point-lights" ) );
325  for ( const QgsPointLightSettings &pointLight : std::as_const( mPointLights ) )
326  {
327  QDomElement elemPointLight = pointLight.writeXml( doc );
328  elemPointLights.appendChild( elemPointLight );
329  }
330  elem.appendChild( elemPointLights );
331 
332  QDomElement elemDirectionalLights = doc.createElement( QStringLiteral( "directional-lights" ) );
333  for ( const QgsDirectionalLightSettings &directionalLight : std::as_const( mDirectionalLights ) )
334  {
335  QDomElement elemDirectionalLight = directionalLight.writeXml( doc );
336  elemDirectionalLights.appendChild( elemDirectionalLight );
337  }
338  elem.appendChild( elemDirectionalLights );
339 
340  QDomElement elemMapLayers = doc.createElement( QStringLiteral( "layers" ) );
341  for ( const QgsMapLayerRef &layerRef : mLayers )
342  {
343  QDomElement elemMapLayer = doc.createElement( QStringLiteral( "layer" ) );
344  elemMapLayer.setAttribute( QStringLiteral( "id" ), layerRef.layerId );
345  elemMapLayers.appendChild( elemMapLayer );
346  }
347  elemTerrain.appendChild( elemMapLayers );
348 
349  QDomElement elemTerrainGenerator = doc.createElement( QStringLiteral( "generator" ) );
350  elemTerrainGenerator.setAttribute( QStringLiteral( "type" ), QgsTerrainGenerator::typeToString( mTerrainGenerator->type() ) );
351  mTerrainGenerator->writeXml( elemTerrainGenerator );
352  elemTerrain.appendChild( elemTerrainGenerator );
353  elem.appendChild( elemTerrain );
354 
355  QDomElement elemRenderers = doc.createElement( QStringLiteral( "renderers" ) );
356  for ( const QgsAbstract3DRenderer *renderer : mRenderers )
357  {
358  QDomElement elemRenderer = doc.createElement( QStringLiteral( "renderer" ) );
359  elemRenderer.setAttribute( QStringLiteral( "type" ), renderer->type() );
360  renderer->writeXml( elemRenderer, context );
361  elemRenderers.appendChild( elemRenderer );
362  }
363  elem.appendChild( elemRenderers );
364 
365  QDomElement elemSkybox = doc.createElement( QStringLiteral( "skybox" ) );
366  elemSkybox.setAttribute( QStringLiteral( "skybox-enabled" ), mIsSkyboxEnabled );
367  mSkyboxSettings.writeXml( elemSkybox, context );
368  elem.appendChild( elemSkybox );
369 
370  QDomElement elemShadows = doc.createElement( QStringLiteral( "shadow-rendering" ) );
371  mShadowSettings.writeXml( elemShadows, context );
372  elem.appendChild( elemShadows );
373 
374  QDomElement elemDebug = doc.createElement( QStringLiteral( "debug" ) );
375  elemDebug.setAttribute( QStringLiteral( "bounding-boxes" ), mShowTerrainBoundingBoxes ? 1 : 0 );
376  elemDebug.setAttribute( QStringLiteral( "terrain-tile-info" ), mShowTerrainTileInfo ? 1 : 0 );
377  elemDebug.setAttribute( QStringLiteral( "camera-view-center" ), mShowCameraViewCenter ? 1 : 0 );
378  elemDebug.setAttribute( QStringLiteral( "show-light-sources" ), mShowLightSources ? 1 : 0 );
379  elemDebug.setAttribute( QStringLiteral( "show-fps-counter" ), mIsFpsCounterEnabled ? 1 : 0 );
380  elem.appendChild( elemDebug );
381 
382  QDomElement elemEyeDomeLighting = doc.createElement( QStringLiteral( "eye-dome-lighting" ) );
383  elemEyeDomeLighting.setAttribute( "enabled", mEyeDomeLightingEnabled ? 1 : 0 );
384  elemEyeDomeLighting.setAttribute( "eye-dome-lighting-strength", mEyeDomeLightingStrength );
385  elemEyeDomeLighting.setAttribute( "eye-dome-lighting-distance", mEyeDomeLightingDistance );
386  elem.appendChild( elemEyeDomeLighting );
387 
388 
389  QDomElement elemDebugSettings = doc.createElement( QStringLiteral( "debug-settings" ) );
390  elemDebugSettings.setAttribute( QStringLiteral( "shadowmap-enabled" ), mDebugShadowMapEnabled );
391  elemDebugSettings.setAttribute( QStringLiteral( "shadowmap-corner" ), mDebugShadowMapCorner );
392  elemDebugSettings.setAttribute( QStringLiteral( "shadowmap-size" ), mDebugShadowMapSize );
393  elemDebugSettings.setAttribute( QStringLiteral( "depthmap-enabled" ), mDebugDepthMapEnabled );
394  elemDebugSettings.setAttribute( QStringLiteral( "depthmap-corner" ), mDebugDepthMapCorner );
395  elemDebugSettings.setAttribute( QStringLiteral( "depthmap-size" ), mDebugDepthMapSize );
396  elem.appendChild( elemDebugSettings );
397 
398  QDomElement elemTemporalRange = doc.createElement( QStringLiteral( "temporal-range" ) );
399  elemTemporalRange.setAttribute( QStringLiteral( "start" ), temporalRange().begin().toString( Qt::ISODate ) );
400  elemTemporalRange.setAttribute( QStringLiteral( "end" ), temporalRange().end().toString( Qt::ISODate ) );
401 
402  return elem;
403 }
404 
406 {
407  for ( int i = 0; i < mLayers.count(); ++i )
408  {
409  QgsMapLayerRef &layerRef = mLayers[i];
410  layerRef.setLayer( project.mapLayer( layerRef.layerId ) );
411  }
412 
413  mTerrainGenerator->resolveReferences( project );
414 
415  for ( int i = 0; i < mRenderers.count(); ++i )
416  {
417  QgsAbstract3DRenderer *renderer = mRenderers[i];
418  renderer->resolveReferences( project );
419  }
420 }
421 
423 {
424  return Qgs3DUtils::mapToWorldCoordinates( mapCoords, mOrigin );
425 }
426 
428 {
429  return Qgs3DUtils::worldToMapCoordinates( worldCoords, mOrigin );
430 }
431 
433 {
434  mCrs = crs;
435 }
436 
438 {
439  return mTransformContext;
440 }
441 
443 {
444  mTransformContext = context;
445 }
446 
447 void Qgs3DMapSettings::setBackgroundColor( const QColor &color )
448 {
449  if ( color == mBackgroundColor )
450  return;
451 
452  mBackgroundColor = color;
453  emit backgroundColorChanged();
454 }
455 
457 {
458  return mBackgroundColor;
459 }
460 
461 void Qgs3DMapSettings::setSelectionColor( const QColor &color )
462 {
463  if ( color == mSelectionColor )
464  return;
465 
466  mSelectionColor = color;
467  emit selectionColorChanged();
468 }
469 
471 {
472  return mSelectionColor;
473 }
474 
476 {
477  if ( zScale == mTerrainVerticalScale )
478  return;
479 
480  mTerrainVerticalScale = zScale;
482 }
483 
485 {
486  return mTerrainVerticalScale;
487 }
488 
489 void Qgs3DMapSettings::setLayers( const QList<QgsMapLayer *> &layers )
490 {
491  QList<QgsMapLayerRef> lst;
492  lst.reserve( layers.count() );
493  for ( QgsMapLayer *layer : layers )
494  {
495  lst.append( layer );
496  }
497 
498  if ( mLayers == lst )
499  return;
500 
501  mLayers = lst;
502  emit layersChanged();
503 }
504 
505 QList<QgsMapLayer *> Qgs3DMapSettings::layers() const
506 {
507  QList<QgsMapLayer *> lst;
508  lst.reserve( mLayers.count() );
509  for ( const QgsMapLayerRef &layerRef : mLayers )
510  {
511  if ( layerRef.layer )
512  lst.append( layerRef.layer );
513  }
514  return lst;
515 }
516 
518 {
519  if ( mMapTileResolution == res )
520  return;
521 
522  mMapTileResolution = res;
524 }
525 
527 {
528  return mMapTileResolution;
529 }
530 
532 {
533  if ( mMaxTerrainScreenError == error )
534  return;
535 
536  mMaxTerrainScreenError = error;
538 }
539 
541 {
542  return mMaxTerrainScreenError;
543 }
544 
546 {
547  if ( mMaxTerrainGroundError == error )
548  return;
549 
550  mMaxTerrainGroundError = error;
552 }
553 
555 {
556  if ( mTerrainElevationOffset == offset )
557  return;
558  mTerrainElevationOffset = offset;
559  emit terrainElevationOffsetChanged( mTerrainElevationOffset );
560 }
561 
563 {
564  return mMaxTerrainGroundError;
565 }
566 
568 {
569  if ( mTerrainGenerator )
570  {
571  disconnect( mTerrainGenerator.get(), &QgsTerrainGenerator::extentChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );
572  disconnect( mTerrainGenerator.get(), &QgsTerrainGenerator::terrainChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );
573  }
574 
575  mTerrainGenerator.reset( gen );
576  connect( mTerrainGenerator.get(), &QgsTerrainGenerator::extentChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );
577  connect( mTerrainGenerator.get(), &QgsTerrainGenerator::terrainChanged, this, &Qgs3DMapSettings::terrainGeneratorChanged );
578 
580 }
581 
583 {
584  if ( mTerrainShadingEnabled == enabled )
585  return;
586 
587  mTerrainShadingEnabled = enabled;
588  emit terrainShadingChanged();
589 }
590 
592 {
593  if ( mTerrainShadingMaterial == material )
594  return;
595 
596  mTerrainShadingMaterial = material;
597  emit terrainShadingChanged();
598 }
599 
600 void Qgs3DMapSettings::setTerrainMapTheme( const QString &theme )
601 {
602  if ( mTerrainMapTheme == theme )
603  return;
604 
605  mTerrainMapTheme = theme;
606  emit terrainMapThemeChanged();
607 }
608 
609 void Qgs3DMapSettings::setRenderers( const QList<QgsAbstract3DRenderer *> &renderers )
610 {
611  qDeleteAll( mRenderers );
612 
613  mRenderers = renderers;
614 
615  emit renderersChanged();
616 }
617 
619 {
620  if ( mShowTerrainBoundingBoxes == enabled )
621  return;
622 
623  mShowTerrainBoundingBoxes = enabled;
625 }
626 
628 {
629  if ( mShowTerrainTileInfo == enabled )
630  return;
631 
632  mShowTerrainTileInfo = enabled;
634 }
635 
637 {
638  if ( mShowCameraViewCenter == enabled )
639  return;
640 
641  mShowCameraViewCenter = enabled;
643 }
644 
646 {
647  if ( mShowLightSources == enabled )
648  return;
649 
650  mShowLightSources = enabled;
652 }
653 
655 {
656  if ( mShowLabels == enabled )
657  return;
658 
659  mShowLabels = enabled;
660  emit showLabelsChanged();
661 }
662 
664 {
665  if ( mEyeDomeLightingEnabled == enabled )
666  return;
667  mEyeDomeLightingEnabled = enabled;
669 }
670 
672 {
673  if ( mEyeDomeLightingStrength == strength )
674  return;
675  mEyeDomeLightingStrength = strength;
677 }
678 
680 {
681  if ( mEyeDomeLightingDistance == distance )
682  return;
683  mEyeDomeLightingDistance = distance;
685 }
686 
687 void Qgs3DMapSettings::setPointLights( const QList<QgsPointLightSettings> &pointLights )
688 {
689  if ( mPointLights == pointLights )
690  return;
691 
692  mPointLights = pointLights;
693  emit pointLightsChanged();
694 }
695 
696 void Qgs3DMapSettings::setDirectionalLights( const QList<QgsDirectionalLightSettings> &directionalLights )
697 {
698  if ( mDirectionalLights == directionalLights )
699  return;
700 
701  mDirectionalLights = directionalLights;
703 }
704 
705 void Qgs3DMapSettings::setFieldOfView( const float fieldOfView )
706 {
707  if ( mFieldOfView == fieldOfView )
708  return;
709 
710  mFieldOfView = fieldOfView;
711  emit fieldOfViewChanged();
712 }
713 
714 void Qgs3DMapSettings::setProjectionType( const Qt3DRender::QCameraLens::ProjectionType projectionType )
715 {
716  if ( mProjectionType == projectionType )
717  return;
718 
719  mProjectionType = projectionType;
720  emit projectionTypeChanged();
721 }
722 
724 {
725  if ( mCameraNavigationMode == navigationMode )
726  return;
727 
728  mCameraNavigationMode = navigationMode;
730 }
731 
732 void Qgs3DMapSettings::setCameraMovementSpeed( double movementSpeed )
733 {
734  if ( mCameraMovementSpeed == movementSpeed )
735  return;
736 
737  mCameraMovementSpeed = movementSpeed;
739 }
740 
742 {
743  mSkyboxSettings = skyboxSettings;
744  emit skyboxSettingsChanged();
745 }
746 
748 {
749  mShadowSettings = shadowSettings;
750  emit shadowSettingsChanged();
751 }
752 
753 void Qgs3DMapSettings::setDebugShadowMapSettings( bool enabled, Qt::Corner corner, double size )
754 {
755  mDebugShadowMapEnabled = enabled;
756  mDebugShadowMapCorner = corner;
757  mDebugShadowMapSize = size;
759 }
760 
761 void Qgs3DMapSettings::setDebugDepthMapSettings( bool enabled, Qt::Corner corner, double size )
762 {
763  mDebugDepthMapEnabled = enabled;
764  mDebugDepthMapCorner = corner;
765  mDebugDepthMapSize = size;
767 }
768 
769 void Qgs3DMapSettings::setIsFpsCounterEnabled( bool fpsCounterEnabled )
770 {
771  if ( fpsCounterEnabled == mIsFpsCounterEnabled )
772  return;
773  mIsFpsCounterEnabled = fpsCounterEnabled;
774  emit fpsCounterEnabledChanged( mIsFpsCounterEnabled );
775 }
776 
777 void Qgs3DMapSettings::setTerrainRenderingEnabled( bool terrainRenderingEnabled )
778 {
779  if ( terrainRenderingEnabled == mTerrainRenderingEnabled )
780  return;
781  mTerrainRenderingEnabled = terrainRenderingEnabled;
783 }
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.
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.
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.
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:442
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:434
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()
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:101
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 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.