4

I use rasterio.features.shapes and use the geometry of pixels in raster data to create polygons for each pixel. Pixels with the same value merge these pixels if they are adjacent.

What I want is for each pixel to be in the form of separate polygons. How can I do it?

import rasterio
from rasterio.features import shapes
mask = None
with rasterio.Env():
    with rasterio.open(r"C:\Users\Lenovo\Desktop\clipped.tiff") as src:
        image = src.read(1) # first band
        results = (
        {'properties': {'raster_val': v}, 'geometry': s}
        for i, (s, v) 
        in enumerate(
            shapes(image, transform=src.transform)))
            
geoms = list(results)

The result (the red area is the combination of two same value pixels):
)

Expected result (separate polygons for all pixels):
expected result (separate polygons for all pixels)

5

1 Answer 1

7

When two adjacent pixels have the same value they are dissolved into one.

You can:

  1. add a random float value between 0-0.9999 to each pixel value to make all pixel values unique,

  2. vectorize

  3. then floor them back to the original values:

    import rasterio
    from rasterio.features import shapes
    import numpy as np
    import geopandas as gpd
    
    file = r"C:\GIS\data\testdata\random_uint16.tif"
    
    mask = None
    with rasterio.Env():
    with rasterio.open(file) as src:
        image = src.read(1) # first band
        #image[:2,:2]
        #array([[7, 4],
        #       [2, 7]], dtype=int16)
    
        newimage = np.random.uniform(size=image.shape).astype(np.float32) #Create an array of random floats between 0-1 with the same shape as the raster
        newimage = image+newimage #Sum the original and random array
        #array([[7.9048324, 4.694755 ],
        #       [2.716989 , 7.423101 ]], dtype=float32)
    
        results = (
        {'properties': {'raster_val': v}, 'geometry': s}
        for i, (s, v) 
        in enumerate(
            shapes(newimage, mask=mask, transform=src.transform)))
    
    geoms = list(results)
    
    df  = gpd.GeoDataFrame.from_features(geoms)
    df = df.set_crs(3006)
    df["raster_val"] = np.floor(df["raster_val"]).astype(int) 
    #Restore the original raster values
    df.to_file(r"C:\GIS\data\testdata\random_unint16.shp")
    
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.