You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
rasterize(like=...) silently produces spatially wrong output when the template like DataArray has a descending x-axis (largest x first, smallest last).
The comment at xrspatial/rasterize.py:2936 says "descending-x templates would hit the same bug class and are not supported here," but the code neither rejects descending-x nor flips columns to compensate. _extract_grid_from_like notes the issue and moves on.
Ascending y is already handled at line 3349-3350: the burned array is flipped along axis 0 so result.sel(y=...) lines up with the geometry in world coordinates. There's no equivalent for x.
When a descending-x like is passed, the rasterizer writes pixels using ascending-x column order (column 0 = xmin), but reuse_like_coords at line 3340 assigns the descending-x coord array unchanged. A polygon at world x=0.5 ends up labelled under coord x=3.5.
Expected behavior
result.sel(x=world_x) should return the burned value at world_x regardless of whether like.x is ascending or descending. Either flip the output along axis 1 to match the coords, or reject descending-x with a clear ValueError (the existing comment already claims it is unsupported).
Reproducer
importnumpyasnpimportxarrayasxrfromshapely.geometryimportboxfromxrspatial.rasterizeimportrasterize# Descending-x like gridx_desc=np.linspace(3.5, 0.5, 4) # descendingy=np.linspace(3.5, 0.5, 4)
like=xr.DataArray(
np.zeros((4, 4)), dims=['y', 'x'], coords={'y': y, 'x': x_desc},
)
# Burn a 1x1 box at world (0.5, 0.5) -- the lower-left cornerresult=rasterize([(box(0, 0, 1, 1), 1.0)], like=like, fill=0)
# Expected: result.sel(x=0.5, y=0.5).item() == 1.0# Actual: result.sel(x=0.5, y=0.5).item() == 0.0# result.sel(x=3.5, y=0.5).item() == 1.0 (mislabelled)
Impact
Any coord-aware downstream op (xr.align, .sel, slope/aspect, zonal stats keyed off coords) operates on the wrong cells. The output looks plausible but is spatially wrong. No exception is raised.
Fix should be small and local: detect descending-x in _extract_grid_from_like, carry it on _LikeGrid, and flip axis 1 in rasterize when reusing coords. Or reject with ValueError.
Worth confirming descending-y is genuinely covered by the existing y-flip path while you're in there.
Describe the bug
rasterize(like=...)silently produces spatially wrong output when the templatelikeDataArray has a descending x-axis (largest x first, smallest last).The comment at
xrspatial/rasterize.py:2936says "descending-x templates would hit the same bug class and are not supported here," but the code neither rejects descending-x nor flips columns to compensate._extract_grid_from_likenotes the issue and moves on.Ascending y is already handled at line 3349-3350: the burned array is flipped along axis 0 so
result.sel(y=...)lines up with the geometry in world coordinates. There's no equivalent for x.When a descending-x
likeis passed, the rasterizer writes pixels using ascending-x column order (column 0 = xmin), butreuse_like_coordsat line 3340 assigns the descending-x coord array unchanged. A polygon at world x=0.5 ends up labelled under coord x=3.5.Expected behavior
result.sel(x=world_x)should return the burned value atworld_xregardless of whetherlike.xis ascending or descending. Either flip the output along axis 1 to match the coords, or reject descending-x with a clearValueError(the existing comment already claims it is unsupported).Reproducer
Impact
Any coord-aware downstream op (
xr.align,.sel, slope/aspect, zonal stats keyed off coords) operates on the wrong cells. The output looks plausible but is spatially wrong. No exception is raised.Additional context
_extract_grid_from_like, carry it on_LikeGrid, and flip axis 1 inrasterizewhen reusing coords. Or reject withValueError.