Navigation Menu

Skip to content

Commit

Permalink
Add overlaps test to QgsRasterRange
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jun 13, 2018
1 parent eec2f47 commit f934c5c
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 0 deletions.
7 changes: 7 additions & 0 deletions python/core/auto_generated/raster/qgsrasterrange.sip.in
Expand Up @@ -112,6 +112,13 @@ Tests if a ``value`` is within the list of ranges
:param rangeList: list of ranges

:return: true if value is in at least one of ranges
%End

bool overlaps( const QgsRasterRange &other ) const;
%Docstring
Returns true if this range overlaps another range.

.. versionadded:: 3.2
%End

};
Expand Down
41 changes: 41 additions & 0 deletions src/core/raster/qgsrasterrange.cpp
Expand Up @@ -24,6 +24,47 @@ QgsRasterRange::QgsRasterRange( double min, double max, BoundsType bounds )
{
}

bool QgsRasterRange::overlaps( const QgsRasterRange &other ) const
{
bool thisIncludesLower = mType == IncludeMinAndMax || mType == IncludeMin;
bool thisIncludesUpper = mType == IncludeMinAndMax || mType == IncludeMax;
bool thisLowerInfinite = !std::isfinite( mMin );
bool thisUpperInfinite = !std::isfinite( mMax );
bool otherIncludesLower = other.mType == IncludeMinAndMax || other.mType == IncludeMin;
bool otherIncludesUpper = other.mType == IncludeMinAndMax || other.mType == IncludeMax;
bool otherLowerInfinite = !std::isfinite( other.mMin );
bool otherUpperInfinite = !std::isfinite( other.mMax );

if ( ( ( thisIncludesLower && otherIncludesLower && ( mMin <= other.mMin || thisLowerInfinite ) ) ||
( ( !thisIncludesLower || !otherIncludesLower ) && ( mMin < other.mMin || thisLowerInfinite ) ) )
&& ( ( thisIncludesUpper && otherIncludesUpper && ( mMax >= other.mMax || thisUpperInfinite ) ) ||
( ( !thisIncludesUpper || !otherIncludesUpper ) && ( mMax > other.mMax || thisUpperInfinite ) ) ) )
return true;

if ( ( ( otherIncludesLower && ( mMin <= other.mMin || thisLowerInfinite ) ) ||
( !otherIncludesLower && ( mMin < other.mMin || thisLowerInfinite ) ) )
&& ( ( thisIncludesUpper && otherIncludesLower && ( mMax >= other.mMin || thisUpperInfinite ) ) ||
( ( !thisIncludesUpper || !otherIncludesLower ) && ( mMax > other.mMin || thisUpperInfinite ) ) ) )
return true;

if ( ( ( thisIncludesLower && otherIncludesUpper && ( mMin <= other.mMax || thisLowerInfinite ) ) ||
( ( !thisIncludesLower || !otherIncludesUpper ) && ( mMin < other.mMax || thisLowerInfinite ) ) )
&& ( ( thisIncludesUpper && otherIncludesUpper && ( mMax >= other.mMax || thisUpperInfinite ) ) ||
( ( !thisIncludesUpper || !otherIncludesUpper ) && ( mMax > other.mMax || thisUpperInfinite ) ) ) )
return true;

if ( ( ( thisIncludesLower && otherIncludesLower && ( mMin >= other.mMin || otherLowerInfinite ) ) ||
( ( !thisIncludesLower || !otherIncludesLower ) && ( mMin > other.mMin || otherLowerInfinite ) ) )
&& ( ( thisIncludesLower && otherIncludesUpper && ( mMin <= other.mMax || thisLowerInfinite || otherUpperInfinite ) ) ||
( ( !thisIncludesLower || !otherIncludesUpper ) && ( mMin < other.mMax || thisLowerInfinite || otherUpperInfinite ) ) ) )
return true;

if ( qgsDoubleNear( mMin, other.mMin ) && qgsDoubleNear( mMax, other.mMax ) )
return true;

return false;
}




Expand Down
6 changes: 6 additions & 0 deletions src/core/raster/qgsrasterrange.h
Expand Up @@ -140,6 +140,12 @@ class CORE_EXPORT QgsRasterRange
return false;
}

/**
* Returns true if this range overlaps another range.
* \since QGIS 3.2
*/
bool overlaps( const QgsRasterRange &other ) const;

private:
double mMin = std::numeric_limits<double>::quiet_NaN();
double mMax = std::numeric_limits<double>::quiet_NaN();
Expand Down
201 changes: 201 additions & 0 deletions tests/src/python/test_qgsrasterrange.py
Expand Up @@ -119,6 +119,207 @@ def testContainsList(self):
self.assertTrue(QgsRasterRange.contains(13, ranges))
self.assertFalse(QgsRasterRange.contains(16, ranges))

def testOverlaps(self):
# includes both ends
range = QgsRasterRange(0, 10, QgsRasterRange.IncludeMinAndMax)
self.assertTrue(range.overlaps(QgsRasterRange(1, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(10, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0)))
self.assertFalse(range.overlaps(QgsRasterRange(-10, -1)))
self.assertFalse(range.overlaps(QgsRasterRange(11, 12)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(0, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(1, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(10, float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(11, float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), -1)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 0)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 1)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 10)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 11)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.Exclusive)))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMin)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMax)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.Exclusive)))
self.assertTrue(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMin)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMax)))

range = QgsRasterRange(float('NaN'), 10, QgsRasterRange.IncludeMinAndMax)
self.assertTrue(range.overlaps(QgsRasterRange(1, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(10, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0)))
self.assertTrue(range.overlaps(QgsRasterRange(-10, -1)))
self.assertFalse(range.overlaps(QgsRasterRange(11, 12)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(0, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(1, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(10, float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(11, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), -1)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 0)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 1)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 10)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 11)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.Exclusive)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMin)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMax)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.Exclusive)))
self.assertTrue(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMin)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMax)))

range = QgsRasterRange(0, float('NaN'), QgsRasterRange.IncludeMinAndMax)
self.assertTrue(range.overlaps(QgsRasterRange(1, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(10, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0)))
self.assertFalse(range.overlaps(QgsRasterRange(-10, -1)))
self.assertTrue(range.overlaps(QgsRasterRange(11, 12)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(0, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(1, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(10, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(11, float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), -1)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 0)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 1)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 10)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 11)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.Exclusive)))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMin)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMax)))
self.assertTrue(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.Exclusive)))
self.assertTrue(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMin)))
self.assertTrue(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMax)))

# includes left end
range = QgsRasterRange(0, 10, QgsRasterRange.IncludeMin)
self.assertTrue(range.overlaps(QgsRasterRange(1, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 11)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0)))
self.assertFalse(range.overlaps(QgsRasterRange(-10, -1)))
self.assertFalse(range.overlaps(QgsRasterRange(11, 12)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(0, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(1, float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(10, float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(11, float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), -1)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 0)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 1)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 10)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 11)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.Exclusive)))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMin)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMax)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.Exclusive)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMin)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMax)))

# includes right end
range = QgsRasterRange(0, 10, QgsRasterRange.IncludeMax)
self.assertTrue(range.overlaps(QgsRasterRange(1, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(10, 11)))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0)))
self.assertFalse(range.overlaps(QgsRasterRange(-10, -1)))
self.assertFalse(range.overlaps(QgsRasterRange(11, 12)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(0, 50)))
self.assertTrue(range.overlaps(QgsRasterRange(1, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(10, float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(11, float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), -1)))
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), 0)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 1)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 10)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 11)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.Exclusive)))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMin)))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMax)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.Exclusive)))
self.assertTrue(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMin)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMax)))

# includes neither end
range = QgsRasterRange(0, 10, QgsRasterRange.Exclusive)
self.assertTrue(range.overlaps(QgsRasterRange(1, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(0, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 10)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 9)))
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, 11)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11)))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0)))
self.assertFalse(range.overlaps(QgsRasterRange(-10, -1)))
self.assertFalse(range.overlaps(QgsRasterRange(11, 12)))
self.assertTrue(range.overlaps(QgsRasterRange(-1, float('NaN'))))
self.assertTrue(range.overlaps(QgsRasterRange(1, float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(10, float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(11, float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), -1)))
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), 0)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 1)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 10)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 11)))
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), float('NaN'))))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.Exclusive)))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMin)))
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMax)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.Exclusive)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMin)))
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMax)))


if __name__ == '__main__':
unittest.main()

0 comments on commit f934c5c

Please sign in to comment.