shapelib.tools.converters package#

Submodules#

shapelib.tools.converters.lines_raster_converter module#

shapelib.tools.converters.lines_raster_converter.mask_to_lines(mask, dataset_reader, window=None, dilation_kernel_size=5, min_distance_points=10, look_ahead_distance=8, min_line_size=10, min_object_size=0, target_resolution_cm_per_pixel=None)[source]#

Convert a binary mask to a GeoDataFrame of line geometries using optimized line extraction.

Extracts line geometries from a 2D binary mask using morphological operations, skeletonization, and line tracing.

Parameters:
  • mask (ndarray) – A 2D binary array where nonzero values represent features to extract lines from. Values should be 0 for background and any nonzero value for foreground.

  • dataset_reader (DatasetReader) – Rasterio dataset that the mask is derived from, used for coordinate transformation and CRS.

  • window (Window) – If provided, the transform will be adjusted for the window region. The mask should correspond to the windowed region. Defaults to None.

  • dilation_kernel_size (int) – Size of the morphological dilation kernel. Larger values connect nearby features but may merge distinct lines. Set to 0 to skip dilation. Defaults to 2.

  • min_distance_points (int) – Minimum distance between consecutive points in the line tracing algorithm. Higher values produce smoother lines with fewer vertices. Defaults to 10.

  • look_ahead_distance (int) – Look-ahead distance for the line tracing algorithm. Higher values produce smoother but potentially less accurate lines. Defaults to 8.

  • min_line_size (int) – Minimum number of pixels required for a line to be included in the output. Shorter lines are filtered out to reduce noise. Defaults to 10.

  • min_object_size (int) – Minimum number of pixels required for a connected component to be included in the output. Connected components smaller than this threshold are filtered out to reduce noise. Defaults to 0.

  • target_resolution_cm_per_pixel (float | None) – Target resolution in centimeters per pixel if the mask was resampled. If provided and different from the dataset’s original resolution, the transform will be automatically adjusted to account for resampling. This works for both upsampling and downsampling.

Returns:

GeoDataFrame containing LineString geometries extracted from the mask. Each row represents a single line feature with proper coordinate transformation.

Return type:

GeoDataFrame

Examples

>>> with rasterio.open('image.tif') as src:
...     mask = model.predict(src.read(1))  # Get a binary mask
...     gdf = mask_to_lines(mask, src)
...     print(gdf)
...
...     # Extract lines with resampling
...     resampled_mask = model.predict_resampled(src.read(1))
...     gdf_resampled = mask_to_lines(
...         resampled_mask,
...         src,
...         target_resolution_cm_per_pixel=3.0
...     )
...
...     # Extract lines from a specific window
...     window = rasterio.windows.Window(0, 0, 100, 100)
...     mask_window = mask[:100, :100]
...     gdf_window = mask_to_lines(mask_window, src, window=window)
...     print(gdf_window)
shapelib.tools.converters.lines_raster_converter.lines_to_mask(gdf, dataset_reader, fill_value=1, background_value=0, all_touched=True, window=None, min_size=None)[source]#

Convert a GeoDataFrame of lines to a binary mask using rasterio.

This function rasterizes line geometries from a GeoDataFrame into a binary mask with the same dimensions and coordinate reference system as the provided rasterio dataset reader. If a window is provided, only the region inside the window is rasterized. If min_size is specified and the resulting mask is smaller, it will be padded with background_value to match the exact minimum size.

Parameters:
  • gdf (GeoDataFrame) – GeoDataFrame containing line geometries to be rasterized.

  • dataset_reader (DatasetReader) – Rasterio dataset reader that defines the target raster properties (transform, CRS, height, width) for the output mask.

  • fill_value (int) – Value to assign to pixels that intersect with line geometries. Defaults to 1.

  • background_value (int) – Value to assign to pixels that do not intersect with any line. Defaults to 0.

  • all_touched (bool) – If True, all pixels touched by geometries will be burned in. If False, only pixels whose center is within the line or that are selected by Bresenham’s line algorithm will be burned in. Defaults to True for better line visibility.

  • window (Window | None) – If provided, only rasterize the region inside the window. The output mask will have shape (window.height, window.width).

  • min_size (tuple[int, int] | None) – Minimum size (height, width) for the output mask. If the generated mask is smaller than this size, it will be padded with background_value to match the exact minimum size. If None or if the mask is already equal to or larger than min_size, no padding is applied. Defaults to None.

Returns:

A 2D numpy array (mask) with the same dimensions as the input raster or window (or min_size if padding was applied), where pixels intersecting with lines have the fill_value and background pixels have the background_value.

Return type:

ndarray

Examples

>>> import rasterio
>>> import geopandas as gpd
>>> from shapelib.tools.converters import lines_to_mask
>>>
>>> # Load a raster and line data
>>> with rasterio.open('image.tif') as src:
...     gdf = gpd.read_file('roads.shp')
...     mask = lines_to_mask(gdf, src)
...     print(mask.shape)  # Should match src.shape
...
...     # With window
...     window = rasterio.windows.Window(0, 0, 50, 50)
...     mask_window = lines_to_mask(gdf, src, window=window)
...     print(mask_window.shape)  # Should be (50, 50)
...
...     # With minimum size padding
...     mask_padded = lines_to_mask(gdf, src, window=window, min_size=(256, 256))
...     print(mask_padded.shape)  # Should be (256, 256) with zero padding

Notes

The all_touched parameter is set to True by default for line geometries to ensure better line visibility in the rasterized output. Lines are typically thin features that may be missed if only center points are considered.

shapelib.tools.converters.points_raster_converter module#

shapelib.tools.converters.points_raster_converter.mask_to_points(mask, dataset_reader, window=None, target_resolution_cm_per_pixel=None)[source]#

Convert a binary or labeled mask to a GeoDataFrame of points.

Each connected component (blob) in the mask is converted to a point at its centroid using the dataset’s affine transform. If the mask was resampled, use target_resolution_cm_per_pixel to ensure correct spatial positioning.

Parameters:
  • mask (ndarray) – A 2D array with 0 for background and any nonzero value for features.

  • dataset_reader (DatasetReader) – Rasterio dataset that the mask is derived from, used for transform and CRS.

  • window (rasterio.windows.Window, optional) – If provided, the transform will be adjusted for the window region.

  • target_resolution_cm_per_pixel (float | None) – Target resolution in centimeters per pixel if the mask was resampled. If provided and different from the dataset’s original resolution, the transform will be automatically adjusted to account for resampling. This works for both upsampling and downsampling.

Returns:

GeoDataFrame with the extracted points and their associated values (label).

Return type:

GeoDataFrame

Examples

>>> import rasterio
>>> with rasterio.open('image.tif') as src:
...     # Extract points without resampling
...     mask = model.predict(src.read(1))
...     gdf = mask_to_points(mask, src)
...
...     # Extract points with resampling
...     resampled_mask = model.predict_resampled(src.read(1))
...     gdf_resampled = mask_to_points(
...         resampled_mask,
...         src,
...         target_resolution_cm_per_pixel=3.0
...     )
shapelib.tools.converters.points_raster_converter.points_to_mask(gdf, dataset_reader, fill_value=1, background_value=0, all_touched=True, window=None, min_size=None)[source]#

Convert a GeoDataFrame of points to a binary mask.

Parameters:
  • gdf (GeoDataFrame) – GeoDataFrame containing point geometries to be rasterized.

  • dataset_reader (DatasetReader) – Rasterio dataset reader that defines the target raster properties (transform, CRS, height, width) for the output mask.

  • fill_value (int) – Value to assign to pixels that coincide with point geometries. Defaults to 1.

  • background_value (int) – Value to assign to pixels that do not coincide with any point. Defaults to 0.

  • all_touched (bool) – If True, all pixels touched by geometries will be burned in. Defaults to True.

  • window (rasterio.windows.Window, optional) – If provided, only rasterize the region inside the window. The output mask will have shape (window.height, window.width).

  • min_size (tuple[int, int] | None) – Minimum size (height, width) for the output mask. If the generated mask is smaller than this size, it will be padded with background_value to match the exact minimum size. If None or if the mask is already equal to or larger than min_size, no padding is applied. Defaults to None.

Returns:

A 2D numpy array (mask) where pixels corresponding to input points have the fill_value and background pixels have the background_value.

Return type:

ndarray

shapelib.tools.converters.polygon_raster_converter module#

shapelib.tools.converters.polygon_raster_converter.mask_to_polygons(mask, dataset_reader, window=None, target_resolution_cm_per_pixel=None)[source]#

Convert a binary or labeled mask to a GeoDataFrame of polygons using rasterio.

This function extracts polygon geometries from a 2D NumPy array (mask), where nonzero values represent features of interest (e.g., 1 for foreground, 0 for background, or any labeled regions).

When the mask has been resampled to a different resolution than the original dataset, the target_resolution_cm_per_pixel parameter ensures correct spatial positioning by automatically adjusting the affine transform. This works for both upsampling (finer resolution) and downsampling (coarser resolution).

Parameters:
  • mask (ndarray) – A 2D array with 0 for background and any nonzero value for features.

  • dataset_reader (DatasetReader) – Rasterio dataset that the mask is derived from, used for transform and CRS.

  • window (Window | None) – If provided, the transform will be adjusted for the window region. The mask should correspond to the windowed region.

  • target_resolution_cm_per_pixel (float | None) –

    Target resolution in centimeters per pixel if the mask was resampled. If provided and different from the dataset’s original resolution, the transform will be automatically adjusted to account for resampling.

    Examples:
    • Original 6 cm/pixel downsampled to 3 cm/pixel: pass 3.0

    • Original 3 cm/pixel upsampled to 6 cm/pixel: pass 6.0

    • No resampling: omit this parameter or pass None

Returns:

GeoDataFrame with the extracted polygons and their associated values.

Return type:

GeoDataFrame

Raises:

ValueError – If target_resolution_cm_per_pixel results in an invalid scale factor.

Examples

>>> import rasterio
>>> import numpy as np
>>> from shapelib.tools.converters import mask_to_polygons
>>>
>>> # Example 1: Basic usage without resampling
>>> mask = np.zeros((100, 100), dtype=np.uint8)
>>> mask[20:80, 20:80] = 1
>>> with rasterio.open('image.tif') as src:
...     polygons = mask_to_polygons(mask, src)
...     print(len(polygons))
>>>
>>> # Example 2: With resampling (original 6cm -> resampled to 3cm)
>>> resampled_mask = np.zeros((200, 200), dtype=np.uint8)
>>> resampled_mask[40:160, 40:160] = 1
>>> with rasterio.open('image_6cm.tif') as src:
...     polygons = mask_to_polygons(
...         resampled_mask,
...         src,
...         target_resolution_cm_per_pixel=3.0
...     )
...     print(len(polygons))
>>>
>>> # Example 3: With window
>>> window = rasterio.windows.Window(0, 0, 50, 50)
>>> mask_window = mask[:50, :50]
>>> with rasterio.open('image.tif') as src:
...     polygons = mask_to_polygons(mask_window, src, window=window)
shapelib.tools.converters.polygon_raster_converter.polygons_to_mask(gdf, dataset_reader, fill_value=1, background_value=0, all_touched=False, window=None, min_size=None)[source]#

Convert a GeoDataFrame of polygons to a binary mask using rasterio.

This function rasterizes polygon geometries from a GeoDataFrame into a binary mask with the same dimensions and coordinate reference system as the provided rasterio dataset reader. If a window is provided, only the region inside the window is rasterized. If min_size is specified and the resulting mask is smaller than the minimum size, it will be padded with background_value to match the exact minimum size.

Parameters:
  • gdf (GeoDataFrame) – GeoDataFrame containing polygon geometries to be rasterized.

  • dataset_reader (DatasetReader) – Rasterio dataset reader that defines the target raster properties (transform, CRS, height, width) for the output mask.

  • fill_value (int) – Value to assign to pixels that intersect with polygon geometries. Defaults to 1.

  • background_value (int) – Value to assign to pixels that do not intersect with any polygon. Defaults to 0.

  • all_touched (bool) – If True, all pixels touched by geometries will be burned in. If False, only pixels whose center is within the polygon or that are selected by Bresenham’s line algorithm will be burned in. Defaults to False for more precise boundary adherence.

  • window (rasterio.windows.Window, optional) – If provided, only rasterize the region inside the window. The output mask will have shape (window.height, window.width).

  • min_size (tuple[int, int] | None) – Minimum size (height, width) for the output mask. If the generated mask is smaller than this size, it will be padded with background_value to match the exact minimum size. If None or if the mask is already equal to or larger than min_size, no padding is applied. Defaults to None.

Returns:

A 2D numpy array (mask) with the same dimensions as the input raster or window (or min_size if padding was applied), where pixels intersecting with polygons have the fill_value and background pixels have the background_value.

Return type:

ndarray

Examples

>>> import rasterio
>>> import geopandas as gpd
>>> from shapelib.tools.converters import polygons_to_mask
>>>
>>> # Load a raster and polygon data
>>> with rasterio.open('image.tif') as src:
...     gdf = gpd.read_file('polygons.shp')
...     mask = polygons_to_mask(gdf, src)
...     print(mask.shape)  # Should match src.shape
...
...     # With window
...     window = rasterio.windows.Window(0, 0, 50, 50)
...     mask_window = polygons_to_mask(gdf, src, window=window)
...     print(mask_window.shape)  # Should be (50, 50)
...
...     # With minimum size padding
...     mask_padded = polygons_to_mask(gdf, src, window=window, min_size=(256, 256))
...     print(mask_padded.shape)  # Should be (256, 256) with zero padding

shapelib.tools.converters.transform_utils module#

Utilities for affine transform adjustments in raster-to-vector conversions.

shapelib.tools.converters.transform_utils.get_transform_with_resampling(dataset_reader, window=None, target_resolution_cm_per_pixel=None)[source]#

Get affine transform from dataset, optionally adjusted for resampling.

This function retrieves the affine transform from a rasterio dataset reader, with optional adjustment for window regions and resolution resampling. When masks are generated from resampled imagery, the transform must be adjusted to maintain correct spatial positioning.

Parameters:
  • dataset_reader (DatasetReader) – Rasterio dataset reader containing the original transform and CRS.

  • window (Window | None) – If provided, the transform will be adjusted for the window region.

  • target_resolution_cm_per_pixel (float | None) – Target resolution in centimeters per pixel if the mask was resampled. If provided and different from the dataset’s original resolution, the transform will be automatically adjusted to account for resampling.

Returns:

Affine transform, potentially adjusted for window and/or resampling.

Return type:

Affine

Examples

>>> import rasterio
>>> with rasterio.open('image.tif') as src:
...     # Get transform without adjustments
...     transform1 = get_transform_with_resampling(src)
...
...     # Get transform adjusted for resampling
...     transform2 = get_transform_with_resampling(
...         src,
...         target_resolution_cm_per_pixel=3.0
...     )
...
...     # Get transform for window with resampling
...     window = rasterio.windows.Window(0, 0, 100, 100)
...     transform3 = get_transform_with_resampling(
...         src,
...         window=window,
...         target_resolution_cm_per_pixel=3.0
...     )
shapelib.tools.converters.transform_utils.adjust_transform_for_resampling(transform, target_resolution_cm_per_pixel)[source]#

Adjust an affine transform to account for mask resampling.

When a mask is resampled to a different resolution, its pixel coordinates no longer align with the original dataset’s transform. This function computes a corrected transform where pixel sizes are scaled appropriately while maintaining the geographic origin.

Parameters:
  • transform (Affine) – Original affine transform from the dataset.

  • target_resolution_cm_per_pixel (float) – Target resolution in centimeters per pixel that the mask was resampled to.

Returns:

Adjusted transform with corrected pixel sizes for the resampled mask.

Return type:

Affine

Raises:

ValueError – If the calculated scale factor is invalid (<=0, infinite, or NaN).

Notes

The transform adjustment formula:

scale_factor = original_resolution / target_resolution adjusted_pixel_size = original_pixel_size / scale_factor

This works for both:
  • Downsampling (scale_factor > 1): finer resolution, smaller pixels

  • Upsampling (scale_factor < 1): coarser resolution, larger pixels

If the original resolution matches the target resolution (within 0.001% tolerance), the transform is returned unchanged to avoid unnecessary computation and potential floating-point errors.

Examples

>>> import rasterio
>>> # Original: 6 cm/pixel, downsampled to 3 cm/pixel (scale = 2.0)
>>> original_transform = rasterio.Affine(0.06, 0, 100, 0, -0.06, 200)
>>> adjusted = adjust_transform_for_resampling(original_transform, 3.0)
>>> # adjusted pixel size will be 0.03m (half of original)
shapelib.tools.converters.transform_utils.pad_mask_to_min_size(mask, min_size, fill_value)[source]#

Pad a mask to match a minimum size.

If the mask is already equal to or larger than min_size in both dimensions, returns the mask unchanged. Otherwise, pads with fill_value to match the exact minimum size. Padding is applied to the right and bottom to preserve spatial alignment.

Parameters:
  • mask (ndarray) – The input mask to pad (2D array).

  • min_size (tuple[int, int]) – Minimum size (height, width) for the output mask.

  • fill_value (int) – Value to use for padding.

Returns:

The padded mask with shape matching min_size, or the original mask if it already meets or exceeds the minimum size.

Return type:

ndarray

Examples

>>> import numpy as np
>>> mask = np.ones((100, 80), dtype=np.uint8)
>>> padded = pad_mask_to_min_size(mask, (256, 256), fill_value=0)
>>> print(padded.shape)
(256, 256)
>>> # No padding when already large enough
>>> large_mask = np.ones((300, 300), dtype=np.uint8)
>>> result = pad_mask_to_min_size(large_mask, (256, 256), fill_value=0)
>>> print(result.shape)
(300, 300)

Notes

Padding is applied to the right and bottom only, preserving the spatial position of the original mask content in the top-left corner.