I have a script that does some geoprocessing, that makes sense in a test run, but when I actually try to use it with my actual dataset, appears to totally overload my computer with memory needs, and I am very confused about about to actually fix this. I am using the rasterio
and geocube
packages.
I have a polygons shapefile here called polygons. This shapefile has three columns with unique values: Blue
, Red
, Green
, and test
. I want to, for each of these columns, rasterize each polygon, and then sum. So I would then have a raster of all Blue
values summed, and then of all Red
values summed, and of all Green
values summed, and then of all test
values summed. I then want to divide each of the summed color rasters by the summed test raster. to produce a final Blue, Red, and Green raster output. Here is my code:
list = ['Blue', 'Red', 'Green', `test']
for i in list:
polygons = gpd.read_file('Colors/Polygons.shp')
polygon_IDs = polygons['Polygon_ID'].tolist()
# Make a GeoJSON string of the bounding box feature
bbox = gpd.GeoSeries(box(*polygons.total_bounds), crs=polygons.crs)
geom = bbox.__geo_interface__["features"][0]["geometry"]
# Add CRS
geom["crs"] = {"properties": {"name": f"EPSG:{polygons.crs.to_epsg()}"}}
cubes = []
for j in polygon_IDs:
x = polygons.loc[polygons['Polygon_ID'] == j]
vector_fn = x
out_grid = make_geocube(
vector_data=vector_fn,
measurements=[i],
resolution=(-25, 25),
fill=0,
geom=json.dumps(geom)
)
cubes.append(out_grid)
out_grid = sum(cubes)
out_grid[i].rio.to_raster(f"Colors/Output_Raster_{i}.tif", dtype=out_grid[i].dtype)
d = ['Blue', 'Red', 'Green']
test = 'Colors/Output_Raster_test.tif'
folder = Path('Colors')
src = rasterio.open(test)
for f in folder.glob("*.tif"):
if any(color in f.name for color in d):
med = rasterio.open(f)
new_raster = med.read(1)/src.read(1)
# write raster
profile = src.profile
profile.update(
dtype=new_raster.dtype,
count=1,
compress='lzw')
with rasterio.open(f"Colors/Output_Raster_{f.name}.tif", 'w', **profile) as dst:
dst.write(new_raster, 1)
However, when I run this code I received this error: MemoryError: Unable to allocate 5.96 GiB for an array with shape (25631, 31233) and data type float64
I then delete files to make space and then receive this error: CPLE_OutOfMemoryError: memdataset.cpp, 1513: cannot allocate 1x6404264184 bytes
I am guessing this means that my code is just to intensive to run smoothly and just requires too much memory. But I am not sure which part is using up all of the memory. I am guessing it probably has to do with all of the raster summing, but I am not sure. Would anyone perhaps know how I might alter my code so that it will not require so much memory or what steps I might be going wrong in?
list = ['Blue', 'Red', 'Green', test']
and down toout_grid[i].rio.to_raster(f"Colors/Output_Raster_{i}.tif", dtype=out_grid[i].dtype)
just to see if those rasters actually would get made. They did not. After a good 10 or so minutes running, nothing happened, and eventually the memory just ran out again and I am left with no output rasters and this error message:CPLE_OutOfMemoryError: memdataset.cpp, 1513: cannot allocate 1x6404264184 bytes
. I would like to use windows, but I'm not sure if they work withgeocube
.