mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	Add QgsMapLayerElevationProperties subclass for vector layers
Allows elevation properties to be set for vector layers, including: - altitude binding - altitude clamping - extrusion - scale - offset These properties can be set through the new "Elevation" tab in the vector layer properties dialog
This commit is contained in:
		
							parent
							
								
									5395d87d7f
								
							
						
					
					
						commit
						cc24106d01
					
				@ -39,64 +39,6 @@ Constructor for QgsPointCloudLayerElevationProperties, with the specified ``pare
 | 
			
		||||
    virtual QgsDoubleRange calculateZRange( QgsMapLayer *layer ) const;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    double zOffset() const;
 | 
			
		||||
%Docstring
 | 
			
		||||
Returns the z offset, which is a fixed offset amount which should be added to z values from
 | 
			
		||||
the layer.
 | 
			
		||||
 | 
			
		||||
This can be used to correct or manually adjust for incorrect elevation values in a point cloud layer.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   Any scaling specified via :py:func:`~QgsPointCloudLayerElevationProperties.zScale` is applied before any offset value specified via :py:func:`~QgsPointCloudLayerElevationProperties.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.
 | 
			
		||||
 | 
			
		||||
This can be used to correct or manually adjust for incorrect elevation values in a point cloud layer.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   Any scaling specified via :py:func:`~QgsPointCloudLayerElevationProperties.zScale` is applied before any offset value specified via :py:func:`~QgsPointCloudLayerElevationProperties.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.
 | 
			
		||||
 | 
			
		||||
This can be used to correct or manually adjust for incorrect elevation values in a point cloud layer, such
 | 
			
		||||
as conversion of elevation values in feet to meters.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   Any scaling specified via :py:func:`~QgsPointCloudLayerElevationProperties.zScale` is applied before any offset value specified via :py:func:`~QgsPointCloudLayerElevationProperties.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.
 | 
			
		||||
 | 
			
		||||
This can be used to correct or manually adjust for incorrect elevation values in a point cloud layer, such
 | 
			
		||||
as conversion of elevation values in feet to meters.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   Any scaling specified via :py:func:`~QgsPointCloudLayerElevationProperties.zScale` is applied before any offset value specified via :py:func:`~QgsPointCloudLayerElevationProperties.zOffset`
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`zScale`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 | 
			
		||||
@ -26,12 +26,17 @@ how an individual :py:class:`QgsMapLayer` behaves with relation to z values or e
 | 
			
		||||
#include "qgsmaplayerelevationproperties.h"
 | 
			
		||||
#include "qgspointcloudlayerelevationproperties.h"
 | 
			
		||||
#include "qgsrasterlayerelevationproperties.h"
 | 
			
		||||
#include "qgsvectorlayerelevationproperties.h"
 | 
			
		||||
%End
 | 
			
		||||
%ConvertToSubClassCode
 | 
			
		||||
    if ( qobject_cast<QgsPointCloudLayerElevationProperties *>( sipCpp ) )
 | 
			
		||||
    {
 | 
			
		||||
      sipType = sipType_QgsPointCloudLayerElevationProperties;
 | 
			
		||||
    }
 | 
			
		||||
    else if ( qobject_cast<QgsVectorLayerElevationProperties *>( sipCpp ) )
 | 
			
		||||
    {
 | 
			
		||||
      sipType = sipType_QgsVectorLayerElevationProperties;
 | 
			
		||||
    }
 | 
			
		||||
    else if ( qobject_cast<QgsRasterLayerElevationProperties *>( sipCpp ) )
 | 
			
		||||
    {
 | 
			
		||||
      sipType = sipType_QgsRasterLayerElevationProperties;
 | 
			
		||||
@ -90,6 +95,60 @@ Attempts to calculate the overall elevation or z range for the specified ``layer
 | 
			
		||||
the settings defined by this elevation properties object.
 | 
			
		||||
 | 
			
		||||
May return an infinite range if the extent could not be calculated.
 | 
			
		||||
%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:`~QgsMapLayerElevationProperties.zScale` is applied before any offset value specified via :py:func:`~QgsMapLayerElevationProperties.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:`~QgsMapLayerElevationProperties.zScale` is applied before any offset value specified via :py:func:`~QgsMapLayerElevationProperties.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.
 | 
			
		||||
 | 
			
		||||
This can be used to correct or manually adjust for incorrect elevation values in a layer, such
 | 
			
		||||
as conversion of elevation values in feet to meters.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   Any scaling specified via :py:func:`~QgsMapLayerElevationProperties.zScale` is applied before any offset value specified via :py:func:`~QgsMapLayerElevationProperties.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.
 | 
			
		||||
 | 
			
		||||
This can be used to correct or manually adjust for incorrect elevation values in a layer, such
 | 
			
		||||
as conversion of elevation values in feet to meters.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   Any scaling specified via :py:func:`~QgsMapLayerElevationProperties.zScale` is applied before any offset value specified via :py:func:`~QgsMapLayerElevationProperties.zOffset`
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`zScale`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
  signals:
 | 
			
		||||
@ -98,6 +157,8 @@ May return an infinite range if the extent could not be calculated.
 | 
			
		||||
%Docstring
 | 
			
		||||
Emitted when the elevation properties have changed.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
  protected:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 | 
			
		||||
@ -51,54 +51,6 @@ Returns ``True`` if the elevation properties are enabled, i.e. the raster layer
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -509,12 +509,10 @@ Uses :py:class:`QgsExpression`
 | 
			
		||||
 | 
			
		||||
    virtual QgsVectorDataProvider *dataProvider() ${SIP_FINAL};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    virtual QgsMapLayerTemporalProperties *temporalProperties();
 | 
			
		||||
 | 
			
		||||
%Docstring
 | 
			
		||||
Returns temporal properties associated with the vector layer.
 | 
			
		||||
%End
 | 
			
		||||
    virtual QgsMapLayerElevationProperties *elevationProperties();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    void setProviderEncoding( const QString &encoding );
 | 
			
		||||
%Docstring
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,102 @@
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 * This file has been generated automatically from                      *
 | 
			
		||||
 *                                                                      *
 | 
			
		||||
 * src/core/vector/qgsvectorlayerelevationproperties.h                  *
 | 
			
		||||
 *                                                                      *
 | 
			
		||||
 * Do not edit manually ! Edit header and run scripts/sipify.pl again   *
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class QgsVectorLayerElevationProperties : QgsMapLayerElevationProperties
 | 
			
		||||
{
 | 
			
		||||
%Docstring(signature="appended")
 | 
			
		||||
Vector layer specific subclass of :py:class:`QgsMapLayerElevationProperties`.
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 3.26
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
%TypeHeaderCode
 | 
			
		||||
#include "qgsvectorlayerelevationproperties.h"
 | 
			
		||||
%End
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    QgsVectorLayerElevationProperties( QObject *parent /TransferThis/ );
 | 
			
		||||
%Docstring
 | 
			
		||||
Constructor for QgsVectorLayerElevationProperties, 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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Qgis::AltitudeClamping clamping() const;
 | 
			
		||||
%Docstring
 | 
			
		||||
Returns the altitude clamping method, which dictates how feature heights are interpreted
 | 
			
		||||
with respect to terrain heights.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`setClamping`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    void setClamping( Qgis::AltitudeClamping clamping );
 | 
			
		||||
%Docstring
 | 
			
		||||
Sets the altitude ``clamping`` method, which dictates how feature heights are interpreted
 | 
			
		||||
with respect to terrain heights.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`clamping`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    Qgis::AltitudeBinding binding() const;
 | 
			
		||||
%Docstring
 | 
			
		||||
Returns the altitude binding method, which determines how altitude is bound to individual vertices in features.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`setBinding`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    void setBinding( Qgis::AltitudeBinding binding );
 | 
			
		||||
%Docstring
 | 
			
		||||
Sets the altitude ``binding`` method, which determines how altitude is bound to individual vertices in features.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`binding`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    double extrusionHeight() const;
 | 
			
		||||
%Docstring
 | 
			
		||||
Returns the feature extrusion height.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   the :py:func:`~QgsVectorLayerElevationProperties.zScale` factor is NOT applied to extrusion heights.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`setExtrusionHeight`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    void setExtrusionHeight( double height );
 | 
			
		||||
%Docstring
 | 
			
		||||
Sets the feature extrusion height.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   the :py:func:`~QgsVectorLayerElevationProperties.zScale` factor is NOT applied to extrusion heights.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`extrusionHeight`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/************************************************************************
 | 
			
		||||
 * This file has been generated automatically from                      *
 | 
			
		||||
 *                                                                      *
 | 
			
		||||
 * src/core/vector/qgsvectorlayerelevationproperties.h                  *
 | 
			
		||||
 *                                                                      *
 | 
			
		||||
 * Do not edit manually ! Edit header and run scripts/sipify.pl again   *
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
@ -674,6 +674,7 @@
 | 
			
		||||
%Include auto_generated/vector/qgsvectorlayereditbuffer.sip
 | 
			
		||||
%Include auto_generated/vector/qgsvectorlayereditpassthrough.sip
 | 
			
		||||
%Include auto_generated/vector/qgsvectorlayereditutils.sip
 | 
			
		||||
%Include auto_generated/vector/qgsvectorlayerelevationproperties.sip
 | 
			
		||||
%Include auto_generated/vector/qgsvectorlayerexporter.sip
 | 
			
		||||
%Include auto_generated/vector/qgsvectorlayerfeaturecounter.sip
 | 
			
		||||
%Include auto_generated/vector/qgsvectorlayerfeatureiterator.sip
 | 
			
		||||
 | 
			
		||||
@ -259,6 +259,8 @@ set(QGIS_APP_SRCS
 | 
			
		||||
  mesh/qgsmaptooleditmeshframe.cpp
 | 
			
		||||
  mesh/qgsmeshtransformcoordinatesdockwidget.cpp
 | 
			
		||||
  mesh/qgsmeshselectbyexpressiondialog.cpp
 | 
			
		||||
 | 
			
		||||
  vector/qgsvectorelevationpropertieswidget.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if (WITH_SPATIALITE)
 | 
			
		||||
 | 
			
		||||
@ -118,6 +118,7 @@
 | 
			
		||||
#include "options/qgscustomprojectionoptions.h"
 | 
			
		||||
 | 
			
		||||
#include "raster/qgsrasterelevationpropertieswidget.h"
 | 
			
		||||
#include "vector/qgsvectorelevationpropertieswidget.h"
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_3D
 | 
			
		||||
#include "qgs3d.h"
 | 
			
		||||
@ -1481,6 +1482,7 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipBadLayers
 | 
			
		||||
#endif
 | 
			
		||||
  registerMapLayerPropertiesFactory( new QgsPointCloudElevationPropertiesWidgetFactory( this ) );
 | 
			
		||||
  registerMapLayerPropertiesFactory( new QgsRasterElevationPropertiesWidgetFactory( this ) );
 | 
			
		||||
  registerMapLayerPropertiesFactory( new QgsVectorElevationPropertiesWidgetFactory( this ) );
 | 
			
		||||
  registerMapLayerPropertiesFactory( new QgsAnnotationItemPropertiesWidgetFactory( this ) );
 | 
			
		||||
  registerMapLayerPropertiesFactory( new QgsLayerTreeGroupPropertiesWidgetFactory( this ) );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -92,7 +92,7 @@ bool QgsRasterElevationPropertiesWidgetFactory::supportLayerPropertiesDialog() c
 | 
			
		||||
 | 
			
		||||
bool QgsRasterElevationPropertiesWidgetFactory::supportsStyleDock() const
 | 
			
		||||
{
 | 
			
		||||
  return true;
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsRasterElevationPropertiesWidgetFactory::supportsLayer( QgsMapLayer *layer ) const
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										186
									
								
								src/app/vector/qgsvectorelevationpropertieswidget.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								src/app/vector/qgsvectorelevationpropertieswidget.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,186 @@
 | 
			
		||||
/***************************************************************************
 | 
			
		||||
    qgsvectorrelevationpropertieswidget.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 "qgsvectorelevationpropertieswidget.h"
 | 
			
		||||
#include "qgsstyle.h"
 | 
			
		||||
#include "qgsapplication.h"
 | 
			
		||||
#include "qgsmaplayer.h"
 | 
			
		||||
#include "qgsvectorlayer.h"
 | 
			
		||||
#include "qgsvectorlayerelevationproperties.h"
 | 
			
		||||
 | 
			
		||||
QgsVectorElevationPropertiesWidget::QgsVectorElevationPropertiesWidget( QgsVectorLayer *layer, QgsMapCanvas *canvas, QWidget *parent )
 | 
			
		||||
  : QgsMapLayerConfigWidget( layer, canvas, parent )
 | 
			
		||||
{
 | 
			
		||||
  setupUi( this );
 | 
			
		||||
 | 
			
		||||
  mOffsetZSpinBox->setClearValue( 0 );
 | 
			
		||||
  mScaleZSpinBox->setClearValue( 1 );
 | 
			
		||||
  mExtrusionSpinBox->setClearValue( 0 );
 | 
			
		||||
 | 
			
		||||
  mComboClamping->addItem( tr( "Clamped to Terrain" ), static_cast< int >( Qgis::AltitudeClamping::Terrain ) );
 | 
			
		||||
  mComboClamping->addItem( tr( "Relative to Terrain" ), static_cast< int >( Qgis::AltitudeClamping::Relative ) );
 | 
			
		||||
  mComboClamping->addItem( tr( "Absolute" ), static_cast< int >( Qgis::AltitudeClamping::Absolute ) );
 | 
			
		||||
 | 
			
		||||
  mComboBinding->addItem( tr( "Vertex" ), static_cast< int >( Qgis::AltitudeBinding::Vertex ) );
 | 
			
		||||
  mComboBinding->addItem( tr( "Centroid" ), static_cast< int >( Qgis::AltitudeBinding::Centroid ) );
 | 
			
		||||
 | 
			
		||||
  syncToLayer( layer );
 | 
			
		||||
 | 
			
		||||
  connect( mOffsetZSpinBox, qOverload<double >( &QDoubleSpinBox::valueChanged ), this, &QgsVectorElevationPropertiesWidget::onChanged );
 | 
			
		||||
  connect( mScaleZSpinBox, qOverload<double >( &QDoubleSpinBox::valueChanged ), this, &QgsVectorElevationPropertiesWidget::onChanged );
 | 
			
		||||
  connect( mExtrusionSpinBox, qOverload<double >( &QDoubleSpinBox::valueChanged ), this, &QgsVectorElevationPropertiesWidget::onChanged );
 | 
			
		||||
  connect( mComboClamping, qOverload<int>( &QComboBox::currentIndexChanged ), this, &QgsVectorElevationPropertiesWidget::onChanged );
 | 
			
		||||
  connect( mComboBinding, qOverload<int>( &QComboBox::currentIndexChanged ), this, &QgsVectorElevationPropertiesWidget::onChanged );
 | 
			
		||||
  connect( mComboClamping, qOverload<int>( &QComboBox::currentIndexChanged ), this, &QgsVectorElevationPropertiesWidget::clampingChanged );
 | 
			
		||||
  connect( mComboBinding, qOverload<int>( &QComboBox::currentIndexChanged ), this, &QgsVectorElevationPropertiesWidget::bindingChanged );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsVectorElevationPropertiesWidget::syncToLayer( QgsMapLayer *layer )
 | 
			
		||||
{
 | 
			
		||||
  mLayer = qobject_cast< QgsVectorLayer * >( layer );
 | 
			
		||||
  if ( !mLayer )
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  mBlockUpdates = true;
 | 
			
		||||
  const QgsVectorLayerElevationProperties *props = qgis::down_cast< const QgsVectorLayerElevationProperties * >( mLayer->elevationProperties() );
 | 
			
		||||
 | 
			
		||||
  mComboClamping->setCurrentIndex( mComboClamping->findData( static_cast< int >( props->clamping() ) ) );
 | 
			
		||||
  mComboBinding->setCurrentIndex( mComboBinding->findData( static_cast< int >( props->binding() ) ) );
 | 
			
		||||
  mOffsetZSpinBox->setValue( props->zOffset() );
 | 
			
		||||
  mScaleZSpinBox->setValue( props->zScale() );
 | 
			
		||||
  mExtrusionSpinBox->setValue( props->extrusionHeight() );
 | 
			
		||||
  mBlockUpdates = false;
 | 
			
		||||
 | 
			
		||||
  clampingChanged();
 | 
			
		||||
  bindingChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsVectorElevationPropertiesWidget::apply()
 | 
			
		||||
{
 | 
			
		||||
  if ( !mLayer )
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  QgsVectorLayerElevationProperties *props = qgis::down_cast< QgsVectorLayerElevationProperties * >( mLayer->elevationProperties() );
 | 
			
		||||
 | 
			
		||||
  props->setZOffset( mOffsetZSpinBox->value() );
 | 
			
		||||
  props->setZScale( mScaleZSpinBox->value() );
 | 
			
		||||
  props->setClamping( static_cast< Qgis::AltitudeClamping >( mComboClamping->currentData().toInt() ) );
 | 
			
		||||
  props->setBinding( static_cast< Qgis::AltitudeBinding >( mComboBinding->currentData().toInt() ) );
 | 
			
		||||
  props->setExtrusionHeight( mExtrusionSpinBox->value() );
 | 
			
		||||
  mLayer->trigger3DUpdate();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsVectorElevationPropertiesWidget::onChanged()
 | 
			
		||||
{
 | 
			
		||||
  if ( !mBlockUpdates )
 | 
			
		||||
    emit widgetChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsVectorElevationPropertiesWidget::clampingChanged()
 | 
			
		||||
{
 | 
			
		||||
  bool enableScale = true;
 | 
			
		||||
  bool enableBinding = true;
 | 
			
		||||
  switch ( static_cast< Qgis::AltitudeClamping >( mComboClamping->currentData().toInt() ) )
 | 
			
		||||
  {
 | 
			
		||||
    case Qgis::AltitudeClamping::Absolute:
 | 
			
		||||
      mLabelClampingExplanation->setText(
 | 
			
		||||
        QStringLiteral( "<p><b>%1</b></p><p>%2</p>" ).arg(
 | 
			
		||||
          tr( "Elevation will be taken directly from features." ),
 | 
			
		||||
          tr( "Z values from the features will be used for elevation, and the terrain height will be ignored." ) )
 | 
			
		||||
      );
 | 
			
		||||
      enableBinding = false; // not used in absolute mode
 | 
			
		||||
      break;
 | 
			
		||||
    case Qgis::AltitudeClamping::Relative:
 | 
			
		||||
      mLabelClampingExplanation->setText(
 | 
			
		||||
        QStringLiteral( "<p><b>%1</b></p><p>%2</p>" ).arg(
 | 
			
		||||
          tr( "Elevation is relative to terrain height." ),
 | 
			
		||||
          tr( "Any z values present in the features will be added to the terrain height." ) )
 | 
			
		||||
      );
 | 
			
		||||
      break;
 | 
			
		||||
    case Qgis::AltitudeClamping::Terrain:
 | 
			
		||||
      mLabelClampingExplanation->setText(
 | 
			
		||||
        QStringLiteral( "<p><b>%1</b></p><p>%2</p>" ).arg(
 | 
			
		||||
          tr( "Feature elevation will be taken directly from the terrain height." ),
 | 
			
		||||
          tr( "Any existing z values present in the features will be ignored." ) )
 | 
			
		||||
      );
 | 
			
		||||
      enableScale = false; // not used in terrain mode
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
  mLabelScale->setVisible( enableScale );
 | 
			
		||||
  mScaleZSpinBox->setVisible( enableScale );
 | 
			
		||||
  mBindingGroupBox->setVisible( enableBinding );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsVectorElevationPropertiesWidget::bindingChanged()
 | 
			
		||||
{
 | 
			
		||||
  switch ( static_cast< Qgis::AltitudeBinding >( mComboBinding->currentData().toInt() ) )
 | 
			
		||||
  {
 | 
			
		||||
    case Qgis::AltitudeBinding::Vertex:
 | 
			
		||||
      mLabelBindingExplanation->setText(
 | 
			
		||||
        QStringLiteral( "<p><b>%1</b></p><p>%2</p>" ).arg(
 | 
			
		||||
          tr( "Feature elevation is relative to the terrain height at every vertex." ),
 | 
			
		||||
          tr( "The terrain will be sampled at every individual vertex before being added to the vertex's z value." )
 | 
			
		||||
        )
 | 
			
		||||
      );
 | 
			
		||||
      break;
 | 
			
		||||
    case Qgis::AltitudeBinding::Centroid:
 | 
			
		||||
      mLabelBindingExplanation->setText(
 | 
			
		||||
        QStringLiteral( "<p><b>%1</b></p><p>%2</p>" ).arg(
 | 
			
		||||
          tr( "Feature elevation is relative to the terrain height at feature's centroid only." ),
 | 
			
		||||
          tr( "The terrain will be sampled once at the feature's centroid, with the centroid height being added to each vertex's z value." )
 | 
			
		||||
        )
 | 
			
		||||
      );
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// QgsVectorElevationPropertiesWidgetFactory
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
QgsVectorElevationPropertiesWidgetFactory::QgsVectorElevationPropertiesWidgetFactory( QObject *parent )
 | 
			
		||||
  : QObject( parent )
 | 
			
		||||
{
 | 
			
		||||
  setIcon( QgsApplication::getThemeIcon( QStringLiteral( "propertyicons/elevationscale.svg" ) ) );
 | 
			
		||||
  setTitle( tr( "Elevation" ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QgsMapLayerConfigWidget *QgsVectorElevationPropertiesWidgetFactory::createWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, bool, QWidget *parent ) const
 | 
			
		||||
{
 | 
			
		||||
  return new QgsVectorElevationPropertiesWidget( qobject_cast< QgsVectorLayer * >( layer ), canvas, parent );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsVectorElevationPropertiesWidgetFactory::supportLayerPropertiesDialog() const
 | 
			
		||||
{
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsVectorElevationPropertiesWidgetFactory::supportsStyleDock() const
 | 
			
		||||
{
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsVectorElevationPropertiesWidgetFactory::supportsLayer( QgsMapLayer *layer ) const
 | 
			
		||||
{
 | 
			
		||||
  return layer->type() == QgsMapLayerType::VectorLayer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString QgsVectorElevationPropertiesWidgetFactory::layerPropertiesPagePositionHint() const
 | 
			
		||||
{
 | 
			
		||||
  return QStringLiteral( "mOptsPage_Metadata" );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										67
									
								
								src/app/vector/qgsvectorelevationpropertieswidget.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/app/vector/qgsvectorelevationpropertieswidget.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,67 @@
 | 
			
		||||
/***************************************************************************
 | 
			
		||||
    qgsvectorrelevationpropertieswidget.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 QGSVECTORELEVATIONPROPERTIESWIDGET_H
 | 
			
		||||
#define QGSVECTORELEVATIONPROPERTIESWIDGET_H
 | 
			
		||||
 | 
			
		||||
#include "qgsmaplayerconfigwidget.h"
 | 
			
		||||
#include "qgsmaplayerconfigwidgetfactory.h"
 | 
			
		||||
 | 
			
		||||
#include "ui_qgsvectorelevationpropertieswidgetbase.h"
 | 
			
		||||
 | 
			
		||||
class QgsVectorLayer;
 | 
			
		||||
 | 
			
		||||
class QgsVectorElevationPropertiesWidget : public QgsMapLayerConfigWidget, private Ui::QgsVectorElevationPropertiesWidgetBase
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    QgsVectorElevationPropertiesWidget( QgsVectorLayer *layer, QgsMapCanvas *canvas, QWidget *parent );
 | 
			
		||||
 | 
			
		||||
    void syncToLayer( QgsMapLayer *layer ) override;
 | 
			
		||||
 | 
			
		||||
  public slots:
 | 
			
		||||
    void apply() override;
 | 
			
		||||
 | 
			
		||||
  private slots:
 | 
			
		||||
 | 
			
		||||
    void onChanged();
 | 
			
		||||
    void clampingChanged();
 | 
			
		||||
    void bindingChanged();
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
 | 
			
		||||
    QgsVectorLayer *mLayer = nullptr;
 | 
			
		||||
    bool mBlockUpdates = false;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class QgsVectorElevationPropertiesWidgetFactory : public QObject, public QgsMapLayerConfigWidgetFactory
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
  public:
 | 
			
		||||
    explicit QgsVectorElevationPropertiesWidgetFactory( 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 // QGSVECTORELEVATIONPROPERTIESWIDGET_H
 | 
			
		||||
@ -819,6 +819,7 @@ set(QGIS_CORE_SRCS
 | 
			
		||||
  vector/qgsvectorlayereditbuffer.cpp
 | 
			
		||||
  vector/qgsvectorlayereditpassthrough.cpp
 | 
			
		||||
  vector/qgsvectorlayereditutils.cpp
 | 
			
		||||
  vector/qgsvectorlayerelevationproperties.cpp
 | 
			
		||||
  vector/qgsvectorlayerfeatureiterator.cpp
 | 
			
		||||
  vector/qgsvectorlayerexporter.cpp
 | 
			
		||||
  vector/qgsvectorlayerjoinbuffer.cpp
 | 
			
		||||
@ -1758,6 +1759,7 @@ set(QGIS_CORE_HDRS
 | 
			
		||||
  vector/qgsvectorlayereditbuffer.h
 | 
			
		||||
  vector/qgsvectorlayereditpassthrough.h
 | 
			
		||||
  vector/qgsvectorlayereditutils.h
 | 
			
		||||
  vector/qgsvectorlayerelevationproperties.h
 | 
			
		||||
  vector/qgsvectorlayerexporter.h
 | 
			
		||||
  vector/qgsvectorlayerfeaturecounter.h
 | 
			
		||||
  vector/qgsvectorlayerfeatureiterator.h
 | 
			
		||||
 | 
			
		||||
@ -48,60 +48,6 @@ class CORE_EXPORT QgsPointCloudLayerElevationProperties : public QgsMapLayerElev
 | 
			
		||||
    bool isVisibleInZRange( const QgsDoubleRange &range ) const override;
 | 
			
		||||
    QgsDoubleRange calculateZRange( QgsMapLayer *layer ) const override;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the z offset, which is a fixed offset amount which should be added to z values from
 | 
			
		||||
     * the layer.
 | 
			
		||||
     *
 | 
			
		||||
     * This can be used to correct or manually adjust for incorrect elevation values in a point cloud 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.
 | 
			
		||||
     *
 | 
			
		||||
     * This can be used to correct or manually adjust for incorrect elevation values in a point cloud 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.
 | 
			
		||||
     *
 | 
			
		||||
     * This can be used to correct or manually adjust for incorrect elevation values in a point cloud layer, such
 | 
			
		||||
     * as conversion of elevation values in feet to meters.
 | 
			
		||||
     *
 | 
			
		||||
     * \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.
 | 
			
		||||
     *
 | 
			
		||||
     * This can be used to correct or manually adjust for incorrect elevation values in a point cloud layer, such
 | 
			
		||||
     * as conversion of elevation values in feet to meters.
 | 
			
		||||
     *
 | 
			
		||||
     * \note Any scaling specified via zScale() is applied before any offset value specified via zOffset()
 | 
			
		||||
     *
 | 
			
		||||
     * \see zScale()
 | 
			
		||||
     */
 | 
			
		||||
    void setZScale( double scale ) { mZScale = scale; }
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
 | 
			
		||||
    double mZScale = 1.0;
 | 
			
		||||
    double mZOffset = 0.0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // QGSPOINTCLOUDLAYERELEVATIONPROPERTIES_H
 | 
			
		||||
 | 
			
		||||
@ -42,6 +42,7 @@ class CORE_EXPORT QgsMapLayerElevationProperties : public QObject
 | 
			
		||||
#ifdef SIP_RUN
 | 
			
		||||
#include "qgspointcloudlayerelevationproperties.h"
 | 
			
		||||
#include "qgsrasterlayerelevationproperties.h"
 | 
			
		||||
#include "qgsvectorlayerelevationproperties.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
@ -52,6 +53,10 @@ class CORE_EXPORT QgsMapLayerElevationProperties : public QObject
 | 
			
		||||
    {
 | 
			
		||||
      sipType = sipType_QgsPointCloudLayerElevationProperties;
 | 
			
		||||
    }
 | 
			
		||||
    else if ( qobject_cast<QgsVectorLayerElevationProperties *>( sipCpp ) )
 | 
			
		||||
    {
 | 
			
		||||
      sipType = sipType_QgsVectorLayerElevationProperties;
 | 
			
		||||
    }
 | 
			
		||||
    else if ( qobject_cast<QgsRasterLayerElevationProperties *>( sipCpp ) )
 | 
			
		||||
    {
 | 
			
		||||
      sipType = sipType_QgsRasterLayerElevationProperties;
 | 
			
		||||
@ -116,12 +121,64 @@ class CORE_EXPORT QgsMapLayerElevationProperties : public QObject
 | 
			
		||||
     */
 | 
			
		||||
    virtual QgsDoubleRange calculateZRange( QgsMapLayer *layer ) const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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.
 | 
			
		||||
     *
 | 
			
		||||
     * This can be used to correct or manually adjust for incorrect elevation values in a layer, such
 | 
			
		||||
     * as conversion of elevation values in feet to meters.
 | 
			
		||||
     *
 | 
			
		||||
     * \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.
 | 
			
		||||
     *
 | 
			
		||||
     * This can be used to correct or manually adjust for incorrect elevation values in a layer, such
 | 
			
		||||
     * as conversion of elevation values in feet to meters.
 | 
			
		||||
     *
 | 
			
		||||
     * \note Any scaling specified via zScale() is applied before any offset value specified via zOffset()
 | 
			
		||||
     *
 | 
			
		||||
     * \see zScale()
 | 
			
		||||
     */
 | 
			
		||||
    void setZScale( double scale ) { mZScale = scale; }
 | 
			
		||||
 | 
			
		||||
  signals:
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Emitted when the elevation properties have changed.
 | 
			
		||||
     */
 | 
			
		||||
    void changed();
 | 
			
		||||
 | 
			
		||||
  protected:
 | 
			
		||||
    //! Z scale
 | 
			
		||||
    double mZScale = 1.0;
 | 
			
		||||
    //! Z offset
 | 
			
		||||
    double mZOffset = 0.0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // QGSMAPLAYERELEVATIONPROPERTIES_H
 | 
			
		||||
 | 
			
		||||
@ -62,51 +62,10 @@ class CORE_EXPORT QgsRasterLayerElevationProperties : public QgsMapLayerElevatio
 | 
			
		||||
     */
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
@ -57,6 +57,7 @@
 | 
			
		||||
#include "qgsrendercontext.h"
 | 
			
		||||
#include "qgsvectordataprovider.h"
 | 
			
		||||
#include "qgsvectorlayertemporalproperties.h"
 | 
			
		||||
#include "qgsvectorlayerelevationproperties.h"
 | 
			
		||||
#include "qgsvectorlayereditbuffer.h"
 | 
			
		||||
#include "qgsvectorlayereditpassthrough.h"
 | 
			
		||||
#include "qgsvectorlayereditutils.h"
 | 
			
		||||
@ -157,6 +158,7 @@ QgsVectorLayer::QgsVectorLayer( const QString &vectorLayerPath,
 | 
			
		||||
                                const QgsVectorLayer::LayerOptions &options )
 | 
			
		||||
  : QgsMapLayer( QgsMapLayerType::VectorLayer, baseName, vectorLayerPath )
 | 
			
		||||
  , mTemporalProperties( new QgsVectorLayerTemporalProperties( this ) )
 | 
			
		||||
  , mElevationProperties( new QgsVectorLayerElevationProperties( this ) )
 | 
			
		||||
  , mAuxiliaryLayer( nullptr )
 | 
			
		||||
  , mAuxiliaryLayerKey( QString() )
 | 
			
		||||
  , mReadExtentFromXml( options.readExtentFromXml )
 | 
			
		||||
@ -670,6 +672,11 @@ QgsMapLayerTemporalProperties *QgsVectorLayer::temporalProperties()
 | 
			
		||||
  return mTemporalProperties;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QgsMapLayerElevationProperties *QgsVectorLayer::elevationProperties()
 | 
			
		||||
{
 | 
			
		||||
  return mElevationProperties;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsVectorLayer::setProviderEncoding( const QString &encoding )
 | 
			
		||||
{
 | 
			
		||||
  if ( isValid() && mDataProvider && mDataProvider->encoding() != encoding )
 | 
			
		||||
 | 
			
		||||
@ -80,6 +80,7 @@ class QgsGeometryOptions;
 | 
			
		||||
class QgsStyleEntityVisitorInterface;
 | 
			
		||||
class QgsVectorLayerTemporalProperties;
 | 
			
		||||
class QgsFeatureRendererGenerator;
 | 
			
		||||
class QgsVectorLayerElevationProperties;
 | 
			
		||||
 | 
			
		||||
typedef QList<int> QgsAttributeList;
 | 
			
		||||
typedef QSet<int> QgsAttributeIds;
 | 
			
		||||
@ -624,11 +625,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
 | 
			
		||||
 | 
			
		||||
    QgsVectorDataProvider *dataProvider() FINAL;
 | 
			
		||||
    const QgsVectorDataProvider *dataProvider() const FINAL SIP_SKIP;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns temporal properties associated with the vector layer.
 | 
			
		||||
     */
 | 
			
		||||
    QgsMapLayerTemporalProperties *temporalProperties() override;
 | 
			
		||||
    QgsMapLayerElevationProperties *elevationProperties() override;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the text \a encoding of the data provider.
 | 
			
		||||
@ -2867,6 +2865,8 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
 | 
			
		||||
    //! Pointer to temporal properties
 | 
			
		||||
    QgsVectorLayerTemporalProperties *mTemporalProperties = nullptr;
 | 
			
		||||
 | 
			
		||||
    QgsVectorLayerElevationProperties *mElevationProperties = nullptr;
 | 
			
		||||
 | 
			
		||||
    //! The preview expression used to generate a human readable preview string for features
 | 
			
		||||
    QString mDisplayExpression;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										68
									
								
								src/core/vector/qgsvectorlayerelevationproperties.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/core/vector/qgsvectorlayerelevationproperties.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,68 @@
 | 
			
		||||
/***************************************************************************
 | 
			
		||||
                         qgsvectorlayerelevationproperties.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 "qgsvectorlayerelevationproperties.h"
 | 
			
		||||
#include "qgsrasterlayer.h"
 | 
			
		||||
 | 
			
		||||
QgsVectorLayerElevationProperties::QgsVectorLayerElevationProperties( QObject *parent )
 | 
			
		||||
  : QgsMapLayerElevationProperties( parent )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsVectorLayerElevationProperties::hasElevation() const
 | 
			
		||||
{
 | 
			
		||||
  // layer is considered as having non-default elevation settings if we aren't clamping to terrain
 | 
			
		||||
  return mClamping != Qgis::AltitudeClamping::Terrain;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QDomElement QgsVectorLayerElevationProperties::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext & )
 | 
			
		||||
{
 | 
			
		||||
  QDomElement element = document.createElement( QStringLiteral( "elevation" ) );
 | 
			
		||||
  element.setAttribute( QStringLiteral( "zoffset" ), qgsDoubleToString( mZOffset ) );
 | 
			
		||||
  element.setAttribute( QStringLiteral( "zscale" ), qgsDoubleToString( mZScale ) );
 | 
			
		||||
 | 
			
		||||
  element.setAttribute( QStringLiteral( "extrusion" ), qgsDoubleToString( mExtrusionHeight ) );
 | 
			
		||||
  element.setAttribute( QStringLiteral( "clamping" ), qgsEnumValueToKey( mClamping ) );
 | 
			
		||||
  element.setAttribute( QStringLiteral( "binding" ), qgsEnumValueToKey( mBinding ) );
 | 
			
		||||
  parentElement.appendChild( element );
 | 
			
		||||
  return element;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsVectorLayerElevationProperties::readXml( const QDomElement &element, const QgsReadWriteContext & )
 | 
			
		||||
{
 | 
			
		||||
  const QDomElement elevationElement = element.firstChildElement( QStringLiteral( "elevation" ) ).toElement();
 | 
			
		||||
  mZOffset = elevationElement.attribute( QStringLiteral( "zoffset" ), QStringLiteral( "0" ) ).toDouble();
 | 
			
		||||
  mZScale = elevationElement.attribute( QStringLiteral( "zscale" ), QStringLiteral( "1" ) ).toDouble();
 | 
			
		||||
 | 
			
		||||
  mClamping = qgsEnumKeyToValue( elevationElement.attribute( QStringLiteral( "clamping" ) ), Qgis::AltitudeClamping::Terrain );
 | 
			
		||||
  mBinding = qgsEnumKeyToValue( elevationElement.attribute( QStringLiteral( "binding" ) ), Qgis::AltitudeBinding::Centroid );
 | 
			
		||||
  mExtrusionHeight = elevationElement.attribute( QStringLiteral( "extrusion" ), QStringLiteral( "0" ) ).toDouble();
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsVectorLayerElevationProperties::isVisibleInZRange( const QgsDoubleRange & ) const
 | 
			
		||||
{
 | 
			
		||||
  // TODO -- test actual layer z range
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QgsDoubleRange QgsVectorLayerElevationProperties::calculateZRange( QgsMapLayer * ) const
 | 
			
		||||
{
 | 
			
		||||
  // TODO -- determine actual z range from layer statistics
 | 
			
		||||
  return QgsDoubleRange();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										109
									
								
								src/core/vector/qgsvectorlayerelevationproperties.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/core/vector/qgsvectorlayerelevationproperties.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,109 @@
 | 
			
		||||
/***************************************************************************
 | 
			
		||||
                         qgsvectorlayerelevationproperties.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 QGSVECTORLAYERELEVATIONPROPERTIES_H
 | 
			
		||||
#define QGSVECTORLAYERELEVATIONPROPERTIES_H
 | 
			
		||||
 | 
			
		||||
#include "qgis_core.h"
 | 
			
		||||
#include "qgis_sip.h"
 | 
			
		||||
#include "qgis.h"
 | 
			
		||||
#include "qgsmaplayerelevationproperties.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \class QgsVectorLayerElevationProperties
 | 
			
		||||
 * \ingroup core
 | 
			
		||||
 * \brief Vector layer specific subclass of QgsMapLayerElevationProperties.
 | 
			
		||||
 *
 | 
			
		||||
 * \since QGIS 3.26
 | 
			
		||||
 */
 | 
			
		||||
class CORE_EXPORT QgsVectorLayerElevationProperties : public QgsMapLayerElevationProperties
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor for QgsVectorLayerElevationProperties, with the specified \a parent object.
 | 
			
		||||
     */
 | 
			
		||||
    QgsVectorLayerElevationProperties( 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 the altitude clamping method, which dictates how feature heights are interpreted
 | 
			
		||||
     * with respect to terrain heights.
 | 
			
		||||
     *
 | 
			
		||||
     * \see setClamping()
 | 
			
		||||
     */
 | 
			
		||||
    Qgis::AltitudeClamping clamping() const { return mClamping; }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the altitude \a clamping method, which dictates how feature heights are interpreted
 | 
			
		||||
     * with respect to terrain heights.
 | 
			
		||||
     *
 | 
			
		||||
     * \see clamping()
 | 
			
		||||
     */
 | 
			
		||||
    void setClamping( Qgis::AltitudeClamping clamping ) { mClamping = clamping; }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the altitude binding method, which determines how altitude is bound to individual vertices in features.
 | 
			
		||||
     *
 | 
			
		||||
     * \see setBinding()
 | 
			
		||||
     */
 | 
			
		||||
    Qgis::AltitudeBinding binding() const { return mBinding; }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the altitude \a binding method, which determines how altitude is bound to individual vertices in features.
 | 
			
		||||
     *
 | 
			
		||||
     * \see binding()
 | 
			
		||||
     */
 | 
			
		||||
    void setBinding( Qgis::AltitudeBinding binding ) { mBinding = binding; }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the feature extrusion height.
 | 
			
		||||
     *
 | 
			
		||||
     * \note the zScale() factor is NOT applied to extrusion heights.
 | 
			
		||||
     *
 | 
			
		||||
     * \see setExtrusionHeight()
 | 
			
		||||
     */
 | 
			
		||||
    double extrusionHeight() const { return mExtrusionHeight; }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the feature extrusion height.
 | 
			
		||||
     *
 | 
			
		||||
     * \note the zScale() factor is NOT applied to extrusion heights.
 | 
			
		||||
     *
 | 
			
		||||
     * \see extrusionHeight()
 | 
			
		||||
     */
 | 
			
		||||
    void setExtrusionHeight( double height ) { mExtrusionHeight = height; }
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
 | 
			
		||||
    Qgis::AltitudeClamping mClamping = Qgis::AltitudeClamping::Terrain;
 | 
			
		||||
    Qgis::AltitudeBinding mBinding = Qgis::AltitudeBinding::Centroid;
 | 
			
		||||
 | 
			
		||||
    double mExtrusionHeight = 0;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // QGSVECTORLAYERELEVATIONPROPERTIES_H
 | 
			
		||||
							
								
								
									
										228
									
								
								src/ui/qgsvectorelevationpropertieswidgetbase.ui
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								src/ui/qgsvectorelevationpropertieswidgetbase.ui
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,228 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>QgsVectorElevationPropertiesWidgetBase</class>
 | 
			
		||||
 <widget class="QWidget" name="QgsVectorElevationPropertiesWidgetBase">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>555</width>
 | 
			
		||||
    <height>445</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>Vector 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>Elevation Clamping</string>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="checkable">
 | 
			
		||||
      <bool>false</bool>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="syncGroup" stdset="0">
 | 
			
		||||
      <string notr="true">vectorgeneral</string>
 | 
			
		||||
     </property>
 | 
			
		||||
     <layout class="QGridLayout" name="gridLayout_2" columnstretch="0,1,0">
 | 
			
		||||
      <item row="3" 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>
 | 
			
		||||
      <item row="1" column="0" colspan="3">
 | 
			
		||||
       <widget class="QLabel" name="mLabelClampingExplanation">
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string/>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="wordWrap">
 | 
			
		||||
         <bool>true</bool>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item row="0" column="0" colspan="3">
 | 
			
		||||
       <widget class="QComboBox" name="mComboClamping"/>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item row="3" column="0">
 | 
			
		||||
       <widget class="QLabel" name="label">
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>Offset</string>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item row="2" column="0">
 | 
			
		||||
       <widget class="QLabel" name="mLabelScale">
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>Scale</string>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item row="2" 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>
 | 
			
		||||
     </layout>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QGroupBox" name="mExtrusionGroupBox">
 | 
			
		||||
     <property name="focusPolicy">
 | 
			
		||||
      <enum>Qt::StrongFocus</enum>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="title">
 | 
			
		||||
      <string>Extrusion</string>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="checkable">
 | 
			
		||||
      <bool>false</bool>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="syncGroup" stdset="0">
 | 
			
		||||
      <string notr="true">vectorgeneral</string>
 | 
			
		||||
     </property>
 | 
			
		||||
     <layout class="QGridLayout" name="gridLayout_4">
 | 
			
		||||
      <item row="3" column="0">
 | 
			
		||||
       <widget class="Line" name="line_5">
 | 
			
		||||
        <property name="orientation">
 | 
			
		||||
         <enum>Qt::Vertical</enum>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item row="0" column="0" colspan="2">
 | 
			
		||||
       <widget class="QLabel" name="mLabelBindingExplanation_2">
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>Extrusion controls how high features extend vertically above their base.</string>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="textFormat">
 | 
			
		||||
         <enum>Qt::PlainText</enum>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="wordWrap">
 | 
			
		||||
         <bool>true</bool>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item row="1" column="0">
 | 
			
		||||
       <widget class="QLabel" name="label_3">
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>Height</string>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item row="1" column="1">
 | 
			
		||||
       <widget class="QgsDoubleSpinBox" name="mExtrusionSpinBox">
 | 
			
		||||
        <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>
 | 
			
		||||
    <widget class="QGroupBox" name="mBindingGroupBox">
 | 
			
		||||
     <property name="focusPolicy">
 | 
			
		||||
      <enum>Qt::StrongFocus</enum>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="title">
 | 
			
		||||
      <string>Elevation Binding</string>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="checkable">
 | 
			
		||||
      <bool>false</bool>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="syncGroup" stdset="0">
 | 
			
		||||
      <string notr="true">vectorgeneral</string>
 | 
			
		||||
     </property>
 | 
			
		||||
     <layout class="QGridLayout" name="gridLayout_3">
 | 
			
		||||
      <item row="0" column="0" colspan="2">
 | 
			
		||||
       <widget class="QComboBox" name="mComboBinding"/>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item row="2" column="0">
 | 
			
		||||
       <widget class="Line" name="line_4">
 | 
			
		||||
        <property name="orientation">
 | 
			
		||||
         <enum>Qt::Vertical</enum>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item row="1" column="0" colspan="2">
 | 
			
		||||
       <widget class="QLabel" name="mLabelBindingExplanation">
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string/>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="wordWrap">
 | 
			
		||||
         <bool>true</bool>
 | 
			
		||||
        </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>
 | 
			
		||||
@ -349,6 +349,7 @@ ADD_PYTHON_TEST(PyQgsVectorFieldMarkerSymbolLayer test_qgsvectorfieldmarkersymbo
 | 
			
		||||
ADD_PYTHON_TEST(PyQgsVectorFileWriter test_qgsvectorfilewriter.py)
 | 
			
		||||
ADD_PYTHON_TEST(PyQgsVectorFileWriterTask test_qgsvectorfilewritertask.py)
 | 
			
		||||
ADD_PYTHON_TEST(PyQgsVectorLayer test_qgsvectorlayer.py)
 | 
			
		||||
ADD_PYTHON_TEST(PyQgsVectorLayerElevationProperties test_qgsvectorlayerelevationproperties.py)
 | 
			
		||||
ADD_PYTHON_TEST(PyQgsVectorLayerFeatureCounter test_qgsvectorlayerfeaturecounter.py)
 | 
			
		||||
ADD_PYTHON_TEST(PyQgsVectorLayerCache test_qgsvectorlayercache.py)
 | 
			
		||||
ADD_PYTHON_TEST(PyQgsVectorLayerEditBuffer test_qgsvectorlayereditbuffer.py)
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,7 @@ class TestQgsRasterLayerElevationProperties(unittest.TestCase):
 | 
			
		||||
        props2.readXml(elem, QgsReadWriteContext())
 | 
			
		||||
        self.assertEqual(props2.zScale(), 2)
 | 
			
		||||
        self.assertEqual(props2.zOffset(), 0.5)
 | 
			
		||||
        self.assertTrue(props.isEnabled())
 | 
			
		||||
        self.assertTrue(props2.isEnabled())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										65
									
								
								tests/src/python/test_qgsvectorlayerelevationproperties.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								tests/src/python/test_qgsvectorlayerelevationproperties.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,65 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
"""QGIS Unit tests for QgsVectorLayerElevationProperties
 | 
			
		||||
 | 
			
		||||
.. 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 (
 | 
			
		||||
    Qgis,
 | 
			
		||||
    QgsVectorLayerElevationProperties,
 | 
			
		||||
    QgsReadWriteContext,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from qgis.PyQt.QtXml import QDomDocument
 | 
			
		||||
 | 
			
		||||
from qgis.testing import start_app, unittest
 | 
			
		||||
 | 
			
		||||
start_app()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestQgsVectorLayerElevationProperties(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def testBasic(self):
 | 
			
		||||
        props = QgsVectorLayerElevationProperties(None)
 | 
			
		||||
        self.assertEqual(props.zScale(), 1)
 | 
			
		||||
        self.assertEqual(props.zOffset(), 0)
 | 
			
		||||
        self.assertEqual(props.extrusionHeight(), 0)
 | 
			
		||||
        self.assertFalse(props.hasElevation())
 | 
			
		||||
        self.assertEqual(props.clamping(), Qgis.AltitudeClamping.Terrain)
 | 
			
		||||
        self.assertEqual(props.binding(), Qgis.AltitudeBinding.Centroid)
 | 
			
		||||
 | 
			
		||||
        props.setZOffset(0.5)
 | 
			
		||||
        props.setZScale(2)
 | 
			
		||||
        props.setClamping(Qgis.AltitudeClamping.Relative)
 | 
			
		||||
        props.setBinding(Qgis.AltitudeBinding.Vertex)
 | 
			
		||||
        props.setExtrusionHeight(10)
 | 
			
		||||
        self.assertEqual(props.zScale(), 2)
 | 
			
		||||
        self.assertEqual(props.zOffset(), 0.5)
 | 
			
		||||
        self.assertEqual(props.extrusionHeight(), 10)
 | 
			
		||||
        self.assertTrue(props.hasElevation())
 | 
			
		||||
        self.assertEqual(props.clamping(), Qgis.AltitudeClamping.Relative)
 | 
			
		||||
        self.assertEqual(props.binding(), Qgis.AltitudeBinding.Vertex)
 | 
			
		||||
 | 
			
		||||
        doc = QDomDocument("testdoc")
 | 
			
		||||
        elem = doc.createElement('test')
 | 
			
		||||
        props.writeXml(elem, doc, QgsReadWriteContext())
 | 
			
		||||
 | 
			
		||||
        props2 = QgsVectorLayerElevationProperties(None)
 | 
			
		||||
        props2.readXml(elem, QgsReadWriteContext())
 | 
			
		||||
        self.assertEqual(props2.zScale(), 2)
 | 
			
		||||
        self.assertEqual(props2.zOffset(), 0.5)
 | 
			
		||||
        self.assertEqual(props2.clamping(), Qgis.AltitudeClamping.Relative)
 | 
			
		||||
        self.assertEqual(props2.binding(), Qgis.AltitudeBinding.Vertex)
 | 
			
		||||
        self.assertEqual(props2.extrusionHeight(), 10)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    unittest.main()
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user