Skip to content

Commit f934c5c

Browse files
committed
Add overlaps test to QgsRasterRange
1 parent eec2f47 commit f934c5c

File tree

4 files changed

+255
-0
lines changed

4 files changed

+255
-0
lines changed

python/core/auto_generated/raster/qgsrasterrange.sip.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ Tests if a ``value`` is within the list of ranges
112112
:param rangeList: list of ranges
113113

114114
:return: true if value is in at least one of ranges
115+
%End
116+
117+
bool overlaps( const QgsRasterRange &other ) const;
118+
%Docstring
119+
Returns true if this range overlaps another range.
120+
121+
.. versionadded:: 3.2
115122
%End
116123

117124
};

src/core/raster/qgsrasterrange.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,47 @@ QgsRasterRange::QgsRasterRange( double min, double max, BoundsType bounds )
2424
{
2525
}
2626

27+
bool QgsRasterRange::overlaps( const QgsRasterRange &other ) const
28+
{
29+
bool thisIncludesLower = mType == IncludeMinAndMax || mType == IncludeMin;
30+
bool thisIncludesUpper = mType == IncludeMinAndMax || mType == IncludeMax;
31+
bool thisLowerInfinite = !std::isfinite( mMin );
32+
bool thisUpperInfinite = !std::isfinite( mMax );
33+
bool otherIncludesLower = other.mType == IncludeMinAndMax || other.mType == IncludeMin;
34+
bool otherIncludesUpper = other.mType == IncludeMinAndMax || other.mType == IncludeMax;
35+
bool otherLowerInfinite = !std::isfinite( other.mMin );
36+
bool otherUpperInfinite = !std::isfinite( other.mMax );
37+
38+
if ( ( ( thisIncludesLower && otherIncludesLower && ( mMin <= other.mMin || thisLowerInfinite ) ) ||
39+
( ( !thisIncludesLower || !otherIncludesLower ) && ( mMin < other.mMin || thisLowerInfinite ) ) )
40+
&& ( ( thisIncludesUpper && otherIncludesUpper && ( mMax >= other.mMax || thisUpperInfinite ) ) ||
41+
( ( !thisIncludesUpper || !otherIncludesUpper ) && ( mMax > other.mMax || thisUpperInfinite ) ) ) )
42+
return true;
43+
44+
if ( ( ( otherIncludesLower && ( mMin <= other.mMin || thisLowerInfinite ) ) ||
45+
( !otherIncludesLower && ( mMin < other.mMin || thisLowerInfinite ) ) )
46+
&& ( ( thisIncludesUpper && otherIncludesLower && ( mMax >= other.mMin || thisUpperInfinite ) ) ||
47+
( ( !thisIncludesUpper || !otherIncludesLower ) && ( mMax > other.mMin || thisUpperInfinite ) ) ) )
48+
return true;
49+
50+
if ( ( ( thisIncludesLower && otherIncludesUpper && ( mMin <= other.mMax || thisLowerInfinite ) ) ||
51+
( ( !thisIncludesLower || !otherIncludesUpper ) && ( mMin < other.mMax || thisLowerInfinite ) ) )
52+
&& ( ( thisIncludesUpper && otherIncludesUpper && ( mMax >= other.mMax || thisUpperInfinite ) ) ||
53+
( ( !thisIncludesUpper || !otherIncludesUpper ) && ( mMax > other.mMax || thisUpperInfinite ) ) ) )
54+
return true;
55+
56+
if ( ( ( thisIncludesLower && otherIncludesLower && ( mMin >= other.mMin || otherLowerInfinite ) ) ||
57+
( ( !thisIncludesLower || !otherIncludesLower ) && ( mMin > other.mMin || otherLowerInfinite ) ) )
58+
&& ( ( thisIncludesLower && otherIncludesUpper && ( mMin <= other.mMax || thisLowerInfinite || otherUpperInfinite ) ) ||
59+
( ( !thisIncludesLower || !otherIncludesUpper ) && ( mMin < other.mMax || thisLowerInfinite || otherUpperInfinite ) ) ) )
60+
return true;
61+
62+
if ( qgsDoubleNear( mMin, other.mMin ) && qgsDoubleNear( mMax, other.mMax ) )
63+
return true;
64+
65+
return false;
66+
}
67+
2768

2869

2970

src/core/raster/qgsrasterrange.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ class CORE_EXPORT QgsRasterRange
140140
return false;
141141
}
142142

143+
/**
144+
* Returns true if this range overlaps another range.
145+
* \since QGIS 3.2
146+
*/
147+
bool overlaps( const QgsRasterRange &other ) const;
148+
143149
private:
144150
double mMin = std::numeric_limits<double>::quiet_NaN();
145151
double mMax = std::numeric_limits<double>::quiet_NaN();

tests/src/python/test_qgsrasterrange.py

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,207 @@ def testContainsList(self):
119119
self.assertTrue(QgsRasterRange.contains(13, ranges))
120120
self.assertFalse(QgsRasterRange.contains(16, ranges))
121121

122+
def testOverlaps(self):
123+
# includes both ends
124+
range = QgsRasterRange(0, 10, QgsRasterRange.IncludeMinAndMax)
125+
self.assertTrue(range.overlaps(QgsRasterRange(1, 9)))
126+
self.assertTrue(range.overlaps(QgsRasterRange(1, 10)))
127+
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
128+
self.assertTrue(range.overlaps(QgsRasterRange(0, 9)))
129+
self.assertTrue(range.overlaps(QgsRasterRange(0, 10)))
130+
self.assertTrue(range.overlaps(QgsRasterRange(0, 11)))
131+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 10)))
132+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 9)))
133+
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
134+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 11)))
135+
self.assertTrue(range.overlaps(QgsRasterRange(10, 11)))
136+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0)))
137+
self.assertFalse(range.overlaps(QgsRasterRange(-10, -1)))
138+
self.assertFalse(range.overlaps(QgsRasterRange(11, 12)))
139+
self.assertTrue(range.overlaps(QgsRasterRange(-1, float('NaN'))))
140+
self.assertTrue(range.overlaps(QgsRasterRange(0, float('NaN'))))
141+
self.assertTrue(range.overlaps(QgsRasterRange(1, float('NaN'))))
142+
self.assertTrue(range.overlaps(QgsRasterRange(10, float('NaN'))))
143+
self.assertFalse(range.overlaps(QgsRasterRange(11, float('NaN'))))
144+
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), -1)))
145+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 0)))
146+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 1)))
147+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 10)))
148+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 11)))
149+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), float('NaN'))))
150+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.Exclusive)))
151+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMin)))
152+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMax)))
153+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.Exclusive)))
154+
self.assertTrue(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMin)))
155+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMax)))
156+
157+
range = QgsRasterRange(float('NaN'), 10, QgsRasterRange.IncludeMinAndMax)
158+
self.assertTrue(range.overlaps(QgsRasterRange(1, 9)))
159+
self.assertTrue(range.overlaps(QgsRasterRange(1, 10)))
160+
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
161+
self.assertTrue(range.overlaps(QgsRasterRange(0, 9)))
162+
self.assertTrue(range.overlaps(QgsRasterRange(0, 10)))
163+
self.assertTrue(range.overlaps(QgsRasterRange(0, 11)))
164+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 10)))
165+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 9)))
166+
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
167+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 11)))
168+
self.assertTrue(range.overlaps(QgsRasterRange(10, 11)))
169+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0)))
170+
self.assertTrue(range.overlaps(QgsRasterRange(-10, -1)))
171+
self.assertFalse(range.overlaps(QgsRasterRange(11, 12)))
172+
self.assertTrue(range.overlaps(QgsRasterRange(-1, float('NaN'))))
173+
self.assertTrue(range.overlaps(QgsRasterRange(0, float('NaN'))))
174+
self.assertTrue(range.overlaps(QgsRasterRange(1, float('NaN'))))
175+
self.assertTrue(range.overlaps(QgsRasterRange(10, float('NaN'))))
176+
self.assertFalse(range.overlaps(QgsRasterRange(11, float('NaN'))))
177+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), -1)))
178+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 0)))
179+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 1)))
180+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 10)))
181+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 11)))
182+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), float('NaN'))))
183+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.Exclusive)))
184+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMin)))
185+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMax)))
186+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.Exclusive)))
187+
self.assertTrue(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMin)))
188+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMax)))
189+
190+
range = QgsRasterRange(0, float('NaN'), QgsRasterRange.IncludeMinAndMax)
191+
self.assertTrue(range.overlaps(QgsRasterRange(1, 9)))
192+
self.assertTrue(range.overlaps(QgsRasterRange(1, 10)))
193+
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
194+
self.assertTrue(range.overlaps(QgsRasterRange(0, 9)))
195+
self.assertTrue(range.overlaps(QgsRasterRange(0, 10)))
196+
self.assertTrue(range.overlaps(QgsRasterRange(0, 11)))
197+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 10)))
198+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 9)))
199+
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
200+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 11)))
201+
self.assertTrue(range.overlaps(QgsRasterRange(10, 11)))
202+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0)))
203+
self.assertFalse(range.overlaps(QgsRasterRange(-10, -1)))
204+
self.assertTrue(range.overlaps(QgsRasterRange(11, 12)))
205+
self.assertTrue(range.overlaps(QgsRasterRange(-1, float('NaN'))))
206+
self.assertTrue(range.overlaps(QgsRasterRange(0, float('NaN'))))
207+
self.assertTrue(range.overlaps(QgsRasterRange(1, float('NaN'))))
208+
self.assertTrue(range.overlaps(QgsRasterRange(10, float('NaN'))))
209+
self.assertTrue(range.overlaps(QgsRasterRange(11, float('NaN'))))
210+
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), -1)))
211+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 0)))
212+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 1)))
213+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 10)))
214+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 11)))
215+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), float('NaN'))))
216+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.Exclusive)))
217+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMin)))
218+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMax)))
219+
self.assertTrue(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.Exclusive)))
220+
self.assertTrue(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMin)))
221+
self.assertTrue(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMax)))
222+
223+
# includes left end
224+
range = QgsRasterRange(0, 10, QgsRasterRange.IncludeMin)
225+
self.assertTrue(range.overlaps(QgsRasterRange(1, 9)))
226+
self.assertTrue(range.overlaps(QgsRasterRange(1, 10)))
227+
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
228+
self.assertTrue(range.overlaps(QgsRasterRange(0, 9)))
229+
self.assertTrue(range.overlaps(QgsRasterRange(0, 10)))
230+
self.assertTrue(range.overlaps(QgsRasterRange(0, 11)))
231+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 10)))
232+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 9)))
233+
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
234+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 11)))
235+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11)))
236+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0)))
237+
self.assertFalse(range.overlaps(QgsRasterRange(-10, -1)))
238+
self.assertFalse(range.overlaps(QgsRasterRange(11, 12)))
239+
self.assertTrue(range.overlaps(QgsRasterRange(-1, float('NaN'))))
240+
self.assertTrue(range.overlaps(QgsRasterRange(0, float('NaN'))))
241+
self.assertTrue(range.overlaps(QgsRasterRange(1, float('NaN'))))
242+
self.assertFalse(range.overlaps(QgsRasterRange(10, float('NaN'))))
243+
self.assertFalse(range.overlaps(QgsRasterRange(11, float('NaN'))))
244+
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), -1)))
245+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 0)))
246+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 1)))
247+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 10)))
248+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 11)))
249+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), float('NaN'))))
250+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.Exclusive)))
251+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMin)))
252+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMax)))
253+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.Exclusive)))
254+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMin)))
255+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMax)))
256+
257+
# includes right end
258+
range = QgsRasterRange(0, 10, QgsRasterRange.IncludeMax)
259+
self.assertTrue(range.overlaps(QgsRasterRange(1, 9)))
260+
self.assertTrue(range.overlaps(QgsRasterRange(1, 10)))
261+
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
262+
self.assertTrue(range.overlaps(QgsRasterRange(0, 9)))
263+
self.assertTrue(range.overlaps(QgsRasterRange(0, 10)))
264+
self.assertTrue(range.overlaps(QgsRasterRange(0, 11)))
265+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 10)))
266+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 9)))
267+
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
268+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 11)))
269+
self.assertTrue(range.overlaps(QgsRasterRange(10, 11)))
270+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0)))
271+
self.assertFalse(range.overlaps(QgsRasterRange(-10, -1)))
272+
self.assertFalse(range.overlaps(QgsRasterRange(11, 12)))
273+
self.assertTrue(range.overlaps(QgsRasterRange(-1, float('NaN'))))
274+
self.assertTrue(range.overlaps(QgsRasterRange(0, 50)))
275+
self.assertTrue(range.overlaps(QgsRasterRange(1, float('NaN'))))
276+
self.assertTrue(range.overlaps(QgsRasterRange(10, float('NaN'))))
277+
self.assertFalse(range.overlaps(QgsRasterRange(11, float('NaN'))))
278+
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), -1)))
279+
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), 0)))
280+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 1)))
281+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 10)))
282+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 11)))
283+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), float('NaN'))))
284+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.Exclusive)))
285+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMin)))
286+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMax)))
287+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.Exclusive)))
288+
self.assertTrue(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMin)))
289+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMax)))
290+
291+
# includes neither end
292+
range = QgsRasterRange(0, 10, QgsRasterRange.Exclusive)
293+
self.assertTrue(range.overlaps(QgsRasterRange(1, 9)))
294+
self.assertTrue(range.overlaps(QgsRasterRange(1, 10)))
295+
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
296+
self.assertTrue(range.overlaps(QgsRasterRange(0, 9)))
297+
self.assertTrue(range.overlaps(QgsRasterRange(0, 10)))
298+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 10)))
299+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 9)))
300+
self.assertTrue(range.overlaps(QgsRasterRange(1, 11)))
301+
self.assertTrue(range.overlaps(QgsRasterRange(-1, 11)))
302+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11)))
303+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0)))
304+
self.assertFalse(range.overlaps(QgsRasterRange(-10, -1)))
305+
self.assertFalse(range.overlaps(QgsRasterRange(11, 12)))
306+
self.assertTrue(range.overlaps(QgsRasterRange(-1, float('NaN'))))
307+
self.assertTrue(range.overlaps(QgsRasterRange(1, float('NaN'))))
308+
self.assertFalse(range.overlaps(QgsRasterRange(10, float('NaN'))))
309+
self.assertFalse(range.overlaps(QgsRasterRange(11, float('NaN'))))
310+
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), -1)))
311+
self.assertFalse(range.overlaps(QgsRasterRange(float('NaN'), 0)))
312+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 1)))
313+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 10)))
314+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), 11)))
315+
self.assertTrue(range.overlaps(QgsRasterRange(float('NaN'), float('NaN'))))
316+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.Exclusive)))
317+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMin)))
318+
self.assertFalse(range.overlaps(QgsRasterRange(-1, 0, QgsRasterRange.IncludeMax)))
319+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.Exclusive)))
320+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMin)))
321+
self.assertFalse(range.overlaps(QgsRasterRange(10, 11, QgsRasterRange.IncludeMax)))
322+
122323

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

0 commit comments

Comments
 (0)