Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[renderer] Live hillshade renderer for raster layers
Thanks to Asger Skovbo Petersen (@AsgerPetersen) for the idea and fixes Thanks to Nyall for reviews and bug fixes
- Loading branch information
Showing
15 changed files
with
947 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
class QgsHillshadeRenderer : QgsRasterRenderer | ||
{ | ||
%TypeHeaderCode | ||
#include "qgshillshaderenderer.h" | ||
%End | ||
public: | ||
/** Renderer owns color array*/ | ||
QgsHillshadeRenderer( QgsRasterInterface* input, int band , double lightAzimuth, double lightAngle ); | ||
|
||
~QgsHillshadeRenderer(); | ||
|
||
virtual QgsHillshadeRenderer * clone() const /Factory/; | ||
|
||
static QgsRasterRenderer* create( const QDomElement& elem, QgsRasterInterface* input ) /Factory/; | ||
|
||
QgsRasterBlock *block( int bandNo, const QgsRectangle & extent, int width, int height ) /Factory/; | ||
|
||
void writeXML( QDomDocument& doc, QDomElement& parentElem ) const; | ||
|
||
QList<int> usesBands() const; | ||
|
||
/** Returns the band used by the renderer | ||
*/ | ||
int band() const; | ||
|
||
/** Sets the band used by the renderer. | ||
* @see band | ||
*/ | ||
void setBand( int bandNo ); | ||
|
||
/** | ||
* @brief The direction of the light over the raster between 0-360 | ||
* @return The direction of the light over the raster | ||
*/ | ||
double azimuth() const; | ||
|
||
/** | ||
* @brief The angle of the light source over the raster | ||
* @return The angle of the light source over the raster | ||
*/ | ||
double altitude() const; | ||
|
||
/** | ||
* @brief Z Factor | ||
* @return Z Factor | ||
*/ | ||
double zFactor() const; | ||
|
||
|
||
/** | ||
* @brief Set the azimith of the light source. | ||
* @param azimuth The azimuth of the light source. | ||
*/ | ||
void setAzimuth( double azimuth ); | ||
|
||
/** | ||
* @brief Set the altitude of the light source | ||
* @param altitude The altitude | ||
*/ | ||
void setAltitude( double angle ); | ||
|
||
/** | ||
* @brief Set the Z factor of the result image. | ||
* @param zfactor The z factor. | ||
*/ | ||
void setZFactor( double zfactor ); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/** | ||
* @brief Renderer widget for the hill shade renderer. | ||
*/ | ||
class QgsHillshadeRendererWidget: QgsRasterRendererWidget | ||
{ | ||
%TypeHeaderCode | ||
#include <qgshillshaderendererwidget.h> | ||
%End | ||
public: | ||
|
||
/** | ||
* @brief Renderer widget for the hill shade renderer. | ||
* @param layer The layer attached for this widget. | ||
* @param extent The current extent. | ||
*/ | ||
QgsHillshadeRendererWidget( QgsRasterLayer* layer, const QgsRectangle &extent = QgsRectangle() ); | ||
~QgsHillshadeRendererWidget(); | ||
|
||
/** | ||
* Factory method to create the renderer for this type. | ||
*/ | ||
static QgsRasterRendererWidget* create( QgsRasterLayer* layer, const QgsRectangle &theExtent ) /Factory/; | ||
|
||
/** | ||
* @brief The renderer for the widget. | ||
* @return A new renderer for the the config in the widget | ||
*/ | ||
QgsRasterRenderer* renderer(); | ||
|
||
/** | ||
* @brief Set the widget state from the given renderer. | ||
* @param r The renderer to take the state from. | ||
*/ | ||
void setFromRenderer( const QgsRasterRenderer* r ); | ||
|
||
/** | ||
* @brief The direction of the light over the raster between 0-360 | ||
* @return The direction of the light over the raster | ||
*/ | ||
double azimuth() const; | ||
|
||
/** | ||
* @brief The angle of the light source over the raster | ||
* @return The angle of the light source over the raster | ||
*/ | ||
double altitude() const; | ||
|
||
/** | ||
* @brief Z Factor | ||
* @return Z Factor | ||
*/ | ||
double zFactor() const; | ||
|
||
public slots: | ||
/** | ||
* @brief Set the altitude of the light source | ||
* @param altitude The altitude | ||
*/ | ||
void setAltitude( double altitude ); | ||
|
||
/** | ||
* @brief Set the azimith of the light source. | ||
* @param azimuth The azimuth of the light source. | ||
*/ | ||
void setAzimuth( double azimuth ); | ||
|
||
/** | ||
* @brief Set the Z factor of the result image. | ||
* @param zfactor The z factor. | ||
*/ | ||
void setZFactor( double zfactor ); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
17b4856
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi guys,
when testing new live hillshader renderer, I got strange visual artifacts, that I don't get with gdal precalculated hillshade. I see random points and ghost grids. Grids seems to be cleaned by bilinear resampling, when points remain. See :
17b4856
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@haubourg That looks strange indeed. Do you have a small sample dataset which can be used for reproducing?
17b4856
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here is one extract:
dem.zip
when using nearest neighbor interpolation, it is even stranger:
17b4856
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@haubourg The nearest neighbor artefact is QGIS behaving "as designed" as far as I can tell.
When QGIS wants to upsample (for instance render 100x100 DEM pixels to 500x500 screen pixels), you can choose between the three resampling options.
When choosing nearest neighbor, QGIS will resample the DEM to 500x500 pixels using nearest neighbor interpolation. This upsampled raster is then handed to the hillshade renderer. This resampling method results in "staircase" artefacts. And we will get steep gradients for every 5 pixels, and no gradient for the next 5 pixels like your screendump above.
If you choose "Bilinear" or "Cubic" QGIS deploys a completely different strategy. In these cases the 100x100 pixel DEM is handed to the renderer which will render a nice (but small) hillshade. This rendered image is then upsampled (or stretched) to 500x500 pixels by QGIS. This results in a hillshade which is more "blurry" than it had to be.
What would be optimal in the context of the hillshade renderer would be, if QGIS could upsample the DEM data using for instance bilinear resampling and then hand the properly upsampled DEM to the renderer.
17b4856
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@haubourg @NathanW2 I fixed this in #3152