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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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