Skip to content

Commit

Permalink
Raster attributes and raster maptips
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Nov 9, 2022
1 parent 5fe715a commit b37f5f4
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 0 deletions.
21 changes: 21 additions & 0 deletions resources/function_help/json/raster_attributes
@@ -0,0 +1,21 @@
{
"name": "raster_attributes",
"type": "function",
"groups": ["Rasters"],
"description": "Returns a map with the fields names as keys and the raster attribute table values as values from the attribute table entry that matches the given raster value .",
"arguments": [{
"arg": "layer",
"description": "the name or id of a raster layer"
}, {
"arg": "band",
"description": "the band number to sample the value from and for the associated attribute table lookup."
}, {
"arg": "value",
"description": "raster value"
}],
"examples": [{
"expression": "raster_attributes('vegetation', 1, raster_value('vegetation', 1, make_point(1,1)))",
"returns": "{'class': 'Vegetated', 'subclass': 'Trees'}"
}],
"tags": ["provider", "point", "raster", "found", "attributes"]
}
51 changes: 51 additions & 0 deletions src/core/expression/qgsexpressionfunction.cpp
Expand Up @@ -1697,6 +1697,56 @@ static QVariant fcnRasterValue( const QVariantList &values, const QgsExpressionC
return std::isnan( value ) ? QVariant() : value;
}

static QVariant fcnRasterAttributes( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
{
QgsRasterLayer *layer = QgsExpressionUtils::getRasterLayer( values.at( 0 ), parent );
if ( !layer || !layer->dataProvider() )
{
parent->setEvalErrorString( QObject::tr( "Function `raster_attributes` requires a valid raster layer." ) );
return QVariant();
}

int bandNb = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
if ( bandNb < 1 || bandNb > layer->bandCount() )
{
parent->setEvalErrorString( QObject::tr( "Function `raster_attributes` requires a valid raster band number." ) );
return QVariant();
}

const double value = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
if ( std::isnan( value ) )
{
parent->setEvalErrorString( QObject::tr( "Function `raster_attributes` requires a valid raster value." ) );
return QVariant();
}

if ( ! layer->dataProvider()->attributeTable( bandNb ) )
{
return QVariant();
}

const QVariantList data { layer->dataProvider()->attributeTable( bandNb )->row( value ) };
if ( data.isEmpty() )
{
return QVariant();
}

QVariantMap result;
const QList<QgsRasterAttributeTable::Field> fields { layer->dataProvider()->attributeTable( bandNb )->fields() };
for ( int idx = 0; idx < static_cast<int>( fields.count( ) ) && idx < static_cast<int>( data.count() ); ++idx )
{
const QgsRasterAttributeTable::Field field { fields.at( idx ) };
if ( field.isColor() || field.isRamp() )
{
continue;
}
result.insert( fields.at( idx ).name, data.at( idx ) );
}

return result;
}


static QVariant fcnFeature( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * )
{
if ( !context )
Expand Down Expand Up @@ -8470,6 +8520,7 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
<< new QgsStaticExpressionFunction( QStringLiteral( "env" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "name" ) ), fcnEnvVar, QStringLiteral( "General" ), QString() )
<< new QgsWithVariableExpressionFunction()
<< new QgsStaticExpressionFunction( QStringLiteral( "raster_value" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "layer" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "band" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "point" ) ), fcnRasterValue, QStringLiteral( "Rasters" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "raster_attributes" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "layer" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "band" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "point" ) ), fcnRasterAttributes, QStringLiteral( "Rasters" ) )

// functions for arrays
<< new QgsArrayForeachExpressionFunction()
Expand Down
26 changes: 26 additions & 0 deletions src/gui/qgsmaptip.cpp
Expand Up @@ -17,6 +17,7 @@
#include "qgsmapcanvas.h"
#include "qgsmaptool.h"
#include "qgsvectorlayer.h"
#include "qgsrasterlayer.h"
#include "qgsexpression.h"
#include "qgslogger.h"
#include "qgssettings.h"
Expand Down Expand Up @@ -313,6 +314,31 @@ QString QgsMapTip::fetchFeature( QgsMapLayer *layer, QgsPointXY &mapPosition, Qg
return tipString;
}

QString QgsMapTip::fetchRaster( QgsMapLayer *layer, QgsPointXY &mapPosition, QgsMapCanvas *mapCanvas )
{
QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer *>( layer );
if ( !rlayer )
return QString();

if ( !layer->isInScaleRange( mapCanvas->mapSettings().scale() ) )
{
return QString();
}

const QgsPointXY mappedPosition { mapCanvas->mapSettings().mapToLayerCoordinates( layer, mapPosition ) };

if ( ! layer->extent().contains( mappedPosition ) )
{
return QString( );
}

QgsExpressionContext context( QgsExpressionContextUtils::globalProjectLayerScopes( layer ) );
context.appendScope( QgsExpressionContextUtils::mapSettingsScope( mapCanvas->mapSettings() ) );

const QString mapTip = rlayer->mapTipTemplate();

}

void QgsMapTip::applyFontSettings()
{
const QgsSettings settings;
Expand Down
5 changes: 5 additions & 0 deletions src/gui/qgsmaptip.h
Expand Up @@ -97,6 +97,11 @@ class GUI_EXPORT QgsMapTip : public QWidget
QgsPointXY &mapPosition,
QgsMapCanvas *mapCanvas );

// Sample the raster and get the maptip text
QString fetchRaster( QgsMapLayer *layer,
QgsPointXY &mapPosition,
QgsMapCanvas *mapCanvas );

QString replaceText(
QString displayText, QgsVectorLayer *layer, QgsFeature &feat );

Expand Down

0 comments on commit b37f5f4

Please sign in to comment.