QGIS API Documentation 3.28.14-Firenze (exported)
Loading...
Searching...
No Matches
qgselevationmap.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgselevationmap.cpp
3 --------------------------------------
4 Date : August 2022
5 Copyright : (C) 2022 by Martin Dobias
6 Email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgselevationmap.h"
17
18#include "qgsrasterblock.h"
19
20#include <QPainter>
21#include <algorithm>
22#include <cmath>
23
24
25static const int ELEVATION_OFFSET = 8000;
26static const int ELEVATION_SCALE = 1000;
27
28
30 : mElevationImage( size, QImage::Format_ARGB32 )
31{
32 mElevationImage.fill( 0 );
33 mPainter.reset( new QPainter );
34 mPainter->begin( &mElevationImage );
35}
36
38{
39 double zScaled = ( z + ELEVATION_OFFSET ) * ELEVATION_SCALE;
40 unsigned int zInt = static_cast<unsigned int>( std::clamp( zScaled, 0., 16777215. ) ); // make sure to fit into 3 bytes
41 return QRgb( zInt | ( 0xff << 24 ) );
42}
43
45{
46 unsigned int zScaled = colorRaw & 0xffffff;
47 return ( ( double ) zScaled ) / ELEVATION_SCALE - ELEVATION_OFFSET;
48}
49
50std::unique_ptr<QgsElevationMap> QgsElevationMap::fromRasterBlock( QgsRasterBlock *block )
51{
52 std::unique_ptr<QgsElevationMap> elevMap( new QgsElevationMap( QSize( block->width(), block->height() ) ) );
53 QRgb *dataPtr = reinterpret_cast<QRgb *>( elevMap->mElevationImage.bits() );
54 for ( int row = 0; row < block->height(); ++row )
55 {
56 for ( int col = 0; col < block->width(); ++col )
57 {
58 bool isNoData;
59 double value = block->valueAndNoData( row, col, isNoData );
60 if ( !isNoData )
61 *dataPtr = encodeElevation( value );
62 ++dataPtr;
63 }
64 }
65 return elevMap;
66}
67
68void QgsElevationMap::applyEyeDomeLighting( QImage &img, int distance, float strength, float rendererScale )
69{
70 const int imgWidth = img.width(), imgHeight = img.height();
71 QRgb *imgPtr = reinterpret_cast<QRgb *>( img.bits() );
72 const QRgb *elevPtr = reinterpret_cast<const QRgb *>( mElevationImage.constBits() );
73
74 const int neighbours[] = { -1, 0, 1, 0, 0, -1, 0, 1 };
75 for ( int i = distance; i < imgWidth - distance; ++i )
76 {
77 for ( int j = distance; j < imgHeight - distance; ++j )
78 {
79 qgssize index = j * static_cast<qgssize>( imgWidth ) + i;
80 float factor = 0.0f;
81 float centerDepth = decodeElevation( elevPtr[ index ] );
82 for ( int k = 0; k < 4; ++k )
83 {
84 int iNeighbour = i + distance * neighbours[2 * k];
85 int jNeighbour = j + distance * neighbours[2 * k + 1];
86 qgssize neighbourIndex = jNeighbour * static_cast<qgssize>( imgWidth ) + iNeighbour;
87 float neighbourDepth = decodeElevation( elevPtr[ neighbourIndex ] );
88 factor += std::max<float>( 0, -( centerDepth - neighbourDepth ) );
89 }
90 float shade = exp( -factor * strength / rendererScale );
91
92 QRgb c = imgPtr[ index ];
93 imgPtr[ index ] = qRgba( qRed( c ) * shade, qGreen( c ) * shade, qBlue( c ) * shade, qAlpha( c ) );
94 }
95 }
96}
Stores digital elevation model in a raster image which may get updated as a part of map layer renderi...
static QRgb encodeElevation(float z)
Converts elevation value to an actual color.
static std::unique_ptr< QgsElevationMap > fromRasterBlock(QgsRasterBlock *block)
Creates an elevation map based on data from the given raster block.
void applyEyeDomeLighting(QImage &img, int distance, float strength, float rendererScale)
Applies eye dome lighting effect to the given image.
QgsElevationMap(const QSize &size)
Constructs an elevation map with the given width and height.
static float decodeElevation(QRgb colorRaw)
Converts a color back to elevation value.
Raster data container.
int height() const
Returns the height (number of rows) of the raster block.
double valueAndNoData(int row, int column, bool &isNoData) const
Reads a single value from the pixel at row and column, if type of block is numeric.
int width() const
Returns the width (number of columns) of the raster block.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...
Definition qgis.h:3032