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)

Kadir Şahbaz
  • 76,800
  • 56
  • 247
  • 389
  • 1
    Please edit the title of your question. There is no error with "shapes" because the function returns an expected result https://rasterio.readthedocs.io/en/stable/api/rasterio.features.html "Get shapes and values of connected regions in a dataset or array." What you need is some other method. – user30184 Mar 23 '23 at 15:49
  • Which method should I use? – geomaticpoly Mar 24 '23 at 07:16
  • A few alternatives: https://gis.stackexchange.com/questions/294592/converting-raster-to-vector-and-creating-polygons-based-on-each-pixel-in-qgis – user30184 Mar 24 '23 at 07:48
  • thank you but i have to do this in python. – geomaticpoly Mar 24 '23 at 08:10
  • How about https://docs.dea.ga.gov.au/notebooks/Frequently_used_code/Polygonise_pixel_edges.html? Or https://spatial-dev.guru/2022/04/16/polygonize-raster-using-rioxarray-and-geopandas/? – user30184 Mar 24 '23 at 09:01

1 Answers1

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")

BERA
  • 72,339
  • 13
  • 72
  • 161