Non-standard affine transforms handled incorrectly
If you have a dataset with inverted y axis (i.e. the affine.e parameter is positive) a lot of assumptions are broken since North is no longer "up".
The bounds_window must return row_start < row_stop due to rasterio design. So why not internally convert to north-up on read? The window_bounds functions always return w,s,e,n and we'd just need a few conditionals to ensure new_array was a north-up array.
Work started in the southup branch
Is this what could be causing 'ValueError: negative dimensions are not allowed' in zonal_stats(vector, raster, categorical=True)?
Possibly. Try rio info on the raster and check the transform.
"transform":[1.0, 0.0, 0.0, 0.0, 1.0, 0.0] Both vector and raster are in EPSG:4326
With that transform, it's likely that your data lacks georeferencing according to rasterio/GDAL. That's the identity transform and is unlikely the true transform for your data unless you have exactly 1 degree cells with the upper left corner at lat 0, lon 0.
EDIT: To your original question re: ValueError: negative dimensions are not allowed - yes that is currently the behavior when the y axis is inverted (i.e. the 5th element of the transform is positive)
Ah, that's it! I was using an .ovr file that was georeferenced in Arc. Converted to .tif, georeferenced, and now it works. Thanks for the help. Rasterstats is an awesome module!
Good to see you know about this problem, it took me a while to find this issue.
It would be nice to do a little check on affine and give a warning when e is positive (or a is negative, even though that's way less common)
For those working with ndarrays, here a little function to flip the raster and affine matrix (assuming coordinates are on center of grid cells):
def flipud(raster, affine):
raster = np.flipud(raster)
affine = Affine(affine.a, affine.b, affine.c,
affine.d, -1 * affine.e, affine.f + (affine.e * (data.shape[0]-1))
return raster, affine
Thanks for the good work!
Would you like me to work on this issue?
FYI the above function has a couple typos (missing a bracket and data not defined). here's the fixed version:
def flipud(raster, affine):
raster = np.flipud(raster)
affine = Affine(
affine.a,
affine.b,
affine.c,
affine.d,
-1 * affine.e,
affine.f + (affine.e * (raster.shape[0] - 1)),
)
return raster, affine