@@ -212,6 +212,12 @@ def test_nearest_negative_rounding(self):
212212 assert result2 [0 , 0 ] == src [0 , 1 ], (
213213 f"r=-0.4 should map to pixel 0, got { result2 [0 , 0 ]} "
214214 )
215+ # r = -0.5 is exactly on the half-pixel boundary: floor(-0.5+0.5)=0 -> pixel 0
216+ rows3 = np .array ([[- 0.5 ]])
217+ result3 = _resample_numpy (src , rows3 , cols , resampling = 'nearest' , nodata = - 999 )
218+ assert result3 [0 , 0 ] == src [0 , 1 ], (
219+ f"r=-0.5 should map to pixel 0, got { result3 [0 , 0 ]} "
220+ )
215221
216222 def test_cubic_oob_fallback (self ):
217223 """Cubic must fall back to bilinear when stencil extends outside source (#1086)."""
@@ -238,6 +244,17 @@ def test_cubic_oob_fallback(self):
238244 # but the point is the code path exercises the non-fallback branch
239245 assert cubic_int [0 , 0 ] != - 999
240246
247+ def test_cubic_oob_fallback_far_edge (self ):
248+ """Cubic at bottom-right boundary: stencil needs row sh, same fallback (#1086)."""
249+ from xrspatial .reproject ._interpolate import _resample_numpy
250+ src = np .arange (36 , dtype = np .float64 ).reshape (6 , 6 )
251+ # r=4.5: cubic stencil needs row 6 (= sh), which is OOB
252+ rows = np .array ([[4.5 ]])
253+ cols = np .array ([[4.5 ]])
254+ cubic = _resample_numpy (src , rows , cols , resampling = 'cubic' , nodata = - 999 )
255+ bilinear = _resample_numpy (src , rows , cols , resampling = 'bilinear' , nodata = - 999 )
256+ np .testing .assert_allclose (cubic , bilinear , atol = 1e-10 )
257+
241258 def test_cubic_oob_bilinear_fallback_renormalizes (self ):
242259 """Cubic at (-0.8,-0.8): stencil OOB triggers bilinear, which
243260 finds pixel (0,0) as the only valid neighbor and returns it (#1086)."""
0 commit comments