mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-08 00:05:09 -04:00
Add QgsMapLayerElevationProperties subclass for raster layers
Allows elevation properties to be set for raster layers, including: - whether raster values represent heights - scale - offset These properties can be set through the new "Elevation" tab in the raster layer properties dialog
This commit is contained in:
parent
1bd6c4535a
commit
2379de4a95
@ -25,12 +25,17 @@ how an individual :py:class:`QgsMapLayer` behaves with relation to z values or e
|
||||
%TypeHeaderCode
|
||||
#include "qgsmaplayerelevationproperties.h"
|
||||
#include "qgspointcloudlayerelevationproperties.h"
|
||||
#include "qgsrasterlayerelevationproperties.h"
|
||||
%End
|
||||
%ConvertToSubClassCode
|
||||
if ( qobject_cast<QgsPointCloudLayerElevationProperties *>( sipCpp ) )
|
||||
{
|
||||
sipType = sipType_QgsPointCloudLayerElevationProperties;
|
||||
}
|
||||
else if ( qobject_cast<QgsRasterLayerElevationProperties *>( sipCpp ) )
|
||||
{
|
||||
sipType = sipType_QgsRasterLayerElevationProperties;
|
||||
}
|
||||
else
|
||||
{
|
||||
sipType = 0;
|
||||
|
@ -421,6 +421,8 @@ to be drawn outside the data extent.
|
||||
|
||||
virtual QgsMapLayerTemporalProperties *temporalProperties();
|
||||
|
||||
virtual QgsMapLayerElevationProperties *elevationProperties();
|
||||
|
||||
|
||||
public slots:
|
||||
void showStatusMessage( const QString &message );
|
||||
|
@ -0,0 +1,112 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/raster/qgsrasterlayerelevationproperties.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsRasterLayerElevationProperties : QgsMapLayerElevationProperties
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
Raster layer specific subclass of :py:class:`QgsMapLayerElevationProperties`.
|
||||
|
||||
.. versionadded:: 3.26
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsrasterlayerelevationproperties.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsRasterLayerElevationProperties( QObject *parent /TransferThis/ );
|
||||
%Docstring
|
||||
Constructor for QgsRasterLayerElevationProperties, with the specified ``parent`` object.
|
||||
%End
|
||||
|
||||
virtual bool hasElevation() const;
|
||||
|
||||
virtual QDomElement writeXml( QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context );
|
||||
|
||||
virtual bool readXml( const QDomElement &element, const QgsReadWriteContext &context );
|
||||
|
||||
virtual bool isVisibleInZRange( const QgsDoubleRange &range ) const;
|
||||
|
||||
virtual QgsDoubleRange calculateZRange( QgsMapLayer *layer ) const;
|
||||
|
||||
|
||||
bool isEnabled() const;
|
||||
%Docstring
|
||||
Returns ``True`` if the elevation properties are enabled, i.e. the raster layer values represent an elevation surface.
|
||||
|
||||
.. seealso:: :py:func:`setEnabled`
|
||||
%End
|
||||
|
||||
void setEnabled( bool enabled );
|
||||
%Docstring
|
||||
Sets whether the elevation properties are enabled, i.e. the raster layer values represent an elevation surface.
|
||||
|
||||
.. seealso:: :py:func:`isEnabled`
|
||||
%End
|
||||
|
||||
double zOffset() const;
|
||||
%Docstring
|
||||
Returns the z offset, which is a fixed offset amount which should be added to z values from
|
||||
the layer.
|
||||
|
||||
.. note::
|
||||
|
||||
Any scaling specified via :py:func:`~QgsRasterLayerElevationProperties.zScale` is applied before any offset value specified via :py:func:`~QgsRasterLayerElevationProperties.zOffset`
|
||||
|
||||
.. seealso:: :py:func:`setZOffset`
|
||||
%End
|
||||
|
||||
void setZOffset( double offset );
|
||||
%Docstring
|
||||
Sets the z ``offset``, which is a fixed offset amount which will be added to z values from
|
||||
the layer.
|
||||
|
||||
.. note::
|
||||
|
||||
Any scaling specified via :py:func:`~QgsRasterLayerElevationProperties.zScale` is applied before any offset value specified via :py:func:`~QgsRasterLayerElevationProperties.zOffset`
|
||||
|
||||
.. seealso:: :py:func:`zOffset`
|
||||
%End
|
||||
|
||||
double zScale() const;
|
||||
%Docstring
|
||||
Returns the z scale, which is a scaling factor which should be applied to z values from
|
||||
the layer.
|
||||
|
||||
.. note::
|
||||
|
||||
Any scaling specified via :py:func:`~QgsRasterLayerElevationProperties.zScale` is applied before any offset value specified via :py:func:`~QgsRasterLayerElevationProperties.zOffset`
|
||||
|
||||
.. seealso:: :py:func:`setZScale`
|
||||
%End
|
||||
|
||||
void setZScale( double scale );
|
||||
%Docstring
|
||||
Sets the z ``scale``, which is a scaling factor which will be applied to z values from
|
||||
the layer.
|
||||
|
||||
.. note::
|
||||
|
||||
Any scaling specified via :py:func:`~QgsRasterLayerElevationProperties.zScale` is applied before any offset value specified via :py:func:`~QgsRasterLayerElevationProperties.zOffset`
|
||||
|
||||
.. seealso:: :py:func:`zScale`
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/raster/qgsrasterlayerelevationproperties.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -577,6 +577,7 @@
|
||||
%Include auto_generated/raster/qgsrasterinterface.sip
|
||||
%Include auto_generated/raster/qgsrasteriterator.sip
|
||||
%Include auto_generated/raster/qgsrasterlayer.sip
|
||||
%Include auto_generated/raster/qgsrasterlayerelevationproperties.sip
|
||||
%Include auto_generated/raster/qgsrasterlayertemporalproperties.sip
|
||||
%Include auto_generated/raster/qgsrasterminmaxorigin.sip
|
||||
%Include auto_generated/raster/qgsrasternuller.sip
|
||||
|
@ -130,6 +130,8 @@ set(QGIS_APP_SRCS
|
||||
pointcloud/qgspointcloudlayerproperties.cpp
|
||||
pointcloud/qgspointcloudlayerstylewidget.cpp
|
||||
|
||||
raster/qgsrasterelevationpropertieswidget.cpp
|
||||
|
||||
vectortile/qgsvectortilelayerproperties.cpp
|
||||
|
||||
vertextool/qgslockedfeature.cpp
|
||||
|
@ -117,6 +117,8 @@
|
||||
#include "options/qgsgpsdeviceoptions.h"
|
||||
#include "options/qgscustomprojectionoptions.h"
|
||||
|
||||
#include "raster/qgsrasterelevationpropertieswidget.h"
|
||||
|
||||
#ifdef HAVE_3D
|
||||
#include "qgs3d.h"
|
||||
#include "qgs3danimationsettings.h"
|
||||
@ -1478,6 +1480,7 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipBadLayers
|
||||
registerMapLayerPropertiesFactory( new QgsPointCloudLayer3DRendererWidgetFactory( this ) );
|
||||
#endif
|
||||
registerMapLayerPropertiesFactory( new QgsPointCloudElevationPropertiesWidgetFactory( this ) );
|
||||
registerMapLayerPropertiesFactory( new QgsRasterElevationPropertiesWidgetFactory( this ) );
|
||||
registerMapLayerPropertiesFactory( new QgsAnnotationItemPropertiesWidgetFactory( this ) );
|
||||
registerMapLayerPropertiesFactory( new QgsLayerTreeGroupPropertiesWidgetFactory( this ) );
|
||||
|
||||
|
107
src/app/raster/qgsrasterelevationpropertieswidget.cpp
Normal file
107
src/app/raster/qgsrasterelevationpropertieswidget.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/***************************************************************************
|
||||
qgsrasterelevationpropertieswidget.cpp
|
||||
---------------------
|
||||
begin : February 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 "qgsrasterelevationpropertieswidget.h"
|
||||
#include "qgsstyle.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsmaplayer.h"
|
||||
#include "qgsrasterlayer.h"
|
||||
#include "qgsrasterlayerelevationproperties.h"
|
||||
|
||||
QgsRasterElevationPropertiesWidget::QgsRasterElevationPropertiesWidget( QgsRasterLayer *layer, QgsMapCanvas *canvas, QWidget *parent )
|
||||
: QgsMapLayerConfigWidget( layer, canvas, parent )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
mOffsetZSpinBox->setClearValue( 0 );
|
||||
mScaleZSpinBox->setClearValue( 1 );
|
||||
mElevationGroupBox->setChecked( false );
|
||||
|
||||
syncToLayer( layer );
|
||||
|
||||
connect( mOffsetZSpinBox, qOverload<double >( &QDoubleSpinBox::valueChanged ), this, &QgsRasterElevationPropertiesWidget::onChanged );
|
||||
connect( mScaleZSpinBox, qOverload<double >( &QDoubleSpinBox::valueChanged ), this, &QgsRasterElevationPropertiesWidget::onChanged );
|
||||
connect( mElevationGroupBox, &QGroupBox::toggled, this, &QgsRasterElevationPropertiesWidget::onChanged );
|
||||
}
|
||||
|
||||
void QgsRasterElevationPropertiesWidget::syncToLayer( QgsMapLayer *layer )
|
||||
{
|
||||
mLayer = qobject_cast< QgsRasterLayer * >( layer );
|
||||
if ( !mLayer )
|
||||
return;
|
||||
|
||||
mBlockUpdates = true;
|
||||
const QgsRasterLayerElevationProperties *props = qgis::down_cast< const QgsRasterLayerElevationProperties * >( mLayer->elevationProperties() );
|
||||
mElevationGroupBox->setChecked( props->isEnabled() );
|
||||
mOffsetZSpinBox->setValue( props->zOffset() );
|
||||
mScaleZSpinBox->setValue( props->zScale() );
|
||||
mBlockUpdates = false;
|
||||
}
|
||||
|
||||
void QgsRasterElevationPropertiesWidget::apply()
|
||||
{
|
||||
if ( !mLayer )
|
||||
return;
|
||||
|
||||
QgsRasterLayerElevationProperties *props = qgis::down_cast< QgsRasterLayerElevationProperties * >( mLayer->elevationProperties() );
|
||||
props->setEnabled( mElevationGroupBox->isChecked() );
|
||||
props->setZOffset( mOffsetZSpinBox->value() );
|
||||
props->setZScale( mScaleZSpinBox->value() );
|
||||
mLayer->trigger3DUpdate();
|
||||
}
|
||||
|
||||
void QgsRasterElevationPropertiesWidget::onChanged()
|
||||
{
|
||||
if ( !mBlockUpdates )
|
||||
emit widgetChanged();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// QgsRasterElevationPropertiesWidgetFactory
|
||||
//
|
||||
|
||||
QgsRasterElevationPropertiesWidgetFactory::QgsRasterElevationPropertiesWidgetFactory( QObject *parent )
|
||||
: QObject( parent )
|
||||
{
|
||||
setIcon( QgsApplication::getThemeIcon( QStringLiteral( "propertyicons/elevationscale.svg" ) ) );
|
||||
setTitle( tr( "Elevation" ) );
|
||||
}
|
||||
|
||||
QgsMapLayerConfigWidget *QgsRasterElevationPropertiesWidgetFactory::createWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, bool, QWidget *parent ) const
|
||||
{
|
||||
return new QgsRasterElevationPropertiesWidget( qobject_cast< QgsRasterLayer * >( layer ), canvas, parent );
|
||||
}
|
||||
|
||||
bool QgsRasterElevationPropertiesWidgetFactory::supportLayerPropertiesDialog() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsRasterElevationPropertiesWidgetFactory::supportsStyleDock() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsRasterElevationPropertiesWidgetFactory::supportsLayer( QgsMapLayer *layer ) const
|
||||
{
|
||||
return layer->type() == QgsMapLayerType::RasterLayer;
|
||||
}
|
||||
|
||||
QString QgsRasterElevationPropertiesWidgetFactory::layerPropertiesPagePositionHint() const
|
||||
{
|
||||
return QStringLiteral( "mOptsPage_Metadata" );
|
||||
}
|
||||
|
65
src/app/raster/qgsrasterelevationpropertieswidget.h
Normal file
65
src/app/raster/qgsrasterelevationpropertieswidget.h
Normal file
@ -0,0 +1,65 @@
|
||||
/***************************************************************************
|
||||
qgsrasterelevationpropertieswidget.h
|
||||
---------------------
|
||||
begin : February 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSRASTERELEVATIONPROPERTIESWIDGET_H
|
||||
#define QGSRASTERELEVATIONPROPERTIESWIDGET_H
|
||||
|
||||
#include "qgsmaplayerconfigwidget.h"
|
||||
#include "qgsmaplayerconfigwidgetfactory.h"
|
||||
|
||||
#include "ui_qgsrasterelevationpropertieswidgetbase.h"
|
||||
|
||||
class QgsRasterLayer;
|
||||
|
||||
class QgsRasterElevationPropertiesWidget : public QgsMapLayerConfigWidget, private Ui::QgsRasterElevationPropertiesWidgetBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
QgsRasterElevationPropertiesWidget( QgsRasterLayer *layer, QgsMapCanvas *canvas, QWidget *parent );
|
||||
|
||||
void syncToLayer( QgsMapLayer *layer ) override;
|
||||
|
||||
public slots:
|
||||
void apply() override;
|
||||
|
||||
private slots:
|
||||
|
||||
void onChanged();
|
||||
|
||||
private:
|
||||
|
||||
QgsRasterLayer *mLayer = nullptr;
|
||||
bool mBlockUpdates = false;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class QgsRasterElevationPropertiesWidgetFactory : public QObject, public QgsMapLayerConfigWidgetFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QgsRasterElevationPropertiesWidgetFactory( QObject *parent = nullptr );
|
||||
|
||||
QgsMapLayerConfigWidget *createWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, bool dockWidget, QWidget *parent ) const override;
|
||||
bool supportLayerPropertiesDialog() const override;
|
||||
bool supportsStyleDock() const override;
|
||||
bool supportsLayer( QgsMapLayer *layer ) const override;
|
||||
QString layerPropertiesPagePositionHint() const override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // QGSRASTERELEVATIONPROPERTIESWIDGET_H
|
@ -657,6 +657,7 @@ set(QGIS_CORE_SRCS
|
||||
raster/qgsrasterinterface.cpp
|
||||
raster/qgsrasteriterator.cpp
|
||||
raster/qgsrasterlayer.cpp
|
||||
raster/qgsrasterlayerelevationproperties.cpp
|
||||
raster/qgsrasterlayerrenderer.cpp
|
||||
raster/qgsrasterlayertemporalproperties.cpp
|
||||
raster/qgsrasterminmaxorigin.cpp
|
||||
@ -1648,6 +1649,7 @@ set(QGIS_CORE_HDRS
|
||||
raster/qgsrasterinterface.h
|
||||
raster/qgsrasteriterator.h
|
||||
raster/qgsrasterlayer.h
|
||||
raster/qgsrasterlayerelevationproperties.h
|
||||
raster/qgsrasterlayerrenderer.h
|
||||
raster/qgsrasterlayertemporalproperties.h
|
||||
raster/qgsrasterminmaxorigin.h
|
||||
|
@ -41,6 +41,7 @@ class CORE_EXPORT QgsMapLayerElevationProperties : public QObject
|
||||
{
|
||||
#ifdef SIP_RUN
|
||||
#include "qgspointcloudlayerelevationproperties.h"
|
||||
#include "qgsrasterlayerelevationproperties.h"
|
||||
#endif
|
||||
|
||||
Q_OBJECT
|
||||
@ -51,6 +52,10 @@ class CORE_EXPORT QgsMapLayerElevationProperties : public QObject
|
||||
{
|
||||
sipType = sipType_QgsPointCloudLayerElevationProperties;
|
||||
}
|
||||
else if ( qobject_cast<QgsRasterLayerElevationProperties *>( sipCpp ) )
|
||||
{
|
||||
sipType = sipType_QgsRasterLayerElevationProperties;
|
||||
}
|
||||
else
|
||||
{
|
||||
sipType = 0;
|
||||
|
@ -59,6 +59,7 @@ email : tim at linfiniti.com
|
||||
#include "qgsruntimeprofiler.h"
|
||||
#include "qgsmaplayerfactory.h"
|
||||
#include "qgsrasterpipe.h"
|
||||
#include "qgsrasterlayerelevationproperties.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
@ -107,8 +108,8 @@ QgsRasterLayer::QgsRasterLayer()
|
||||
, QSTRING_NOT_SET( QStringLiteral( "Not Set" ) )
|
||||
, TRSTRING_NOT_SET( tr( "Not Set" ) )
|
||||
, mTemporalProperties( new QgsRasterLayerTemporalProperties( this ) )
|
||||
, mElevationProperties( new QgsRasterLayerElevationProperties( this ) )
|
||||
, mPipe( std::make_unique< QgsRasterPipe >() )
|
||||
|
||||
{
|
||||
init();
|
||||
setValid( false );
|
||||
@ -123,6 +124,7 @@ QgsRasterLayer::QgsRasterLayer( const QString &uri,
|
||||
, QSTRING_NOT_SET( QStringLiteral( "Not Set" ) )
|
||||
, TRSTRING_NOT_SET( tr( "Not Set" ) )
|
||||
, mTemporalProperties( new QgsRasterLayerTemporalProperties( this ) )
|
||||
, mElevationProperties( new QgsRasterLayerElevationProperties( this ) )
|
||||
, mPipe( std::make_unique< QgsRasterPipe >() )
|
||||
{
|
||||
mShouldValidateCrs = !options.skipCrsValidation;
|
||||
@ -1070,6 +1072,11 @@ QgsMapLayerTemporalProperties *QgsRasterLayer::temporalProperties()
|
||||
return mTemporalProperties;
|
||||
}
|
||||
|
||||
QgsMapLayerElevationProperties *QgsRasterLayer::elevationProperties()
|
||||
{
|
||||
return mElevationProperties;
|
||||
}
|
||||
|
||||
void QgsRasterLayer::setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm algorithm, QgsRasterMinMaxOrigin::Limits limits, const QgsRectangle &extent, int sampleSize, bool generateLookupTableFlag )
|
||||
{
|
||||
setContrastEnhancement( algorithm,
|
||||
|
@ -47,6 +47,7 @@ class QgsRasterPipe;
|
||||
class QgsRasterResampleFilter;
|
||||
class QgsBrightnessContrastFilter;
|
||||
class QgsHueSaturationFilter;
|
||||
class QgsRasterLayerElevationProperties;
|
||||
|
||||
class QImage;
|
||||
class QPixmap;
|
||||
@ -467,6 +468,7 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
|
||||
bool ignoreExtents() const;
|
||||
|
||||
QgsMapLayerTemporalProperties *temporalProperties() override;
|
||||
QgsMapLayerElevationProperties *elevationProperties() override;
|
||||
|
||||
public slots:
|
||||
void showStatusMessage( const QString &message );
|
||||
@ -552,6 +554,8 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
|
||||
//! Pointer to temporal properties
|
||||
QgsRasterLayerTemporalProperties *mTemporalProperties = nullptr;
|
||||
|
||||
QgsRasterLayerElevationProperties *mElevationProperties = nullptr;
|
||||
|
||||
//! [ data provider interface ] Timestamp, the last modified time of the data source when the layer was created
|
||||
QDateTime mLastModified;
|
||||
|
||||
|
60
src/core/raster/qgsrasterlayerelevationproperties.cpp
Normal file
60
src/core/raster/qgsrasterlayerelevationproperties.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
/***************************************************************************
|
||||
qgsrasterlayerelevationproperties.cpp
|
||||
---------------
|
||||
begin : February 2022
|
||||
copyright : (C) 2022 by Nyall Dawson
|
||||
email : nyall dot dawson 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 "qgsrasterlayerelevationproperties.h"
|
||||
#include "qgsrasterlayer.h"
|
||||
|
||||
QgsRasterLayerElevationProperties::QgsRasterLayerElevationProperties( QObject *parent )
|
||||
: QgsMapLayerElevationProperties( parent )
|
||||
{
|
||||
}
|
||||
|
||||
bool QgsRasterLayerElevationProperties::hasElevation() const
|
||||
{
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
QDomElement QgsRasterLayerElevationProperties::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext & )
|
||||
{
|
||||
QDomElement element = document.createElement( QStringLiteral( "elevation" ) );
|
||||
element.setAttribute( QStringLiteral( "enabled" ), mEnabled ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
|
||||
element.setAttribute( QStringLiteral( "zoffset" ), qgsDoubleToString( mZOffset ) );
|
||||
element.setAttribute( QStringLiteral( "zscale" ), qgsDoubleToString( mZScale ) );
|
||||
parentElement.appendChild( element );
|
||||
return element;
|
||||
}
|
||||
|
||||
bool QgsRasterLayerElevationProperties::readXml( const QDomElement &element, const QgsReadWriteContext & )
|
||||
{
|
||||
const QDomElement elevationElement = element.firstChildElement( QStringLiteral( "elevation" ) ).toElement();
|
||||
mEnabled = elevationElement.attribute( QStringLiteral( "enabled" ), QStringLiteral( "0" ) ).toInt();
|
||||
mZOffset = elevationElement.attribute( QStringLiteral( "zoffset" ), QStringLiteral( "0" ) ).toDouble();
|
||||
mZScale = elevationElement.attribute( QStringLiteral( "zscale" ), QStringLiteral( "1" ) ).toDouble();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsRasterLayerElevationProperties::isVisibleInZRange( const QgsDoubleRange & ) const
|
||||
{
|
||||
// TODO -- test actual raster z range
|
||||
return true;
|
||||
}
|
||||
|
||||
QgsDoubleRange QgsRasterLayerElevationProperties::calculateZRange( QgsMapLayer * ) const
|
||||
{
|
||||
// TODO -- determine actual z range from raster statistics
|
||||
return QgsDoubleRange();
|
||||
}
|
112
src/core/raster/qgsrasterlayerelevationproperties.h
Normal file
112
src/core/raster/qgsrasterlayerelevationproperties.h
Normal file
@ -0,0 +1,112 @@
|
||||
/***************************************************************************
|
||||
qgsrasterlayerelevationproperties.h
|
||||
---------------
|
||||
begin : February 2022
|
||||
copyright : (C) 2022 by Nyall Dawson
|
||||
email : nyall dot dawson 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef QGSRASTERLAYERELEVATIONPROPERTIES_H
|
||||
#define QGSRASTERLAYERELEVATIONPROPERTIES_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgis_sip.h"
|
||||
#include "qgsmaplayerelevationproperties.h"
|
||||
|
||||
/**
|
||||
* \class QgsRasterLayerElevationProperties
|
||||
* \ingroup core
|
||||
* \brief Raster layer specific subclass of QgsMapLayerElevationProperties.
|
||||
*
|
||||
* \since QGIS 3.26
|
||||
*/
|
||||
class CORE_EXPORT QgsRasterLayerElevationProperties : public QgsMapLayerElevationProperties
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsRasterLayerElevationProperties, with the specified \a parent object.
|
||||
*/
|
||||
QgsRasterLayerElevationProperties( QObject *parent SIP_TRANSFERTHIS );
|
||||
|
||||
bool hasElevation() const override;
|
||||
QDomElement writeXml( QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context ) override;
|
||||
bool readXml( const QDomElement &element, const QgsReadWriteContext &context ) override;
|
||||
bool isVisibleInZRange( const QgsDoubleRange &range ) const override;
|
||||
QgsDoubleRange calculateZRange( QgsMapLayer *layer ) const override;
|
||||
|
||||
/**
|
||||
* Returns TRUE if the elevation properties are enabled, i.e. the raster layer values represent an elevation surface.
|
||||
*
|
||||
* \see setEnabled()
|
||||
*/
|
||||
bool isEnabled() const { return mEnabled; }
|
||||
|
||||
/**
|
||||
* Sets whether the elevation properties are enabled, i.e. the raster layer values represent an elevation surface.
|
||||
*
|
||||
* \see isEnabled()
|
||||
*/
|
||||
void setEnabled( bool enabled ) { mEnabled = enabled; }
|
||||
|
||||
/**
|
||||
* Returns the z offset, which is a fixed offset amount which should be added to z values from
|
||||
* the layer.
|
||||
*
|
||||
* \note Any scaling specified via zScale() is applied before any offset value specified via zOffset()
|
||||
*
|
||||
* \see setZOffset()
|
||||
*/
|
||||
double zOffset() const { return mZOffset; }
|
||||
|
||||
/**
|
||||
* Sets the z \a offset, which is a fixed offset amount which will be added to z values from
|
||||
* the layer.
|
||||
*
|
||||
* \note Any scaling specified via zScale() is applied before any offset value specified via zOffset()
|
||||
*
|
||||
* \see zOffset()
|
||||
*/
|
||||
void setZOffset( double offset ) { mZOffset = offset; }
|
||||
|
||||
/**
|
||||
* Returns the z scale, which is a scaling factor which should be applied to z values from
|
||||
* the layer.
|
||||
*
|
||||
* \note Any scaling specified via zScale() is applied before any offset value specified via zOffset()
|
||||
*
|
||||
* \see setZScale()
|
||||
*/
|
||||
double zScale() const { return mZScale; }
|
||||
|
||||
/**
|
||||
* Sets the z \a scale, which is a scaling factor which will be applied to z values from
|
||||
* the layer.
|
||||
*
|
||||
* \note Any scaling specified via zScale() is applied before any offset value specified via zOffset()
|
||||
*
|
||||
* \see zScale()
|
||||
*/
|
||||
void setZScale( double scale ) { mZScale = scale; }
|
||||
|
||||
private:
|
||||
|
||||
bool mEnabled = false;
|
||||
double mZScale = 1.0;
|
||||
double mZOffset = 0.0;
|
||||
};
|
||||
|
||||
#endif // QGSRASTERLAYERELEVATIONPROPERTIES_H
|
136
src/ui/raster/qgsrasterelevationpropertieswidgetbase.ui
Normal file
136
src/ui/raster/qgsrasterelevationpropertieswidgetbase.ui
Normal file
@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsRasterElevationPropertiesWidgetBase</class>
|
||||
<widget class="QWidget" name="QgsRasterElevationPropertiesWidgetBase">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>242</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Raster Elevation Properties</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="mElevationGroupBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Represents Elevation Surface</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="syncGroup" stdset="0">
|
||||
<string notr="true">vectorgeneral</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="3" column="0">
|
||||
<widget class="Line" name="line_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Scale</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" font-weight:600;">Elevation scaling and offset can be used to manually correct elevation values from the layer.</span></p><p>The scale is applied to the raster values before adding the offset.</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QgsDoubleSpinBox" name="mScaleZSpinBox">
|
||||
<property name="decimals">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>99999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QgsDoubleSpinBox" name="mOffsetZSpinBox">
|
||||
<property name="decimals">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-99999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>99999999999.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsDoubleSpinBox</class>
|
||||
<extends>QDoubleSpinBox</extends>
|
||||
<header>qgsdoublespinbox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>mElevationGroupBox</tabstop>
|
||||
<tabstop>mScaleZSpinBox</tabstop>
|
||||
<tabstop>mOffsetZSpinBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -272,6 +272,7 @@ ADD_PYTHON_TEST(PyQgsRasterBandComboBox test_qgsrasterbandcombobox.py)
|
||||
ADD_PYTHON_TEST(PyQgsRasterFileWriter test_qgsrasterfilewriter.py)
|
||||
ADD_PYTHON_TEST(PyQgsRasterFileWriterTask test_qgsrasterfilewritertask.py)
|
||||
ADD_PYTHON_TEST(PyQgsRasterLayer test_qgsrasterlayer.py)
|
||||
ADD_PYTHON_TEST(PyQgsRasterLayerElevationProperties test_qgsrasterlayerelevationproperties.py)
|
||||
ADD_PYTHON_TEST(PyQgsRasterLayerProperties test_qgsrasterlayerproperties.py)
|
||||
ADD_PYTHON_TEST(PyQgsRasterLayerRenderer test_qgsrasterlayerrenderer.py)
|
||||
ADD_PYTHON_TEST(PyQgsRasterColorRampShader test_qgsrastercolorrampshader.py)
|
||||
|
56
tests/src/python/test_qgsrasterlayerelevationproperties.py
Normal file
56
tests/src/python/test_qgsrasterlayerelevationproperties.py
Normal file
@ -0,0 +1,56 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""QGIS Unit tests for QgsRasterLayerElevationProperties
|
||||
|
||||
.. note:: 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.
|
||||
"""
|
||||
__author__ = 'Nyall Dawson'
|
||||
__date__ = '09/11/2020'
|
||||
__copyright__ = 'Copyright 2020, The QGIS Project'
|
||||
|
||||
import qgis # NOQA
|
||||
|
||||
from qgis.core import (
|
||||
QgsRasterLayerElevationProperties,
|
||||
QgsReadWriteContext,
|
||||
)
|
||||
|
||||
from qgis.PyQt.QtXml import QDomDocument
|
||||
|
||||
from qgis.testing import start_app, unittest
|
||||
|
||||
start_app()
|
||||
|
||||
|
||||
class TestQgsRasterLayerElevationProperties(unittest.TestCase):
|
||||
|
||||
def testBasic(self):
|
||||
props = QgsRasterLayerElevationProperties(None)
|
||||
self.assertEqual(props.zScale(), 1)
|
||||
self.assertEqual(props.zOffset(), 0)
|
||||
self.assertFalse(props.isEnabled())
|
||||
self.assertFalse(props.hasElevation())
|
||||
|
||||
props.setZOffset(0.5)
|
||||
props.setZScale(2)
|
||||
props.setEnabled(True)
|
||||
self.assertEqual(props.zScale(), 2)
|
||||
self.assertEqual(props.zOffset(), 0.5)
|
||||
self.assertTrue(props.isEnabled())
|
||||
self.assertTrue(props.hasElevation())
|
||||
|
||||
doc = QDomDocument("testdoc")
|
||||
elem = doc.createElement('test')
|
||||
props.writeXml(elem, doc, QgsReadWriteContext())
|
||||
|
||||
props2 = QgsRasterLayerElevationProperties(None)
|
||||
props2.readXml(elem, QgsReadWriteContext())
|
||||
self.assertEqual(props2.zScale(), 2)
|
||||
self.assertEqual(props2.zOffset(), 0.5)
|
||||
self.assertTrue(props.isEnabled())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user