Skip to content

Commit

Permalink
Expose choice of raster data type for reclassify algs
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jun 13, 2018
1 parent b26957e commit a62a2bc
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 3 deletions.
8 changes: 7 additions & 1 deletion src/analysis/processing/qgsalgorithmreclassifybylayer.cpp
Expand Up @@ -18,6 +18,7 @@
#include "qgsalgorithmreclassifybylayer.h"
#include "qgsrasterfilewriter.h"
#include "qgsreclassifyutils.h"
#include "qgsrasteranalysisutils.h"
#include "qgis.h"

///@cond PRIVATE
Expand Down Expand Up @@ -65,11 +66,16 @@ void QgsReclassifyAlgorithmBase::initAlgorithm( const QVariantMap & )
missingValuesParam->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
addParameter( missingValuesParam.release() );

std::unique_ptr< QgsProcessingParameterDefinition > typeChoice = QgsRasterAnalysisUtils::createRasterTypeParameter( QStringLiteral( "DATA_TYPE" ), QObject::tr( "Output data type" ), Qgis::Float32 );
typeChoice->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
addParameter( typeChoice.release() );

addParameter( new QgsProcessingParameterRasterDestination( QStringLiteral( "OUTPUT" ), QObject::tr( "Reclassified raster" ) ) );
}

bool QgsReclassifyAlgorithmBase::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
{
mDataType = QgsRasterAnalysisUtils::rasterTypeChoiceToDataType( parameterAsEnum( parameters, QStringLiteral( "DATA_TYPE" ), context ) );
QgsRasterLayer *layer = parameterAsRasterLayer( parameters, QStringLiteral( "INPUT_RASTER" ), context );

if ( !layer )
Expand Down Expand Up @@ -125,7 +131,7 @@ QVariantMap QgsReclassifyAlgorithmBase::processAlgorithm( const QVariantMap &par
std::unique_ptr< QgsRasterFileWriter > writer = qgis::make_unique< QgsRasterFileWriter >( outputFile );
writer->setOutputProviderKey( QStringLiteral( "gdal" ) );
writer->setOutputFormat( outputFormat );
std::unique_ptr<QgsRasterDataProvider > provider( writer->createOneBandRaster( Qgis::Float32, mNbCellsXProvider, mNbCellsYProvider, mExtent, mCrs ) );
std::unique_ptr<QgsRasterDataProvider > provider( writer->createOneBandRaster( mDataType, mNbCellsXProvider, mNbCellsYProvider, mExtent, mCrs ) );
if ( !provider )
throw QgsProcessingException( QObject::tr( "Could not create raster output: %1" ).arg( outputFile ) );
if ( !provider->isValid() )
Expand Down
1 change: 1 addition & 0 deletions src/analysis/processing/qgsalgorithmreclassifybylayer.h
Expand Up @@ -64,6 +64,7 @@ class QgsReclassifyAlgorithmBase : public QgsProcessingAlgorithm

std::unique_ptr< QgsRasterInterface > mInterface;

Qgis::DataType mDataType = Qgis::Float32;
double mNoDataValue = -9999;
int mBand = 1;
QgsRectangle mExtent;
Expand Down
50 changes: 49 additions & 1 deletion src/analysis/processing/qgsrasteranalysisutils.cpp
Expand Up @@ -19,7 +19,8 @@
#include "qgsrasterblock.h"
#include "qgsrasteriterator.h"
#include "qgsgeos.h"

#include "qgsprocessingparameters.h"
#include <map>
///@cond PRIVATE

void QgsRasterAnalysisUtils::cellInfoForBBox( const QgsRectangle &rasterBBox, const QgsRectangle &featureBBox, double cellSizeX, double cellSizeY,
Expand Down Expand Up @@ -171,4 +172,51 @@ bool QgsRasterAnalysisUtils::validPixel( double value )
return !std::isnan( value );
}

static QVector< QPair< QString, Qgis::DataType > > sDataTypes;

void populateDataTypes()
{
if ( sDataTypes.empty() )
{
sDataTypes.append( qMakePair( QStringLiteral( "Byte" ), Qgis::Byte ) );
sDataTypes.append( qMakePair( QStringLiteral( "Int16" ), Qgis::Int16 ) );
sDataTypes.append( qMakePair( QStringLiteral( "UInt16" ), Qgis::UInt16 ) );
sDataTypes.append( qMakePair( QStringLiteral( "Int32" ), Qgis::Int32 ) );
sDataTypes.append( qMakePair( QStringLiteral( "UInt32" ), Qgis::UInt32 ) );
sDataTypes.append( qMakePair( QStringLiteral( "Float32" ), Qgis::Float32 ) );
sDataTypes.append( qMakePair( QStringLiteral( "Float64" ), Qgis::Float64 ) );
sDataTypes.append( qMakePair( QStringLiteral( "CInt16" ), Qgis::CInt16 ) );
sDataTypes.append( qMakePair( QStringLiteral( "CInt32" ), Qgis::CInt32 ) );
sDataTypes.append( qMakePair( QStringLiteral( "CFloat32" ), Qgis::CFloat32 ) );
sDataTypes.append( qMakePair( QStringLiteral( "CFloat64" ), Qgis::CFloat64 ) );
}
}

std::unique_ptr<QgsProcessingParameterDefinition> QgsRasterAnalysisUtils::createRasterTypeParameter( const QString &name, const QString &description, Qgis::DataType defaultType )
{
populateDataTypes();

QStringList names;
int defaultChoice = 0;
int i = 0;
for ( auto it = sDataTypes.constBegin(); it != sDataTypes.constEnd(); ++it )
{
names.append( it->first );
if ( it->second == defaultType )
defaultChoice = i;
i++;
}

return qgis::make_unique< QgsProcessingParameterEnum >( name, description, names, false, defaultChoice );
}

Qgis::DataType QgsRasterAnalysisUtils::rasterTypeChoiceToDataType( int choice )
{
if ( choice < 0 || choice >= sDataTypes.count() )
return Qgis::Float32;

return sDataTypes.value( choice ).second;
}

///@endcond PRIVATE

18 changes: 18 additions & 0 deletions src/analysis/processing/qgsrasteranalysisutils.h
Expand Up @@ -17,8 +17,10 @@
#define QGSRASTERANALYSISUTILS_H

#include "qgis_analysis.h"
#include "qgis.h"

#include <functional>
#include <memory>

#define SIP_NO_FILE

Expand All @@ -27,6 +29,7 @@
class QgsRasterInterface;
class QgsGeometry;
class QgsRectangle;
class QgsProcessingParameterDefinition;

namespace QgsRasterAnalysisUtils
{
Expand All @@ -48,8 +51,23 @@ namespace QgsRasterAnalysisUtils

//! Tests whether a pixel's value should be included in the result
bool validPixel( double value );

/**
* Returns a new processing enum parameter for choice of raster data types.
* \see rasterTypeChoiceToDataType()
*/
std::unique_ptr< QgsProcessingParameterDefinition > createRasterTypeParameter( const QString &name,
const QString &description,
Qgis::DataType defaultType = Qgis::Float32 );

/**
* Converts the value of a raster type parameter to the corresponding data type.
* \see createRasterTypeParameter()
*/
Qgis::DataType rasterTypeChoiceToDataType( int choice );
}


///@endcond PRIVATE

#endif // QGSRASTERANALYSISUTILS_H
2 changes: 1 addition & 1 deletion src/analysis/processing/qgsreclassifyutils.cpp
Expand Up @@ -56,7 +56,7 @@ void QgsReclassifyUtils::reclassify( const QVector<QgsReclassifyUtils::RasterCla
feedback->setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
if ( feedback && feedback->isCanceled() )
break;
std::unique_ptr< QgsRasterBlock > reclassifiedBlock = qgis::make_unique< QgsRasterBlock >( Qgis::Float32, iterCols, iterRows );
std::unique_ptr< QgsRasterBlock > reclassifiedBlock = qgis::make_unique< QgsRasterBlock >( destinationRaster->dataType( 1 ), iterCols, iterRows );

for ( int row = 0; row < iterRows; row++ )
{
Expand Down

0 comments on commit a62a2bc

Please sign in to comment.