Skip to content

Commit

Permalink
Global map terrain shading (#51535)
Browse files Browse the repository at this point in the history
* QgsShadingRendering and pipe to render global elevation map

* gdal utils with datatype and resampling method enum

* raster layer elevation map

* optimize raster elevation map with rotation

* handle  no data value in the map elevation raster pipe

* mesh layer and some little fixes

* fix nodata and hillshading z factor

* render shading on layout

* activate/deactivate the shading from ui

* shading only for layer that have elevation

* apply Z scale and offset of layer elevation properties

* ui settings

* allow elevation from point cloud even edl is deactivate for pointcloud

* fix ui

* sipify

* Shading renderer widget in styling panel

* icone for shading renderer settings widget

* two methods to combin elevation

* rewording

* remove check box at the bottom of canvas

* use band of elevation properties

* fix styling pannel

* render shading in layout

* keep EDL point cloud shading individually

* add shading rendering tests

* add missing code for local EDL for point cloud

* shading inactive by default

* rework raster layer resampling

* improve nodata in elevation map

* don't allow elevation map with != size to be combined

* remove EDL from point cloud

* renaming

* sipify

* colorize tests

* renaming

* RGB32

* renaming leftover

* some ui fixes

* fix border for EDL alg

* fix EDL closed next to nodata value

* fix first shading when activated

* renaming and typo

* fixes for doc, doxygen, indentation and spelling

* remove leftover member

* fix clang-tidy

* fix edl tests

* fix dll export

* minor fixes

* adapt images of tests

* fix narrowing

* fix indentation

* sipify

* WIP

* minor ui changes
  • Loading branch information
vcloarec committed Jan 26, 2023
1 parent 8d8ca9b commit 3ca858a
Show file tree
Hide file tree
Showing 73 changed files with 2,917 additions and 484 deletions.
1 change: 1 addition & 0 deletions images/images.qrc
Expand Up @@ -966,6 +966,7 @@
<file>themes/default/mActionNewFileGeodatabase.svg</file>
<file>themes/default/mIconBrowserRelations.svg</file>
<file>themes/default/mActionIdentifyByMouseOver.svg</file>
<file>themes/default/mShadingRenderer.svg</file>
<file>themes/default/gpsicons/mIconGpsConnect.svg</file>
<file>themes/default/gpsicons/mIconGpsDisconnect.svg</file>
<file>themes/default/gpsicons/mActionRecenter.svg</file>
Expand Down
1 change: 1 addition & 0 deletions images/themes/default/mShadingRenderer.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions python/core/auto_additions/qgis.py
Expand Up @@ -2465,3 +2465,9 @@
Qgis.RasterIdentifyFormat.__doc__ = 'Raster identify formats.\n\n.. note::\n\n Prior to QGIS 3.30 this was available as :py:class:`QgsRaster`.IdentifyFormat\n\n.. versionadded:: 3.30\n\n' + '* ``IdentifyFormatUndefined``: ' + Qgis.RasterIdentifyFormat.Undefined.__doc__ + '\n' + '* ``IdentifyFormatValue``: ' + Qgis.RasterIdentifyFormat.Value.__doc__ + '\n' + '* ``IdentifyFormatText``: ' + Qgis.RasterIdentifyFormat.Text.__doc__ + '\n' + '* ``IdentifyFormatHtml``: ' + Qgis.RasterIdentifyFormat.Html.__doc__ + '\n' + '* ``IdentifyFormatFeature``: ' + Qgis.RasterIdentifyFormat.Feature.__doc__
# --
Qgis.RasterIdentifyFormat.baseClass = Qgis
# monkey patching scoped based enum
Qgis.ElevationMapCombineMethod.HighestElevation.__doc__ = "Keep the highest elevation if it is not null"
Qgis.ElevationMapCombineMethod.NewerElevation.__doc__ = "Keep the new elevation regardless of its value if it is not null"
Qgis.ElevationMapCombineMethod.__doc__ = 'Methods used to select the elevation when two elevation maps are combined\n\n.. versionadded:: 3.30\n\n' + '* ``HighestElevation``: ' + Qgis.ElevationMapCombineMethod.HighestElevation.__doc__ + '\n' + '* ``NewerElevation``: ' + Qgis.ElevationMapCombineMethod.NewerElevation.__doc__
# --
Qgis.ElevationMapCombineMethod.baseClass = Qgis
Expand Up @@ -181,6 +181,7 @@ Returns map settings with which this job was started.




signals:

void renderingLayersFinished();
Expand Down Expand Up @@ -242,6 +243,7 @@ emitted when asynchronous rendering is finished (or canceled).






};
Expand Down
89 changes: 0 additions & 89 deletions python/core/auto_generated/pointcloud/qgspointcloudrenderer.sip.in
Expand Up @@ -157,7 +157,6 @@ Returns the feedback object used to cancel rendering
%End



private:
QgsPointCloudRenderContext( const QgsPointCloudRenderContext &rh );
};
Expand Down Expand Up @@ -447,94 +446,6 @@ Creates a set of legend nodes representing the renderer.
virtual QStringList legendRuleKeys() const;
%Docstring
Returns a list of all rule keys for legend nodes created by the renderer.
%End

bool eyeDomeLightingEnabled() const;
%Docstring
Returns whether eye dome lighting effect will be used

.. note::

This is not a part of stable API - this function may be removed in a future release

.. versionadded:: 3.28
%End

void setEyeDomeLightingEnabled( bool enabled );
%Docstring
Sets whether eye dome lighting effect will be used

.. note::

This is not a part of stable API - this function may be removed in a future release

.. versionadded:: 3.28
%End

double eyeDomeLightingStrength() const;
%Docstring
Returns the eye dome lighting strength value

.. note::

This is not a part of stable API - this function may be removed in a future release

.. versionadded:: 3.28
%End

void setEyeDomeLightingStrength( double strength );
%Docstring
Sets the eye dome lighting strength value

.. note::

This is not a part of stable API - this function may be removed in a future release

.. versionadded:: 3.28
%End

double eyeDomeLightingDistance() const;
%Docstring
Returns the eye dome lighting distance

.. note::

This is not a part of stable API - this function may be removed in a future release

.. versionadded:: 3.28
%End

void setEyeDomeLightingDistance( double distance );
%Docstring
Sets the eye dome lighting distance

.. note::

This is not a part of stable API - this function may be removed in a future release

.. versionadded:: 3.28
%End

QgsUnitTypes::RenderUnit eyeDomeLightingDistanceUnit() const;
%Docstring
Returns unit for the eye dome lighting distance

.. note::

This is not a part of stable API - this function may be removed in a future release

.. versionadded:: 3.28
%End

void setEyeDomeLightingDistanceUnit( QgsUnitTypes::RenderUnit unit );
%Docstring
Sets unit for the eye dome lighting distance

.. note::

This is not a part of stable API - this function may be removed in a future release

.. versionadded:: 3.28
%End

protected:
Expand Down
21 changes: 21 additions & 0 deletions python/core/auto_generated/project/qgsproject.sip.in
Expand Up @@ -1603,6 +1603,20 @@ Returns ``True`` if the visitor should continue visiting other objects, or ``Fal
should be canceled.

.. versionadded:: 3.10
%End

QgsElevationShadingRenderer elevationShadingRenderer() const;
%Docstring
Returns the elevation shading renderer used for map shading

.. versionadded:: 3.30
%End

void setElevationShadingRenderer( const QgsElevationShadingRenderer &elevationShadingRenderer );
%Docstring
Sets the elevation shading renderer used for global map shading

.. versionadded:: 3.30
%End

SIP_PYOBJECT __repr__();
Expand Down Expand Up @@ -2035,6 +2049,13 @@ Emitted when the list of custom project map scales changes.
Use :py:func:`~QgsProject.viewSettings` instead
%End

void elevationShadingRendererChanged();
%Docstring
Emitted when the map shading renderer changes

.. versionadded:: 3.30
%End

public slots:

void setSnappingConfig( const QgsSnappingConfig &snappingConfig );
Expand Down
6 changes: 6 additions & 0 deletions python/core/auto_generated/qgis.sip.in
Expand Up @@ -1607,6 +1607,12 @@ The development version
Feature,
};

enum class ElevationMapCombineMethod
{
HighestElevation,
NewerElevation,
};

static const double DEFAULT_SEARCH_RADIUS_MM;

static const float DEFAULT_MAPTOPIXEL_THRESHOLD;
Expand Down
83 changes: 76 additions & 7 deletions python/core/auto_generated/qgselevationmap.sip.in
Expand Up @@ -31,26 +31,67 @@ in meters.
#include "qgselevationmap.h"
%End
public:

QgsElevationMap();
%Docstring
Default constructor
%End

explicit QgsElevationMap( const QSize &size );
%Docstring
Constructs an elevation map with the given width and height
%End

void applyEyeDomeLighting( QImage &img, int distance, float strength, float rendererScale );
explicit QgsElevationMap( const QImage &image );
%Docstring
Constructs an elevation map from an existing raw elevation ``image``.
The image must have ARGB32 format and obtained by the :py:func:`~QgsElevationMap.rawElevationImage` method.

.. seealso:: :py:func:`rawElevationImage`

.. versionadded:: 3.30
%End

QgsElevationMap( const QgsElevationMap &other );
%Docstring
Applies eye dome lighting effect to the given image. The effect makes
Copy constructor
%End

void applyEyeDomeLighting( QImage &image, int distance, float strength, float rendererScale ) const;
%Docstring
Applies eye dome lighting effect to the given ``image``. The effect makes
angled surfaces darker and adds silhouettes in case of larger differences
of elevations between neighboring pixels.

The distance parameter tells how many pixels away from the original pixel
The ``distance`` parameter tells how many pixels away from the original pixel
to sample neighboring pixels. Normally distance of 2 pixels gives good results.

The strength parameter adjusts how strong the added shading will be.
The ``strength`` parameter adjusts how strong the added shading will be.
Good default for this value seems to be 1000.

The zScale parameter adjusts scale of elevation values. It is recommended
The ``rendererScale`` parameter adjusts scale of elevation values. It is recommended
to set this to the map's scale denominator to get similarly looking results
at different map scales.
%End

void applyHillshading( QImage &image, bool multiDirectional, double altitude, double azimuth, double zFactor, double cellSizeX, double cellSizeY ) const;
%Docstring
Applies hill shading effect to the given ``image``.

If the ``multidirectinal`` parameter is ``True``, the algorithm will considered a
multi horizontal directional light to apply the shading.

The parameter ``altitude`` (could also be named zenith) is the vertical direction of the light.

The parameter ``azimuth`` is the horizontal direction of the light considered if
``multidirectional`` is ``False``.

The parameter ``zFactor`` is the vertical exageration of the terrain.

The parameters ``cellSizeX`` and ``cellSizeY`` are the sizes of the elevation map cells in unit consistent
with the unit of the encoded elevation in this elevation map.

.. versionadded:: 3.30
%End

QImage rawElevationImage() const;
Expand All @@ -61,6 +102,25 @@ Returns raw elevation image with elevations encoded as color values
QPainter *painter() const;
%Docstring
Returns painter to the underlying QImage with elevations
%End

void combine( const QgsElevationMap &otherElevationMap, Qgis::ElevationMapCombineMethod method );
%Docstring
Combines this elevation map with ``otherElevationMap``.
This elevation map keeps its size and takes elevation values of otherElevationMap that
is not null for same row and column following the combine ``method``.
The other elevation map can have a different size, only rows and columns contained in
this elevation map will be considered.

.. versionadded:: 3.30
%End


bool isValid() const;
%Docstring
Returns whether the elevation map is valid.

.. versionadded:: 3.30
%End

static QRgb encodeElevation( float z );
Expand All @@ -73,8 +133,17 @@ Converts a color back to elevation value
%End


private:
QgsElevationMap( const QgsElevationMap & );
bool isNoData( QRgb colorRaw ) const;
%Docstring
Returns whether the encoded value is a no data value
%End

float noDataValue() const;
%Docstring
Returns the no data value for the elevation map
%End


};

/************************************************************************
Expand Down

0 comments on commit 3ca858a

Please sign in to comment.