Skip to content

Commit 7c1dcfa

Browse files
committed
Support infinite ranges for null class boundaries
1 parent 2320a04 commit 7c1dcfa

File tree

2 files changed

+73
-13
lines changed

2 files changed

+73
-13
lines changed

src/analysis/processing/qgsalgorithmreclassifybylayer.cpp

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,35 @@ QVector<QgsReclassifyUtils::RasterClass> QgsReclassifyByLayerAlgorithm::createCl
226226
while ( mTableIterator.nextFeature( f ) )
227227
{
228228
bool ok = false;
229-
double minValue = f.attribute( mMinFieldIdx ).toDouble( &ok );
230-
if ( !ok )
231-
throw QgsProcessingException( QObject::tr( "Invalid value for minimum: %1" ).arg( f.attribute( mMinFieldIdx ).toString() ) );
232-
double maxValue = f.attribute( mMaxFieldIdx ).toDouble( &ok );
233-
if ( !ok )
234-
throw QgsProcessingException( QObject::tr( "Invalid value for maximum: %1" ).arg( f.attribute( mMaxFieldIdx ).toString() ) );
235-
double value = f.attribute( mValueFieldIdx ).toDouble( &ok );
229+
230+
// null values map to nan, which corresponds to a range extended to +/- infinity....
231+
const QVariant minVariant = f.attribute( mMinFieldIdx );
232+
double minValue;
233+
if ( minVariant.isNull() || minVariant.toString().isEmpty() )
234+
{
235+
minValue = std::numeric_limits<double>::quiet_NaN();
236+
}
237+
else
238+
{
239+
minValue = minVariant.toDouble( &ok );
240+
if ( !ok )
241+
throw QgsProcessingException( QObject::tr( "Invalid value for minimum: %1" ).arg( minVariant.toString() ) );
242+
}
243+
const QVariant maxVariant = f.attribute( mMaxFieldIdx );
244+
double maxValue;
245+
if ( maxVariant.isNull() || maxVariant.toString().isEmpty() )
246+
{
247+
maxValue = std::numeric_limits<double>::quiet_NaN();
248+
ok = true;
249+
}
250+
else
251+
{
252+
maxValue = maxVariant.toDouble( &ok );
253+
if ( !ok )
254+
throw QgsProcessingException( QObject::tr( "Invalid value for maximum: %1" ).arg( maxVariant.toString() ) );
255+
}
256+
257+
const double value = f.attribute( mValueFieldIdx ).toDouble( &ok );
236258
if ( !ok )
237259
throw QgsProcessingException( QObject::tr( "Invalid output value: %1" ).arg( f.attribute( mValueFieldIdx ).toString() ) );
238260

@@ -296,12 +318,34 @@ QVector<QgsReclassifyUtils::RasterClass> QgsReclassifyByTableAlgorithm::createCl
296318
for ( int row = 0; row < rows; ++row )
297319
{
298320
bool ok = false;
299-
const double minValue = table.at( row * 3 ).toDouble( &ok );
300-
if ( !ok )
301-
throw QgsProcessingException( QObject::tr( "Invalid value for minimum: %1" ).arg( table.at( row * 3 ).toString() ) );
302-
const double maxValue = table.at( row * 3 + 1 ).toDouble( &ok );
303-
if ( !ok )
304-
throw QgsProcessingException( QObject::tr( "Invalid value for maximum: %1" ).arg( table.at( row * 3 + 1 ).toString() ) );
321+
322+
// null values map to nan, which corresponds to a range extended to +/- infinity....
323+
const QVariant minVariant = table.at( row * 3 );
324+
double minValue;
325+
if ( minVariant.isNull() || minVariant.toString().isEmpty() )
326+
{
327+
minValue = std::numeric_limits<double>::quiet_NaN();
328+
}
329+
else
330+
{
331+
minValue = minVariant.toDouble( &ok );
332+
if ( !ok )
333+
throw QgsProcessingException( QObject::tr( "Invalid value for minimum: %1" ).arg( table.at( row * 3 ).toString() ) );
334+
}
335+
const QVariant maxVariant = table.at( row * 3 + 1 );
336+
double maxValue;
337+
if ( maxVariant.isNull() || maxVariant.toString().isEmpty() )
338+
{
339+
maxValue = std::numeric_limits<double>::quiet_NaN();
340+
ok = true;
341+
}
342+
else
343+
{
344+
maxValue = maxVariant.toDouble( &ok );
345+
if ( !ok )
346+
throw QgsProcessingException( QObject::tr( "Invalid value for maximum: %1" ).arg( table.at( row * 3 + 1 ).toString() ) );
347+
}
348+
305349
const double value = table.at( row * 3 + 2 ).toDouble( &ok );
306350
if ( !ok )
307351
throw QgsProcessingException( QObject::tr( "Invalid output value: %1" ).arg( table.at( row * 3 + 2 ).toString() ) );

tests/src/analysis/testqgsreclassifyutils.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,22 @@ void TestQgsReclassifyUtils::testReclassify_data()
132132
<< -9999.0 << false << static_cast< int >( Qgis::Float32 )
133133
<< QVector< double > { -7, -7, 3, 8, 8, 6 };
134134

135+
QTest::newRow( "infinite range" ) << QVector< double > { 1, 2, 3, 4, 5, 6 }
136+
<< 3 << 2
137+
<< ( QVector< QgsReclassifyUtils::RasterClass >()
138+
<< QgsReclassifyUtils::RasterClass( 3, std::numeric_limits<double>::quiet_NaN(), QgsRasterRange::IncludeMax, 8 )
139+
<< QgsReclassifyUtils::RasterClass( 1, 3, QgsRasterRange::IncludeMin, -7 ) )
140+
<< -9999.0 << false << static_cast< int >( Qgis::Float32 )
141+
<< QVector< double > { -7, -7, 3, 8, 8, 8 };
142+
143+
QTest::newRow( "infinite range 2" ) << QVector< double > { 1, 2, 3, 4, 5, 6 }
144+
<< 3 << 2
145+
<< ( QVector< QgsReclassifyUtils::RasterClass >()
146+
<< QgsReclassifyUtils::RasterClass( 3, 4, QgsRasterRange::IncludeMax, 8 )
147+
<< QgsReclassifyUtils::RasterClass( std::numeric_limits<double>::quiet_NaN(), 3, QgsRasterRange::IncludeMin, -7 ) )
148+
<< -9999.0 << false << static_cast< int >( Qgis::Float32 )
149+
<< QVector< double > { -7, -7, 3, 8, 5, 6 };
150+
135151
QTest::newRow( "with source no data" ) << QVector< double > { 1, 2, -9999, 4, 5, 6 }
136152
<< 3 << 2
137153
<< ( QVector< QgsReclassifyUtils::RasterClass >()

0 commit comments

Comments
 (0)