I think I have experienced this issue before. The key detail is that rasterio.features.shapes
needs to know about the "transform" of the raster dataset. (The "transform" is how it maps the pixels in the array to the actual coordinates.)
The dataset has a .transform
property that you can pass to rasterio.features.shapes
, as in this example from the rasterio documentation (where src
is the dataset):
shapes = features.shapes(blue, mask=mask, transform=src.transform)
I don't think I see the name of your dataset variable in your post, so I can't suggest the exact code you need.
This is a shapely problem in the creation of MultiPolygons. See Why is a MultiPolygon of a MultiPolygon smaller than its input? for example:
The constructor of MultiPolygon calls the function
geos_multipolygon_from_polygons which performs following check:
# This function does not accept sequences of MultiPolygons: there is
# no implicit flattening.
if isinstance(obs[0], MultiPolygon):
raise ValueError("Sequences of multi-polygons are not valid arguments")
import geopandas as gpd
gdf = gpd.read_file('polygons.shp')
gdf.geometry
0 POLYGON ((251828.453 139390.562, 251854.391 13...
1 MULTIPOLYGON (((257510.859 138175.375, 257428....
2 POLYGON ((257397.594 138708.062, 257397.031 13...
3 MULTIPOLYGON (((251627.188 144678.219, 251608....
Name: geometry, dtype: geometry
Reproduction of the error:
a = gdf.iloc[0:3]
a.geometry
0 POLYGON ((251828.453 139390.562, 251854.391 13...
1 MULTIPOLYGON (((257510.859 138175.375, 257428....
2 POLYGON ((257397.594 138708.062, 257397.031 13...
Name: geometry, dtype: geometry
MultiPolygon((a.geometry.tolist())).bounds
(247965.21875, 138174.9375, 258014.09375, 141038.390625)
# but
b = gdf.iloc[1:4]
b.geometry
1 MULTIPOLYGON (((257510.859 138175.375, 257428....
2 POLYGON ((257397.594 138708.062, 257397.031 13...
3 MULTIPOLYGON (((251627.188 144678.219, 251608....
Name: geometry, dtype: geometry
MultiPolygon((b.geometry.tolist())).bounds
Traceback (most recent call last):
......
raise ValueError("Sequences of multi-polygons are not valid arguments")
ValueError: Sequences of multi-polygons are not valid arguments
To get the extent of the shapefile/GeoDataFrame (all polygons), use total_bounds
xmin,ymin,xmax,ymax = a.total_bounds
print(xmin,ymin,xmax,ymax)
247965.21875 138174.9375 258014.09375 141038.390625
# and
xmin,ymin,xmax,ymax = b.total_bounds
print(xmin,ymin,xmax,ymax)
242520.0625 138175.0 258014.09375 146067.203125
xmin,ymin,xmax,ymax = gdf.total_bounds
print(xmin,ymin,xmax,ymax)
242520.0625, 138174.9375, 258014.09375, 146067.203125
Or unary_union
a.geometry.unary_union.bounds
(247965.21875, 138174.9375, 258014.09375, 141038.390625)
b.geometry.unary_union.bounds
(242520.0625, 138175.0, 258014.09375, 146067.203125)
gdf.geometry.unary_union.bounds
(242520.0625, 138174.9375, 258014.09375, 146067.203125)
New
The problem is the creation of a Multipolygon with your data, so don't use it (I don't use it in my solutions)
MultiPolygon((b['geometry'].tolist())).total_bounds
Traceback (most recent call last):
.........
ValueError: Sequences of multi-polygons are not valid arguments
b['geometry'].tolist().total_bounds
Traceback (most recent call last):
........
AttributeError: 'list' object has no attribute 'total_bounds'
b['geometry'].total_bounds
array([242520.0625, 138175.0., 258014.0937,146067.203125])
b.total_bounds
array([242520.0625, 138175.0, 258014.09375 , 146067.203125])
Best Answer
You can try to escaping the dollar sign.
If that doesn't work you can try this