Skip to content
Permalink
Browse files
[feature] Add WMS/XYZ interpretation type for Terrarium terrain tiles
Allows reading DEM tiles in the Terrarium terrain encoding type (e.g.
the global Mapzen terrain tiles freely available through AWS)
  • Loading branch information
nyalldawson committed Jan 10, 2022
1 parent ba9daca commit a1e1a53b652ee50b98eb40029348f9b9e702bf3d
@@ -4844,19 +4844,26 @@ QGISEXTERN QgsProviderMetadata *providerMetadataFactory()
}
#endif

Qgis::DataType QgsWmsInterpretationConverter::dataType() const
{
return Qgis::DataType::Float32;
}

std::unique_ptr<QgsWmsInterpretationConverter> QgsWmsInterpretationConverter::createConverter( const QString &key )
{
if ( key == QgsWmsInterpretationConverterMapTilerTerrainRGB::interpretationKey() )
return std::make_unique<QgsWmsInterpretationConverterMapTilerTerrainRGB>();
else if ( key == QgsWmsInterpretationConverterTerrariumRGB::interpretationKey() )
return std::make_unique<QgsWmsInterpretationConverterTerrariumRGB>();

return nullptr;
}

Qgis::DataType QgsWmsInterpretationConverter::dataType() const
{
return Qgis::DataType::Float32;
}

//
// QgsWmsInterpretationConverterMapTilerTerrainRGB
//

void QgsWmsInterpretationConverterMapTilerTerrainRGB::convert( const QRgb &color, float *converted ) const
{
int R = qRed( color );
@@ -4879,3 +4886,36 @@ QgsRasterHistogram QgsWmsInterpretationConverterMapTilerTerrainRGB::histogram( i
{
return QgsRasterHistogram();
}

//
// QgsWmsInterpretationConverterTerrariumRGB
//

void QgsWmsInterpretationConverterTerrariumRGB::convert( const QRgb &color, float *converted ) const
{
// for description of the "terrarium" format:
// https://github.com/tilezen/joerd/blob/master/docs/formats.md

if ( qAlpha( color ) == 255 )
{
*converted = qRed( color ) * 256 + qGreen( color ) + qBlue( color ) / 256.f - 32768;
}
else
{
*converted = std::numeric_limits<float>::quiet_NaN();
}
}

QgsRasterBandStats QgsWmsInterpretationConverterTerrariumRGB::statistics( int, int, const QgsRectangle &, int, QgsRasterBlockFeedback * ) const
{
QgsRasterBandStats stat;
stat.minimumValue = -11000;
stat.maximumValue = 9000;
stat.statsGathered = QgsRasterBandStats::Min | QgsRasterBandStats::Max;
return stat;
}

QgsRasterHistogram QgsWmsInterpretationConverterTerrariumRGB::histogram( int, int, double, double, const QgsRectangle &, int, bool, QgsRasterBlockFeedback * ) const
{
return QgsRasterHistogram();
}
@@ -156,6 +156,30 @@ class QgsWmsInterpretationConverterMapTilerTerrainRGB : public QgsWmsInterpretat
static QString interpretationKey() {return QStringLiteral( "maptilerterrain" );}
};

//! Class to convert color to float value following the terrarium terrain RGB interpretation
class QgsWmsInterpretationConverterTerrariumRGB : public QgsWmsInterpretationConverter
{
public:
void convert( const QRgb &color, float *converted ) const override;

QgsRasterBandStats statistics( int bandNo,
int stats = QgsRasterBandStats::All,
const QgsRectangle &extent = QgsRectangle(),
int sampleSize = 0, QgsRasterBlockFeedback *feedback = nullptr ) const override;

QgsRasterHistogram histogram( int bandNo,
int binCount = 0,
double minimum = std::numeric_limits<double>::quiet_NaN(),
double maximum = std::numeric_limits<double>::quiet_NaN(),
const QgsRectangle &extent = QgsRectangle(),
int sampleSize = 0,
bool includeOutOfRange = false,
QgsRasterBlockFeedback *feedback = nullptr ) const override;

static QString displayName() {return QObject::tr( "Terrarium Terrain RGB" );}
static QString interpretationKey() {return QStringLiteral( "terrariumterrain" );}
};

/**
*
* \brief Data provider for OGC WMS layers.
@@ -1322,6 +1322,7 @@ QgsWmsInterpretationComboBox::QgsWmsInterpretationComboBox( QWidget *parent ): Q
{
addItem( tr( "Default" ), QString() );
addItem( QgsWmsInterpretationConverterMapTilerTerrainRGB::displayName(), QgsWmsInterpretationConverterMapTilerTerrainRGB::interpretationKey() );
addItem( QgsWmsInterpretationConverterTerrariumRGB::displayName(), QgsWmsInterpretationConverterTerrariumRGB::interpretationKey() );
}

void QgsWmsInterpretationComboBox::setInterpretation( const QString &interpretationKey )
@@ -26,6 +26,8 @@
#include <qgssinglebandpseudocolorrenderer.h>
#include <qgsrastershader.h>
#include <qgsstyle.h>
#include "qgssinglebandgrayrenderer.h"
#include "qgsrasterlayer.h"

/**
* \ingroup UnitTests
@@ -271,6 +273,34 @@ class TestQgsWmsProvider: public QObject
QVERIFY( imageCheck( "convert_value", mapSettings ) );
}

void testTerrariumInterpretation()
{
QString dataDir( TEST_DATA_DIR );

QgsXyzConnection xyzConn;
xyzConn.interpretation = QgsWmsInterpretationConverterTerrariumRGB::interpretationKey();
xyzConn.url = QUrl::fromLocalFile( dataDir + QStringLiteral( "/terrarium_terrain_rgb.png" ) ).toString();
QgsRasterLayer layer( xyzConn.encodedUri(), "terrain", "wms" );
QVERIFY( layer.isValid() );
QVERIFY( layer.dataProvider()->dataType( 1 ) == Qgis::DataType::Float32 );

QgsSingleBandGrayRenderer *renderer = new QgsSingleBandGrayRenderer( layer.dataProvider(), 1 );
QgsContrastEnhancement *e = new QgsContrastEnhancement( Qgis::DataType::Float32 );
e->setMinimumValue( -50 );
e->setMaximumValue( 50 );
e->setContrastEnhancementAlgorithm( QgsContrastEnhancement::StretchToMinimumMaximum );
renderer->setContrastEnhancement( e );
layer.setRenderer( renderer );

QgsMapSettings mapSettings;
mapSettings.setLayers( QList<QgsMapLayer *>() << &layer );
mapSettings.setExtent( layer.extent() );
mapSettings.setOutputSize( QSize( 400, 400 ) );
mapSettings.setOutputDpi( 96 );
mapSettings.setDpiTarget( 48 );
QVERIFY( imageCheck( "terrarium_terrain", mapSettings ) );
}

bool imageCheck( const QString &testType, QgsMapSettings &mapSettings )
{
//use the QgsRenderChecker test utility class to
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a1e1a53

Please sign in to comment.