Post-Processing¶
The postprocess module provides utilities for cleaning up delineated field boundary polygons, including polygonization, simplification, regularization, area filtering, cross-tile merging, and LULC-based crop filtering.
The lulc_filter submodule automatically removes non-agricultural polygons using NLCD (US), Dynamic World (global, ≥2016), or C3S Land Cover (global, pre-Sentinel). This is integrated into the main pipeline and enabled by default.
postprocess ¶
Post-processing utilities for field boundary polygons.
Provides shared functionality for polygonization, simplification, regularization, area filtering, and cross-tile merging.
filter_polygons ¶
filter_polygons(gdf: GeoDataFrame, min_area_m2: float = 2500.0, max_area_m2: float | None = None, remove_holes_below_m2: float | None = None, lulc_mask_path: str | None = None, lulc_agricultural_classes: list[int] | None = None) -> gpd.GeoDataFrame
Filter field boundary polygons by area and optional LULC mask.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gdf
|
GeoDataFrame
|
Input polygons. |
required |
min_area_m2
|
float
|
Minimum polygon area in m** (default 2500). |
2500.0
|
max_area_m2
|
float or None
|
Maximum polygon area in m. None means no upper limit. |
None
|
remove_holes_below_m2
|
float or None
|
Remove interior rings (holes) smaller than this threshold. |
None
|
lulc_mask_path
|
str or None
|
Path to a LULC raster for filtering non-agricultural areas. |
None
|
lulc_agricultural_classes
|
list[int] or None
|
LULC class values considered agricultural. |
None
|
Returns:
| Type | Description |
|---|---|
GeoDataFrame
|
Filtered polygons. |
Source code in agribound/postprocess/filter.py
merge_polygons ¶
merge_polygons(gdf: GeoDataFrame, iou_threshold: float = 0.3, containment_threshold: float = 0.8) -> gpd.GeoDataFrame
Merge overlapping or adjacent polygons.
Uses R-tree spatial indexing for efficient overlap detection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gdf
|
GeoDataFrame
|
Input polygons (potentially with cross-tile duplicates). |
required |
iou_threshold
|
float
|
IoU threshold above which polygons are merged (default 0.3). |
0.3
|
containment_threshold
|
float
|
If one polygon contains this fraction of another, merge them (default 0.8). |
0.8
|
Returns:
| Type | Description |
|---|---|
GeoDataFrame
|
Merged polygons with no duplicates. |
Source code in agribound/postprocess/merge.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | |
polygonize_mask ¶
polygonize_mask(mask_path: str, min_area_m2: float = 2500.0, band: int = 1, connectivity: int = 4, field_value: int | None = None) -> gpd.GeoDataFrame
Convert a raster segmentation mask to field boundary polygons.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mask_path
|
str
|
Path to the segmentation mask GeoTIFF. Non-zero values are treated as field pixels (or only field_value if specified). |
required |
min_area_m2
|
float
|
Minimum polygon area in m**2 to keep (default 2500). |
2500.0
|
band
|
int
|
Band index to polygonize (1-based, default 1). |
1
|
connectivity
|
int
|
Pixel connectivity for grouping (4 or 8, default 4). |
4
|
field_value
|
int or None
|
If set, only pixels equal to this value are polygonized. If None, all non-zero pixels are included. |
None
|
Returns:
| Type | Description |
|---|---|
GeoDataFrame
|
Field boundary polygons with |
Source code in agribound/postprocess/polygonize.py
regularize_polygons ¶
regularize_polygons(gdf: GeoDataFrame, method: str = 'adaptive', angle_threshold: float = 15.0) -> gpd.GeoDataFrame
Regularize field boundary polygon geometry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gdf
|
GeoDataFrame
|
Input polygons. |
required |
method
|
str
|
Regularization method: |
'adaptive'
|
angle_threshold
|
float
|
Maximum deviation angle for orthogonalization (degrees). |
15.0
|
Returns:
| Type | Description |
|---|---|
GeoDataFrame
|
Regularized polygons. |
Source code in agribound/postprocess/regularize.py
simplify_polygons ¶
simplify_polygons(gdf: GeoDataFrame, tolerance: float = 2.0, preserve_topology: bool = True) -> gpd.GeoDataFrame
Simplify field boundary polygons.
The tolerance is always in meters. If the input CRS is geographic (e.g. EPSG:4326), the data is temporarily projected to a local UTM zone for simplification.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gdf
|
GeoDataFrame
|
Input polygons. |
required |
tolerance
|
float
|
Simplification tolerance in meters (default 2.0). |
2.0
|
preserve_topology
|
bool
|
If True, prevent polygon collapse and self-intersection. |
True
|
Returns:
| Type | Description |
|---|---|
GeoDataFrame
|
Simplified polygons. |