Skip to content

Commit

Permalink
Support infinite ranges for null class boundaries
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jun 13, 2018
1 parent 2320a04 commit 7c1dcfa
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 13 deletions.
70 changes: 57 additions & 13 deletions src/analysis/processing/qgsalgorithmreclassifybylayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,35 @@ QVector<QgsReclassifyUtils::RasterClass> QgsReclassifyByLayerAlgorithm::createCl
while ( mTableIterator.nextFeature( f ) )
{
bool ok = false;
double minValue = f.attribute( mMinFieldIdx ).toDouble( &ok );
if ( !ok )
throw QgsProcessingException( QObject::tr( "Invalid value for minimum: %1" ).arg( f.attribute( mMinFieldIdx ).toString() ) );
double maxValue = f.attribute( mMaxFieldIdx ).toDouble( &ok );
if ( !ok )
throw QgsProcessingException( QObject::tr( "Invalid value for maximum: %1" ).arg( f.attribute( mMaxFieldIdx ).toString() ) );
double value = f.attribute( mValueFieldIdx ).toDouble( &ok );

// null values map to nan, which corresponds to a range extended to +/- infinity....
const QVariant minVariant = f.attribute( mMinFieldIdx );
double minValue;
if ( minVariant.isNull() || minVariant.toString().isEmpty() )
{
minValue = std::numeric_limits<double>::quiet_NaN();
}
else
{
minValue = minVariant.toDouble( &ok );
if ( !ok )
throw QgsProcessingException( QObject::tr( "Invalid value for minimum: %1" ).arg( minVariant.toString() ) );
}
const QVariant maxVariant = f.attribute( mMaxFieldIdx );
double maxValue;
if ( maxVariant.isNull() || maxVariant.toString().isEmpty() )
{
maxValue = std::numeric_limits<double>::quiet_NaN();
ok = true;
}
else
{
maxValue = maxVariant.toDouble( &ok );
if ( !ok )
throw QgsProcessingException( QObject::tr( "Invalid value for maximum: %1" ).arg( maxVariant.toString() ) );
}

const double value = f.attribute( mValueFieldIdx ).toDouble( &ok );
if ( !ok )
throw QgsProcessingException( QObject::tr( "Invalid output value: %1" ).arg( f.attribute( mValueFieldIdx ).toString() ) );

Expand Down Expand Up @@ -296,12 +318,34 @@ QVector<QgsReclassifyUtils::RasterClass> QgsReclassifyByTableAlgorithm::createCl
for ( int row = 0; row < rows; ++row )
{
bool ok = false;
const double minValue = table.at( row * 3 ).toDouble( &ok );
if ( !ok )
throw QgsProcessingException( QObject::tr( "Invalid value for minimum: %1" ).arg( table.at( row * 3 ).toString() ) );
const double maxValue = table.at( row * 3 + 1 ).toDouble( &ok );
if ( !ok )
throw QgsProcessingException( QObject::tr( "Invalid value for maximum: %1" ).arg( table.at( row * 3 + 1 ).toString() ) );

// null values map to nan, which corresponds to a range extended to +/- infinity....
const QVariant minVariant = table.at( row * 3 );
double minValue;
if ( minVariant.isNull() || minVariant.toString().isEmpty() )
{
minValue = std::numeric_limits<double>::quiet_NaN();
}
else
{
minValue = minVariant.toDouble( &ok );
if ( !ok )
throw QgsProcessingException( QObject::tr( "Invalid value for minimum: %1" ).arg( table.at( row * 3 ).toString() ) );
}
const QVariant maxVariant = table.at( row * 3 + 1 );
double maxValue;
if ( maxVariant.isNull() || maxVariant.toString().isEmpty() )
{
maxValue = std::numeric_limits<double>::quiet_NaN();
ok = true;
}
else
{
maxValue = maxVariant.toDouble( &ok );
if ( !ok )
throw QgsProcessingException( QObject::tr( "Invalid value for maximum: %1" ).arg( table.at( row * 3 + 1 ).toString() ) );
}

const double value = table.at( row * 3 + 2 ).toDouble( &ok );
if ( !ok )
throw QgsProcessingException( QObject::tr( "Invalid output value: %1" ).arg( table.at( row * 3 + 2 ).toString() ) );
Expand Down
16 changes: 16 additions & 0 deletions tests/src/analysis/testqgsreclassifyutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,22 @@ void TestQgsReclassifyUtils::testReclassify_data()
<< -9999.0 << false << static_cast< int >( Qgis::Float32 )
<< QVector< double > { -7, -7, 3, 8, 8, 6 };

QTest::newRow( "infinite range" ) << QVector< double > { 1, 2, 3, 4, 5, 6 }
<< 3 << 2
<< ( QVector< QgsReclassifyUtils::RasterClass >()
<< QgsReclassifyUtils::RasterClass( 3, std::numeric_limits<double>::quiet_NaN(), QgsRasterRange::IncludeMax, 8 )
<< QgsReclassifyUtils::RasterClass( 1, 3, QgsRasterRange::IncludeMin, -7 ) )
<< -9999.0 << false << static_cast< int >( Qgis::Float32 )
<< QVector< double > { -7, -7, 3, 8, 8, 8 };

QTest::newRow( "infinite range 2" ) << QVector< double > { 1, 2, 3, 4, 5, 6 }
<< 3 << 2
<< ( QVector< QgsReclassifyUtils::RasterClass >()
<< QgsReclassifyUtils::RasterClass( 3, 4, QgsRasterRange::IncludeMax, 8 )
<< QgsReclassifyUtils::RasterClass( std::numeric_limits<double>::quiet_NaN(), 3, QgsRasterRange::IncludeMin, -7 ) )
<< -9999.0 << false << static_cast< int >( Qgis::Float32 )
<< QVector< double > { -7, -7, 3, 8, 5, 6 };

QTest::newRow( "with source no data" ) << QVector< double > { 1, 2, -9999, 4, 5, 6 }
<< 3 << 2
<< ( QVector< QgsReclassifyUtils::RasterClass >()
Expand Down

0 comments on commit 7c1dcfa

Please sign in to comment.