python-rasterstats icon indicating copy to clipboard operation
python-rasterstats copied to clipboard

Non-standard affine transforms handled incorrectly

Open perrygeo opened this issue 10 years ago • 8 comments

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

perrygeo avatar Sep 16 '15 20:09 perrygeo

Is this what could be causing 'ValueError: negative dimensions are not allowed' in zonal_stats(vector, raster, categorical=True)?

kmoses45 avatar Dec 19 '15 14:12 kmoses45

Possibly. Try rio info on the raster and check the transform.

perrygeo avatar Dec 19 '15 14:12 perrygeo

"transform":[1.0, 0.0, 0.0, 0.0, 1.0, 0.0] Both vector and raster are in EPSG:4326

kmoses45 avatar Dec 19 '15 15:12 kmoses45

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)

perrygeo avatar Dec 19 '15 16:12 perrygeo

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!

kmoses45 avatar Dec 20 '15 00:12 kmoses45

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?

pierstitus avatar Mar 09 '19 02:03 pierstitus

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

raybellwaves avatar Sep 19 '21 02:09 raybellwaves