I/O Utilities¶
Raster and vector I/O, study-area parsing (files, GEE assets, bbox: strings,
WKT), CRS/UTM helpers and value-scale conversions.
io ¶
I/O utilities for raster and vector data.
Provides functions for reading/writing GeoTIFF files, vector formats
(GeoJSON, GeoPackage, GeoParquet), study-area parsing (files, GEE assets,
bbox: strings, WKT), CRS/UTM helpers and radiometric value-scale
conversions.
get_equal_area_crs ¶
Return the NSIDC EASE-Grid 2.0 equal-area CRS (EPSG:6933).
Areas in this CRS are exact; lengths and distances are not (they are stretched away from the standard parallels at 30°N/S, e.g. by about 9 % at 55° latitude), so use a local UTM CRS or geodesic lengths for perimeters.
Returns:
| Type | Description |
|---|---|
CRS
|
EPSG:6933 equal-area cylindrical projection. |
Source code in agribound/io/crs.py
get_utm_crs ¶
Determine the UTM CRS for a given longitude/latitude.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lon
|
float
|
Longitude in degrees. |
required |
lat
|
float
|
Latitude in degrees ( |
required |
Returns:
| Type | Description |
|---|---|
CRS
|
WGS 84 / UTM CRS (EPSG:326xx or EPSG:327xx). |
Source code in agribound/io/crs.py
reproject_raster ¶
reproject_raster(src_path: str | Path, dst_path: str | Path, dst_crs: Any, resolution: float | None = None, resampling: str = 'nearest') -> str
Reproject a raster to a different CRS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
src_path
|
str or Path
|
Source raster file. |
required |
dst_path
|
str or Path
|
Destination raster file. |
required |
dst_crs
|
CRS or str
|
Target coordinate reference system. |
required |
resolution
|
float or None
|
Output pixel resolution. If None, computed automatically. |
None
|
resampling
|
str
|
Resampling method: |
'nearest'
|
Returns:
| Type | Description |
|---|---|
str
|
Path to the reprojected raster. |
Source code in agribound/io/crs.py
utm_crs_for_geometry ¶
Return the UTM CRS of the centroid of a geometry in EPSG:4326.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
geom_4326
|
shapely geometry, GeoSeries or GeoDataFrame
|
Geometry in EPSG:4326. GeoSeries/GeoDataFrames are reprojected to EPSG:4326 if needed and unioned. |
required |
Returns:
| Type | Description |
|---|---|
CRS
|
UTM CRS of the centroid (see :func: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the geometry is empty. |
Source code in agribound/io/crs.py
utm_zones_for_bounds ¶
Return the UTM zone numbers spanned by an EPSG:4326 bounding box.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
bounds
|
tuple[float, float, float, float]
|
|
required |
Returns:
| Type | Description |
|---|---|
list[int]
|
Zone numbers from west to east. A box whose eastern edge lies exactly on a zone boundary does not include the next zone. |
Source code in agribound/io/crs.py
get_raster_info ¶
Read metadata from a raster file without loading pixel data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str or Path
|
Path to the raster file (GeoTIFF). |
required |
Returns:
| Type | Description |
|---|---|
RasterInfo
|
Raster metadata. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If the file does not exist. |
Source code in agribound/io/raster.py
percentile_stretch_uint8 ¶
percentile_stretch_uint8(arr: ndarray, nodata: float | None = None, low: float = 1.0, high: float = 99.0, per_band: bool = True, *, return_bounds: bool = False, return_bounds_only: bool = False, max_sample_side: int = MAX_SAMPLE_SIDE)
Stretch an array to uint8 between per-band percentiles.
Mirrors Delineate-Anything's DataAnalyser/DataLoaderCached
normalisation: uint8 input is returned unchanged; otherwise the low and
high percentiles are computed from valid, finite, strictly positive
pixels on a nearest-neighbour sampling grid of at most
max_sample_side pixels per side, and values are mapped with
clip(255 * (v - lo) / (hi - lo), 0, 255) and truncated to uint8.
Invalid pixels (non-finite in any band, or equal to nodata in all
bands) are set to 0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arr
|
ndarray
|
|
required |
nodata
|
float or None
|
Nodata value; a pixel is nodata when all bands equal it. |
None
|
low
|
float
|
Percentiles (default 1 and 99). |
1.0
|
high
|
float
|
Percentiles (default 1 and 99). |
1.0
|
per_band
|
bool
|
Compute bounds per band (default) or pooled over all bands. |
True
|
return_bounds
|
bool
|
Also return the |
False
|
return_bounds_only
|
bool
|
Return only |
False
|
max_sample_side
|
int
|
Maximum side of the percentile sampling grid (default 4096). |
MAX_SAMPLE_SIDE
|
Returns:
| Type | Description |
|---|---|
ndarray or tuple
|
uint8 array of the input shape; |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a band has no valid positive pixels. |
Source code in agribound/io/raster.py
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 | |
read_raster ¶
read_raster(path: str | Path, bands: list[int] | None = None, window: Window | None = None) -> tuple[np.ndarray, dict[str, Any]]
Read a raster file into a NumPy array.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str or Path
|
Path to the raster file. |
required |
bands
|
list[int] or None
|
1-based band indices to read. None reads all bands. |
None
|
window
|
Window or None
|
Spatial sub-window to read. None reads the full extent. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
data |
ndarray
|
Pixel data with shape |
meta |
dict
|
Rasterio metadata dictionary (crs, transform, width, height, etc.). |
Source code in agribound/io/raster.py
to_s2_dn ¶
to_s2_dn(arr: ndarray, source: str, allow_unknown: bool = False, *, value_scale: str | None = None) -> np.ndarray
Convert composite pixel values to Sentinel-2 L2A units (reflectance x 10000).
COPERNICUS/S2_SR_HARMONIZED stores surface reflectance x 10000 with
the processing-baseline offset removed, so this is
to_unit_reflectance(arr) * 10000. Landsat/HLS composites are already
on this scale after the 1.0 harmonisation; uint8 imagery is only rescaled
(0-255 -> 0-10000), which does not make it radiometrically comparable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arr
|
ndarray
|
See :func: |
required |
source
|
ndarray
|
See :func: |
required |
allow_unknown
|
ndarray
|
See :func: |
required |
value_scale
|
ndarray
|
See :func: |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
float32 array of the same shape. |
Source code in agribound/io/raster.py
to_unit_reflectance ¶
to_unit_reflectance(arr: ndarray, source: str, allow_unknown: bool = False, *, value_scale: str | None = None) -> np.ndarray
Convert composite pixel values to 0-1 reflectance-like floats.
"reflectance_x10000" sources are divided by 10000 and "uint8"
sources by 255 (NAIP digital numbers are not calibrated reflectance; the
result is only a 0-1 rescaling). NaN is preserved.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arr
|
ndarray
|
Pixel values as written by the source's composite builder. |
required |
source
|
str
|
Source name (its |
required |
allow_unknown
|
bool
|
For |
False
|
value_scale
|
str or None
|
Explicit scale ( |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
float32 array of the same shape. |
Raises:
| Type | Description |
|---|---|
ValueError
|
For embedding sources, and for |
Source code in agribound/io/raster.py
write_raster ¶
write_raster(path: str | Path, data: ndarray, crs: Any, transform: Any, nodata: float | None = None, dtype: str | None = None, compress: str = 'lzw') -> str
Write a NumPy array as a GeoTIFF.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str or Path
|
Destination file path. |
required |
data
|
ndarray
|
Pixel data with shape |
required |
crs
|
CRS or str
|
Coordinate reference system. |
required |
transform
|
Affine
|
Affine transform. |
required |
nodata
|
float or None
|
Nodata value to encode in the file. |
None
|
dtype
|
str or None
|
Output data type. Defaults to the array dtype. |
None
|
compress
|
str
|
Compression method (default |
'lzw'
|
Returns:
| Type | Description |
|---|---|
str
|
Path to the written file. |
Source code in agribound/io/raster.py
read_config_study_area ¶
Read config.study_area, keeping a local copy of a GEE asset.
Vector files, "bbox:..." strings and WKT are read with
:func:read_study_area. A GEE asset ID is read from its local copy
(:func:study_area_cache_file) when that file exists, without contacting
Earth Engine; otherwise it is read from Earth Engine with the configured
credentials (read_study_area(..., config=config)) and its geometries
are written to the copy. The pipeline stages that read the study area
(composite builders, study-area selection, evaluation, FTW window dates,
LULC filter) do so through this function, so a GEE-asset study area read
once on a node with network access (e.g. by agribound composite) is
available to a later agribound delineate with the same cache
directory on a node without it.
The copy holds the geometries only (EPSG:4326, no properties). Like the cached composites, it is keyed by the asset ID, not by the asset's content: after changing an asset in place, delete the copy (and the cached composites) or use another cache directory. A copy that cannot be read is replaced; a copy that cannot be written is skipped with a WARNING.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
AgriboundConfig
|
Configuration with a |
required |
Returns:
| Type | Description |
|---|---|
GeoDataFrame
|
Study area geometry (for a GEE asset read from Earth Engine, with the asset's properties; from the copy, without them). |
Source code in agribound/io/vector.py
read_study_area ¶
Read a study area definition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str or Path
|
One of:
|
required |
config
|
AgriboundConfig or None
|
Used only for GEE asset IDs: Earth Engine is initialised with
:func: |
None
|
Returns:
| Type | Description |
|---|---|
GeoDataFrame
|
Study area geometry. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the string is not a recognised format, or the bbox/WKT is invalid. |
FileNotFoundError
|
If a vector file path does not exist. |
Source code in agribound/io/vector.py
read_vector ¶
Read a vector file into a GeoDataFrame.
Supports GeoJSON, GeoPackage, Shapefile, and GeoParquet formats.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str or Path
|
Path to the vector file. |
required |
Returns:
| Type | Description |
|---|---|
GeoDataFrame
|
Loaded vector data. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If the file does not exist. |
ValueError
|
If the file format is not supported. |
Source code in agribound/io/vector.py
write_vector ¶
Write a GeoDataFrame to a vector file.
When writing to .parquet, the output is fiboa-compliant GeoParquet.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
gdf
|
GeoDataFrame
|
Vector data to write. |
required |
path
|
str or Path
|
Destination file path. |
required |
format
|
str or None
|
Output format ( |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Path to the written file. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the format cannot be inferred, is unsupported, or contradicts the file extension. |