Skip to content
Permalink
Browse files

Merge pull request #8509 from wonder-sk/terrain-map-themes

[FEATURE] Optionally use a map theme to render terrain textures
  • Loading branch information
wonder-sk committed Nov 22, 2018
2 parents fee3935 + afd3525 commit d4ef55dadb6c850b9ee38d343b3eda3612a8077f
@@ -39,6 +39,7 @@ Qgs3DMapSettings::Qgs3DMapSettings( const Qgs3DMapSettings &other )
, mMaxTerrainGroundError( other.mMaxTerrainGroundError )
, mTerrainShadingEnabled( other.mTerrainShadingEnabled )
, mTerrainShadingMaterial( other.mTerrainShadingMaterial )
, mTerrainMapTheme( other.mTerrainMapTheme )
, mShowTerrainBoundingBoxes( other.mShowTerrainBoundingBoxes )
, mShowTerrainTileInfo( other.mShowTerrainTileInfo )
, mShowCameraViewCenter( other.mShowCameraViewCenter )
@@ -48,6 +49,9 @@ Qgs3DMapSettings::Qgs3DMapSettings( const Qgs3DMapSettings &other )
, mSkyboxEnabled( other.mSkyboxEnabled )
, mSkyboxFileBase( other.mSkyboxFileBase )
, mSkyboxFileExtension( other.mSkyboxFileExtension )
, mTransformContext( other.mTransformContext )
, mPathResolver( other.mPathResolver )
, mMapThemes( other.mMapThemes )
{
Q_FOREACH ( QgsAbstract3DRenderer *renderer, other.mRenderers )
{
@@ -87,6 +91,7 @@ void Qgs3DMapSettings::readXml( const QDomElement &elem, const QgsReadWriteConte
QDomElement elemTerrainShadingMaterial = elemTerrain.firstChildElement( QStringLiteral( "shading-material" ) );
if ( !elemTerrainShadingMaterial.isNull() )
mTerrainShadingMaterial.readXml( elemTerrainShadingMaterial );
mTerrainMapTheme = elemTerrain.attribute( QStringLiteral( "map-theme" ) );
mShowLabels = elemTerrain.attribute( QStringLiteral( "show-labels" ), QStringLiteral( "0" ) ).toInt();

mPointLights.clear();
@@ -204,6 +209,7 @@ QDomElement Qgs3DMapSettings::writeXml( QDomDocument &doc, const QgsReadWriteCon
QDomElement elemTerrainShadingMaterial = doc.createElement( QStringLiteral( "shading-material" ) );
mTerrainShadingMaterial.writeXml( elemTerrainShadingMaterial );
elemTerrain.appendChild( elemTerrainShadingMaterial );
elemTerrain.setAttribute( QStringLiteral( "map-theme" ), mTerrainMapTheme );
elemTerrain.setAttribute( QStringLiteral( "show-labels" ), mShowLabels ? 1 : 0 );

QDomElement elemPointLights = doc.createElement( QStringLiteral( "point-lights" ) );
@@ -432,6 +438,15 @@ void Qgs3DMapSettings::setTerrainShadingMaterial( const QgsPhongMaterialSettings
emit terrainShadingChanged();
}

void Qgs3DMapSettings::setTerrainMapTheme( const QString &theme )
{
if ( mTerrainMapTheme == theme )
return;

mTerrainMapTheme = theme;
emit terrainMapThemeChanged();
}

void Qgs3DMapSettings::setRenderers( const QList<QgsAbstract3DRenderer *> &renderers )
{
mRenderers = renderers;
@@ -126,6 +126,21 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject
*/
void setPathResolver( const QgsPathResolver &resolver ) { mPathResolver = resolver; }

/**
* Returns pointer to the collection of map themes. Normally this would be QgsProject::mapThemeCollection()
* of the currently used project. Without a valid map theme collection object it is not possible
* to resolve map themes from their names.
* \since QGIS 3.6
*/
QgsMapThemeCollection *mapThemeCollection() const { return mMapThemes; }

/**
* Sets pointer to the collection of map themes.
* \see mapThemeCollection()
* \since QGIS 3.6
*/
void setMapThemeCollection( QgsMapThemeCollection *mapThemes ) { mMapThemes = mapThemes; }

//! Sets background color of the 3D map view
void setBackgroundColor( const QColor &color );
//! Returns background color of the 3D map view
@@ -148,9 +163,16 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject
//! Returns vertical scale (exaggeration) of terrain
double terrainVerticalScale() const;

//! Sets the list of map layers to be rendered as a texture of the terrain
/**
* Sets the list of map layers to be rendered as a texture of the terrain
* \note If terrain map theme is set, it has a priority over the list of layers specified here.
*/
void setLayers( const QList<QgsMapLayer *> &layers );
//! Returns the list of map layers to be rendered as a texture of the terrain

/**
* Returns the list of map layers to be rendered as a texture of the terrain
* \note If terrain map theme is set, it has a priority over the list of layers specified here.
*/
QList<QgsMapLayer *> layers() const;

/**
@@ -231,6 +253,25 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject
*/
QgsPhongMaterialSettings terrainShadingMaterial() const { return mTerrainShadingMaterial; }

/**
* Sets name of the map theme.
* \see terrainMapTheme()
* \since QGIS 3.6
*/
void setTerrainMapTheme( const QString &theme );

/**
* Returns name of the map theme (from the active project) that will be used for terrain's texture.
* Empty map theme name means that the map theme is not overridden and the current map theme will be used.
* \note Support for map themes only works if mapThemeCollection() is a valid object (otherwise it is not possible to resolve map themes from names)
* \since QGIS 3.6
*/
QString terrainMapTheme() const { return mTerrainMapTheme; }

//
// misc configuration
//

//! Sets list of extra 3D renderers to use in the scene. Takes ownership of the objects.
void setRenderers( const QList<QgsAbstract3DRenderer *> &renderers SIP_TRANSFER );
//! Returns list of extra 3D renderers
@@ -310,6 +351,12 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject
* \since QGIS 3.6
*/
void terrainShadingChanged();

/**
* Emitted when terrain's map theme has changed
* \since QGIS 3.6
*/
void terrainMapThemeChanged();
//! Emitted when the flag whether terrain's bounding boxes are shown has changed
void showTerrainBoundingBoxesChanged();
//! Emitted when the flag whether terrain's tile info is shown has changed
@@ -342,6 +389,7 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject
float mMaxTerrainGroundError = 1.f; //!< Maximum allowed horizontal map error in map units (determines how many zoom levels will be used)
bool mTerrainShadingEnabled = false; //!< Whether terrain should be shaded taking lights into account
QgsPhongMaterialSettings mTerrainShadingMaterial; //!< Material to use for the terrain (if shading is enabled). Diffuse color is ignored.
QString mTerrainMapTheme; //!< Name of map theme used for terrain's texture (empty means use the current map theme)
bool mShowTerrainBoundingBoxes = false; //!< Whether to show bounding boxes of entities - useful for debugging
bool mShowTerrainTileInfo = false; //!< Whether to draw extra information about terrain tiles to the textures - useful for debugging
bool mShowCameraViewCenter = false; //!< Whether to show camera view center as a sphere - useful for debugging
@@ -355,6 +403,7 @@ class _3D_EXPORT Qgs3DMapSettings : public QObject
//! Coordinate transform context
QgsCoordinateTransformContext mTransformContext;
QgsPathResolver mPathResolver;
QgsMapThemeCollection *mMapThemes = nullptr; //!< Pointer to map themes (e.g. from the current project) to resolve map theme content from the name
};


@@ -217,7 +217,13 @@ bool QgsLayoutItem3DMap::readPropertiesFromElement( const QDomElement &element,
mSettings.reset( new Qgs3DMapSettings );
mSettings->readXml( elemSettings, context );
if ( mLayout->project() )
{
mSettings->resolveReferences( *mLayout->project() );

mSettings->setTransformContext( mLayout->project()->transformContext() );
mSettings->setPathResolver( mLayout->project()->pathResolver() );
mSettings->setMapThemeCollection( mLayout->project()->mapThemeCollection() );
}
}

QDomElement elemCameraPose = element.firstChildElement( QStringLiteral( "camera-pose" ) );
@@ -69,6 +69,7 @@ QgsTerrainEntity::QgsTerrainEntity( int maxLevel, const Qgs3DMapSettings &map, Q
connect( &map, &Qgs3DMapSettings::showLabelsChanged, this, &QgsTerrainEntity::invalidateMapImages );
connect( &map, &Qgs3DMapSettings::layersChanged, this, &QgsTerrainEntity::onLayersChanged );
connect( &map, &Qgs3DMapSettings::backgroundColorChanged, this, &QgsTerrainEntity::invalidateMapImages );
connect( &map, &Qgs3DMapSettings::terrainMapThemeChanged, this, &QgsTerrainEntity::invalidateMapImages );

connectToLayersRepaintRequest();

@@ -18,6 +18,7 @@
#include <qgsmaprenderercustompainterjob.h>
#include <qgsmaprenderersequentialjob.h>
#include <qgsmapsettings.h>
#include <qgsmapthemecollection.h>
#include <qgsproject.h>

#include "qgs3dmapsettings.h"
@@ -127,13 +128,26 @@ void QgsTerrainTextureGenerator::onRenderingFinished()
QgsMapSettings QgsTerrainTextureGenerator::baseMapSettings()
{
QgsMapSettings mapSettings;
mapSettings.setLayers( mMap.layers() );

mapSettings.setOutputSize( QSize( mMap.mapTileResolution(), mMap.mapTileResolution() ) );
mapSettings.setDestinationCrs( mMap.crs() );
mapSettings.setBackgroundColor( mMap.backgroundColor() );
mapSettings.setFlag( QgsMapSettings::DrawLabeling, mMap.showLabels() );
mapSettings.setTransformContext( mMap.transformContext() );
mapSettings.setPathResolver( mMap.pathResolver() );

QgsMapThemeCollection *mapThemes = mMap.mapThemeCollection();
QString mapThemeName = mMap.terrainMapTheme();
if ( mapThemeName.isEmpty() || !mapThemes || !mapThemes->hasMapTheme( mapThemeName ) )
{
mapSettings.setLayers( mMap.layers() );
}
else
{
mapSettings.setLayers( mapThemes->mapThemeVisibleLayers( mapThemeName ) );
mapSettings.setLayerStyleOverrides( mapThemes->mapThemeStyleOverrides( mapThemeName ) );
}

return mapSettings;
}

@@ -21,8 +21,9 @@
#include "qgs3dutils.h"

#include "qgsmapcanvas.h"
#include "qgsmapthemecollection.h"
#include "qgsrasterlayer.h"
//#include "qgsproject.h"
#include "qgsproject.h"

Qgs3DMapConfigWidget::Qgs3DMapConfigWidget( Qgs3DMapSettings *map, QgsMapCanvas *mainCanvas, QWidget *parent )
: QWidget( parent )
@@ -73,6 +74,14 @@ Qgs3DMapConfigWidget::Qgs3DMapConfigWidget( Qgs3DMapSettings *map, QgsMapCanvas
widgetTerrainMaterial->setDiffuseVisible( false );
widgetTerrainMaterial->setMaterial( mMap->terrainShadingMaterial() );

// populate combo box with map themes
const QStringList mapThemeNames = QgsProject::instance()->mapThemeCollection()->mapThemes();
cboTerrainMapTheme->addItem( QString() ); // empty item for no map theme
for ( QString themeName : mapThemeNames )
cboTerrainMapTheme->addItem( themeName );

cboTerrainMapTheme->setCurrentText( mMap->terrainMapTheme() );

widgetLights->setPointLights( mMap->pointLights() );

connect( cboTerrainLayer, static_cast<void ( QComboBox::* )( int )>( &QgsMapLayerComboBox::currentIndexChanged ), this, &Qgs3DMapConfigWidget::onTerrainLayerChanged );
@@ -144,6 +153,8 @@ void Qgs3DMapConfigWidget::apply()
mMap->setTerrainShadingEnabled( groupTerrainShading->isChecked() );
mMap->setTerrainShadingMaterial( widgetTerrainMaterial->material() );

mMap->setTerrainMapTheme( cboTerrainMapTheme->currentText() );

mMap->setPointLights( widgetLights->pointLights() );
}

@@ -11141,8 +11141,10 @@ void QgisApp::new3DMapCanvas()
map->setSelectionColor( mMapCanvas->selectionColor() );
map->setBackgroundColor( mMapCanvas->canvasColor() );
map->setLayers( mMapCanvas->layers() );

map->setTransformContext( QgsProject::instance()->transformContext() );
map->setPathResolver( QgsProject::instance()->pathResolver() );
map->setMapThemeCollection( QgsProject::instance()->mapThemeCollection() );
connect( QgsProject::instance(), &QgsProject::transformContextChanged, map, [map]
{
map->setTransformContext( QgsProject::instance()->transformContext() );
@@ -13562,6 +13564,14 @@ void QgisApp::readProject( const QDomDocument &doc )
map->readXml( elem3D, readWriteContext );
map->resolveReferences( *QgsProject::instance() );

map->setTransformContext( QgsProject::instance()->transformContext() );
map->setPathResolver( QgsProject::instance()->pathResolver() );
map->setMapThemeCollection( QgsProject::instance()->mapThemeCollection() );
connect( QgsProject::instance(), &QgsProject::transformContextChanged, map, [map]
{
map->setTransformContext( QgsProject::instance()->transformContext() );
} );

// these things are not saved in project
map->setSelectionColor( mMapCanvas->selectionColor() );
map->setBackgroundColor( mMapCanvas->canvasColor() );
@@ -7,15 +7,15 @@
<x>0</x>
<y>0</y>
<width>691</width>
<height>1135</height>
<height>1122</height>
</rect>
</property>
<property name="windowTitle">
<string>Configure 3D Map Rendering</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<widget class="QgsCollapsibleGroupBox" name="groupTerrain">
<property name="title">
<string>Terrain</string>
</property>
@@ -84,6 +84,20 @@
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Map theme</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QComboBox" name="cboTerrainMapTheme">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@@ -275,12 +289,15 @@
<tabstop>spinTerrainScale</tabstop>
<tabstop>spinTerrainResolution</tabstop>
<tabstop>spinTerrainSkirtHeight</tabstop>
<tabstop>cboTerrainMapTheme</tabstop>
<tabstop>groupTerrainShading</tabstop>
<tabstop>spinMapResolution</tabstop>
<tabstop>spinScreenError</tabstop>
<tabstop>spinGroundError</tabstop>
<tabstop>chkShowLabels</tabstop>
<tabstop>chkShowTileInfo</tabstop>
<tabstop>chkShowBoundingBoxes</tabstop>
<tabstop>chkShowCameraViewCenter</tabstop>
</tabstops>
<resources/>
<connections/>

0 comments on commit d4ef55d

Please sign in to comment.
You can’t perform that action at this time.