[GIS] Iterating over a raster using rasterio, and then saving to a shapefile

pythonrasterrasterio

I'm trying to create a script to polygonalize a raster using rasterio. I want to only polygonalize pixel values that are not null.

From this SO answer, I derived this function:

def create_geometry(raster_input):
"""
Creates a shapely polygon from a raster image
:param raster_input: raster path
:return: shapely geometry
"""
mask = None
results = None
pixels = []

# with rasterio.drivers():
with rasterio.open(raster_input) as src:
    image = src.read(1)  # first band
    results = (
        {'properties': {'raster_val': v}, 'geometry': s}
        for i, (s, v)
        in enumerate(
        shapes(image, mask=mask, transform=src.affine)))
return results

That function is called by this function, which then saves to shapefile using the polygonalize_geometry() function:

def shape_builder(raster_input, output_path):
"Builds a polygon out of the pixel polygons"

# polygons = []
polygons = create_geometry(raster_input)

for polygon in polygons:
    polygon = shape(polygon[0]['geometry'])
    print(polygon)
    polygonalize_geometry(polygon, output_path)

I then convert it into shapely geometry, and then write a shapefile. However, the shapefile only contains one feature that encompasses one pixel (shown below). I believe that it is only operating on the first pixel it finds. The SO answer I linked above says that the function is a generator, but I haven't ever been able to figure out how to use them. I'm pretty sure that's the issue.

enter image description here

So the script is somewhat working.

The entire script is here.

Where did I go wrong?

Best Answer

Ross, I think the only thing that is wrong is that you're re-opening the shapefile in 'w' mode in polygonalize_geometry() for every shape. 'w' doesn't mean "append to shapefile", it means "overwrite shapefile". Try Python's open() in 'w' mode, for example, fiona.open() has exactly the same behavior. Change your program so that the output vector collection is opened only once and you'll be back on track.

Related Question