post_classify module¶
The Post-processing module
raster2shapefile(image, band=1)
¶
Converts a raster image to a shapefile (GeoDataFrame). This function reads a raster image, masks out NoData values, extracts shapes (polygons) from the raster, and converts them into a GeoDataFrame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image |
rasterio.io.DatasetReader |
The raster image to be converted. |
required |
band |
int |
The band number to read from the raster image. Defaults to 1. |
1 |
Returns:
| Type | Description |
|---|---|
gpd.GeoDataFrame |
A GeoDataFrame containing the extracted polygons and their corresponding values. |
Source code in geonate/post_classify.py
def raster2shapefile(image, band=1):
"""
Converts a raster image to a shapefile (GeoDataFrame).
This function reads a raster image, masks out NoData values, extracts shapes (polygons) from the raster,
and converts them into a GeoDataFrame.
Args:
image (rasterio.io.DatasetReader): The raster image to be converted.
band (int, optional): The band number to read from the raster image. Defaults to 1.
Returns:
gpd.GeoDataFrame: A GeoDataFrame containing the extracted polygons and their corresponding values.
"""
import geopandas as gpd
import rasterio
from rasterio.features import shapes
from shapely.geometry import shape
# Check input data
# Other input
if not isinstance(input, rasterio.DatasetReader):
raise ValueError('Input data is not supported, it must be raster object')
# Other input
else:
ds =image.read(band)
transform = image.transform
# Mask out NoData values
mask = image != image.nodata
# Extract shapes (polygons) from the raster
shapes_gen = shapes(ds, mask=mask, transform=transform)
# Convert to GeoDataFrame
polygons = []
values = []
for geom, value in shapes_gen:
polygons.append(shape(geom))
values.append(value)
gdf = gpd.GeoDataFrame({'geometry': polygons, 'class': values}, crs=image.crs)
return gdf
reclassify(input, breakpoints, classes)
¶
Reclassify image with discrete or continuous values
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input |
raster | array |
Raster or data array input |
required |
breakpoints |
list |
Number list, defines a breakpoint value for reclassifcation, e.g., [ -1, 0, 1] |
required |
classes |
list |
Number list, define classes, number of classes equal number of breakpoints minus 1 |
required |
Returns:
| Type | Description |
|---|---|
raster | dataArray |
Reclassified result in raster or data array depending on input, containing all image pixel values |
Source code in geonate/post_classify.py
def reclassify(input, breakpoints, classes):
"""
Reclassify image with discrete or continuous values
Args:
input (raster | array): Raster or data array input
breakpoints (list): Number list, defines a breakpoint value for reclassifcation, e.g., [ -1, 0, 1]
classes (list): Number list, define classes, number of classes equal number of breakpoints minus 1
Returns:
raster | dataArray: Reclassified result in raster or data array depending on input, containing all image pixel values
"""
import rasterio
import numpy as np
from .common import array2raster
# *****************************************
# Check input data
# input is raster
if isinstance(input, rasterio.DatasetReader):
if len(input.shape) == 2:
dataset = input.read()
meta = input.meta
elif len(input.shape) == 3:
if input.shape[0] > 1:
raise ValueError('Input data has more than one band')
else:
dataset = input.read(1)
meta = input.meta
# input is array
elif isinstance(input, np.ndarray):
if (len(input.shape)) > 2 and (input.shape[0] > 1):
raise ValueError('Input data has more than one band')
else:
dataset = input
# Other input
else:
raise ValueError('Input data is not supported')
# *****************************************
# Create unique values and empty data array to store reclassified result
uniques = np.unique(dataset)
reclassified = np.zeros_like(dataset)
# *****************************************
# If image has discrete values
if len(uniques) == len(classes):
if len(breakpoints) == len(classes):
for i in range(len(classes)):
reclassified[dataset == breakpoints[i]] = classes[i]
elif len(breakpoints) == (len(classes)-1):
for i in range(len(classes)):
reclassified[(dataset >= breakpoints[i]) & (dataset < breakpoints[i+1])] = classes[i]
else:
raise ValueError('Number of classes must be equal to number of breakpoints minus 1')
# If image has continuous values
else:
if len(breakpoints) == (len(classes)+1):
for i in range(len(classes)):
reclassified[(dataset >= breakpoints[i]) & (dataset < breakpoints[i+1])] = classes[i]
else:
raise ValueError('Number of classes must be equal to number of breakpoints minus 1')
# *****************************************
# Define output
if isinstance(input, rasterio.DatasetReader):
reclassified_raster = array2raster(reclassified, meta)
else:
reclassified_raster = reclassified
return reclassified_raster