mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-06 00:03:16 -05:00
173 lines
6.8 KiB
C++
173 lines
6.8 KiB
C++
/***************************************************************************
|
|
qgsprojectelevationsettingswidget.cpp
|
|
---------------------
|
|
begin : March 2022
|
|
copyright : (C) 2022 by Nyall Dawson
|
|
email : nyall dot dawson at gmail dot com
|
|
***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "qgsprojectelevationsettingswidget.h"
|
|
#include "qgsapplication.h"
|
|
#include "qgsproject.h"
|
|
#include "qgsterrainprovider.h"
|
|
#include "qgsprojectelevationproperties.h"
|
|
#include "qgsrasterlayerelevationproperties.h"
|
|
#include "qgselevationshadingrenderersettingswidget.h"
|
|
|
|
QgsProjectElevationSettingsWidget::QgsProjectElevationSettingsWidget( QWidget *parent )
|
|
: QgsOptionsPageWidget( parent )
|
|
{
|
|
setupUi( this );
|
|
|
|
mFlatHeightSpinBox->setClearValue( 0.0 );
|
|
|
|
mDemOffsetSpinBox->setClearValue( 0.0 );
|
|
mDemScaleSpinBox->setClearValue( 1.0 );
|
|
mComboDemLayer->setFilters( Qgis::LayerFilter::RasterLayer );
|
|
|
|
mMeshOffsetSpinBox->setClearValue( 0.0 );
|
|
mMeshScaleSpinBox->setClearValue( 1.0 );
|
|
mComboMeshLayer->setFilters( Qgis::LayerFilter::MeshLayer );
|
|
|
|
mComboTerrainType->addItem( tr( "Flat Terrain" ), QStringLiteral( "flat" ) );
|
|
mComboTerrainType->addItem( tr( "DEM (Raster Layer)" ), QStringLiteral( "raster" ) );
|
|
mComboTerrainType->addItem( tr( "Mesh" ), QStringLiteral( "mesh" ) );
|
|
|
|
mStackedWidget->setCurrentWidget( mPageFlat );
|
|
connect( mComboTerrainType, qOverload< int >( &QComboBox::currentIndexChanged ), this, [ = ]
|
|
{
|
|
const QString terrainType = mComboTerrainType->currentData().toString();
|
|
if ( terrainType == QLatin1String( "flat" ) )
|
|
{
|
|
mStackedWidget->setCurrentWidget( mPageFlat );
|
|
}
|
|
else if ( terrainType == QLatin1String( "raster" ) )
|
|
{
|
|
mStackedWidget->setCurrentWidget( mPageRasterDem );
|
|
}
|
|
else if ( terrainType == QLatin1String( "mesh" ) )
|
|
{
|
|
mStackedWidget->setCurrentWidget( mPageMesh );
|
|
}
|
|
validate();
|
|
} );
|
|
|
|
// setup with current settings
|
|
const QgsAbstractTerrainProvider *provider = QgsProject::instance()->elevationProperties()->terrainProvider();
|
|
mComboTerrainType->setCurrentIndex( mComboTerrainType->findData( provider->type() ) );
|
|
if ( provider->type() == QLatin1String( "flat" ) )
|
|
{
|
|
mStackedWidget->setCurrentWidget( mPageFlat );
|
|
mFlatHeightSpinBox->setValue( provider->offset() );
|
|
}
|
|
else if ( provider->type() == QLatin1String( "raster" ) )
|
|
{
|
|
mStackedWidget->setCurrentWidget( mPageRasterDem );
|
|
mDemOffsetSpinBox->setValue( provider->offset() );
|
|
mDemScaleSpinBox->setValue( provider->scale() );
|
|
mComboDemLayer->setLayer( qgis::down_cast< const QgsRasterDemTerrainProvider * >( provider )->layer() );
|
|
}
|
|
else if ( provider->type() == QLatin1String( "mesh" ) )
|
|
{
|
|
mStackedWidget->setCurrentWidget( mPageMesh );
|
|
mMeshOffsetSpinBox->setValue( provider->offset() );
|
|
mMeshScaleSpinBox->setValue( provider->scale() );
|
|
mComboMeshLayer->setLayer( qgis::down_cast< const QgsMeshTerrainProvider * >( provider )->layer() );
|
|
}
|
|
|
|
connect( mComboDemLayer, &QgsMapLayerComboBox::layerChanged, this, &QgsProjectElevationSettingsWidget::validate );
|
|
connect( mComboMeshLayer, &QgsMapLayerComboBox::layerChanged, this, &QgsProjectElevationSettingsWidget::validate );
|
|
|
|
validate();
|
|
|
|
mElevationShadingSettingsWidget = new QgsElevationShadingRendererSettingsWidget( nullptr, nullptr, this );
|
|
mElevationShadingSettingsLayout->addWidget( mElevationShadingSettingsWidget );
|
|
}
|
|
|
|
void QgsProjectElevationSettingsWidget::apply()
|
|
{
|
|
const QString terrainType = mComboTerrainType->currentData().toString();
|
|
std::unique_ptr< QgsAbstractTerrainProvider > provider;
|
|
if ( terrainType == QLatin1String( "flat" ) )
|
|
{
|
|
provider = std::make_unique< QgsFlatTerrainProvider >();
|
|
provider->setOffset( mFlatHeightSpinBox->value() );
|
|
provider->setScale( 1.0 );
|
|
}
|
|
else if ( terrainType == QLatin1String( "raster" ) )
|
|
{
|
|
provider = std::make_unique< QgsRasterDemTerrainProvider >();
|
|
provider->setOffset( mDemOffsetSpinBox->value() );
|
|
provider->setScale( mDemScaleSpinBox->value() );
|
|
QgsRasterLayer *demLayer = qobject_cast< QgsRasterLayer * >( mComboDemLayer->currentLayer() );
|
|
// always mark the terrain layer as a "dem" layer -- it seems odd for a user to have to manually set this after picking a terrain raster!
|
|
qobject_cast< QgsRasterLayerElevationProperties * >( demLayer->elevationProperties() )->setEnabled( true );
|
|
qgis::down_cast< QgsRasterDemTerrainProvider * >( provider.get() )->setLayer( demLayer );
|
|
}
|
|
else if ( terrainType == QLatin1String( "mesh" ) )
|
|
{
|
|
provider = std::make_unique< QgsMeshTerrainProvider >();
|
|
provider->setOffset( mMeshOffsetSpinBox->value() );
|
|
provider->setScale( mMeshScaleSpinBox->value() );
|
|
qgis::down_cast< QgsMeshTerrainProvider * >( provider.get() )->setLayer( qobject_cast< QgsMeshLayer * >( mComboMeshLayer->currentLayer() ) );
|
|
}
|
|
|
|
QgsProject::instance()->elevationProperties()->setTerrainProvider( provider.release() );
|
|
|
|
mElevationShadingSettingsWidget->apply();
|
|
}
|
|
|
|
bool QgsProjectElevationSettingsWidget::validate()
|
|
{
|
|
mMessageBar->clearWidgets();
|
|
|
|
bool valid = true;
|
|
const QString terrainType = mComboTerrainType->currentData().toString();
|
|
if ( terrainType == QLatin1String( "raster" ) )
|
|
{
|
|
if ( !mComboDemLayer->currentLayer() )
|
|
{
|
|
valid = false;
|
|
mMessageBar->pushMessage( tr( "An elevation layer must be selected for a DEM terrain" ), Qgis::MessageLevel::Critical );
|
|
}
|
|
}
|
|
else if ( terrainType == QLatin1String( "mesh" ) )
|
|
{
|
|
if ( !mComboMeshLayer->currentLayer() )
|
|
{
|
|
valid = false;
|
|
mMessageBar->pushMessage( tr( "An elevation layer must be selected for a mesh terrain" ), Qgis::MessageLevel::Critical );
|
|
}
|
|
}
|
|
return valid;
|
|
}
|
|
|
|
bool QgsProjectElevationSettingsWidget::isValid()
|
|
{
|
|
return validate();
|
|
}
|
|
|
|
|
|
//
|
|
// QgsProjectElevationSettingsWidgetFactory
|
|
//
|
|
|
|
QgsProjectElevationSettingsWidgetFactory::QgsProjectElevationSettingsWidgetFactory( QObject *parent )
|
|
: QgsOptionsWidgetFactory( tr( "Terrain" ), QgsApplication::getThemeIcon( QStringLiteral( "mLayoutItem3DMap.svg" ) ), QStringLiteral( "terrain" ) )
|
|
{
|
|
setParent( parent );
|
|
}
|
|
|
|
|
|
QgsOptionsPageWidget *QgsProjectElevationSettingsWidgetFactory::createWidget( QWidget *parent ) const
|
|
{
|
|
return new QgsProjectElevationSettingsWidget( parent );
|
|
}
|