Ground materials
Ground materials package -- fetch, clean, and deduplicate material layers.
GroundMaterialsServiceError
Bases: Exception
A ground-material operation failed in a way the caller must see.
LocalGroundMaterialCleaner
Clean ground-material layers in-process.
The Local in the name is historical; the name is kept because it is
published API.
clean() takes a dict and returns one. A bulk caller should use
clean_json, or merge_and_clean_json when the input is still the
per-tile documents: both take and return JSON bytes, so no intermediate
layer tree is built as Python objects.
z_step=None uses the default of 0.05 m.
clean
clean(
layers: Dict[str, Any],
*,
latitude: float,
longitude: float,
distance: float,
default_layer: str,
z_step: Optional[float] = None,
) -> Dict[str, Any]
Clean a layer dict and return the cleaned layer dict.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
layers
|
dict
|
|
required |
latitude
|
float
|
Latitude of the clean circle's centre, in degrees. |
required |
longitude
|
float
|
Longitude of the clean circle's centre, in degrees. |
required |
distance
|
float
|
Radius of the clean circle, in metres. |
required |
default_layer
|
str
|
Name of the default material layer, used for the backdrop. |
required |
z_step
|
float
|
Per-layer z spacing in metres (default 0.05). |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
The cleaned |
Raises:
| Type | Description |
|---|---|
GroundMaterialsServiceError
|
If |
clean_json
clean_json(
layers_json: bytes,
*,
latitude: float,
longitude: float,
distance: float,
default_layer: str,
z_step: Optional[float] = None,
) -> bytes
Clean a JSON layer document, bytes in and bytes out.
Nothing here builds a Python object tree.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
layers_json
|
bytes
|
|
required |
latitude
|
float
|
Latitude of the clean circle's centre, in degrees. |
required |
longitude
|
float
|
Longitude of the clean circle's centre, in degrees. |
required |
distance
|
float
|
Radius of the clean circle, in metres. |
required |
default_layer
|
str
|
Name of the default material layer, used for the backdrop. |
required |
z_step
|
float
|
Per-layer z spacing in metres (default 0.05). |
None
|
Returns:
| Type | Description |
|---|---|
bytes
|
The cleaned layers as a UTF-8 JSON document. |
Raises:
| Type | Description |
|---|---|
GroundMaterialsServiceError
|
If the cleaning fails. |
merge_and_clean_json
merge_and_clean_json(
tile_layers_json: bytes,
*,
latitude: float,
longitude: float,
distance: float,
default_layer: str,
z_step: Optional[float] = None,
) -> bytes
Merge per-tile layer documents and clean them in one step.
The merged layer tree never becomes Python objects between the two steps.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tile_layers_json
|
bytes
|
A JSON array of per-tile |
required |
latitude
|
float
|
Latitude of the clean circle's centre, in degrees. |
required |
longitude
|
float
|
Longitude of the clean circle's centre, in degrees. |
required |
distance
|
float
|
Radius of the clean circle, in metres. |
required |
default_layer
|
str
|
Name of the default material layer, used for the backdrop. |
required |
z_step
|
float
|
Per-layer z spacing in metres (default 0.05). |
None
|
Returns:
| Type | Description |
|---|---|
bytes
|
The merged and cleaned layers as a JSON document. |
Raises:
| Type | Description |
|---|---|
GroundMaterialsServiceError
|
If the merge or the cleaning fails. |
Notes
An empty merge returns b"{}" and is not cleaned: no layers, no
default backdrop.
GroundMaterialsServiceClient
Bases: ScrubbedSessionState
Client for ground-material layers.
api_key, base_url, gateway_base_url and telemetry are accepted for
construction compatibility with the other service clients and are unused:
this client sends no request of its own since the utilities routes were
removed. The public data reads go through the range reader of each worker.
logger
instance-attribute
logger: Logger = logger
Logger the client reports progress to.
base_url
instance-attribute
base_url: str = base_url
Base URL accepted for construction compatibility; never contacted.
close
close() -> None
Release the client's resources. Kept for API compatibility.
get_area
get_area(
polygon: dict,
*,
max_workers: int = 10,
default_material: str = "asphalt",
timeout: int = 60,
total_timeout: int = 600,
on_progress: Optional[Callable[[TileProgress], None]] = None,
max_tiles_override: Optional[int] = None,
z_step: Optional[float] = None,
overture_release: Optional[str] = None,
analysis_type: Optional[str] = None,
acquisition: Any = REMOVED,
cleaner: Any = REMOVED,
) -> AreaGroundMaterials
Read, deduplicate, and clean ground materials for a polygon area.
The site is read once: as a single rectangle up to 4 km2, and above that as a grid of roughly 2 x 2 km read chunks, at most two in flight. Nothing is composed per simulation tile.
There is no partial answer. A chunk that fails raises
TiledRunError, whose failed_tiles names the failed chunks and
whose __cause__ is the first underlying error.
The returned AreaGroundMaterials can be reused across
multiple run_area() calls (tile assignment happens at submission).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
polygon
|
dict
|
GeoJSON Polygon. |
required |
max_workers
|
int
|
Read chunks in flight. A CEILING of 2 applies, so this can only
ask for FEWER: |
10
|
default_material
|
str
|
Default material layer name for the clean step (default "asphalt"). |
'asphalt'
|
timeout
|
int
|
Per-REQUEST budget in seconds (default 60), trimmed to what is
left of |
60
|
total_timeout
|
int
|
Wall-clock deadline over the whole site read, in seconds (default 600). Checked between chunks and before each read. |
600
|
on_progress
|
callable
|
Progress callback |
None
|
max_tiles_override
|
int
|
Override the default maximum number of non-empty tiles. |
None
|
z_step
|
float
|
Per-layer z spacing in metres (default 0.05). |
None
|
overture_release
|
str
|
Pin the Overture collections to one immutable release. The resolved release is reported on the result. |
None
|
analysis_type
|
str
|
The analysis this acquisition is for. It decides the read margin
(363 m for |
None
|
acquisition
|
object
|
Removed. Passing a value raises |
REMOVED
|
cleaner
|
object
|
Removed. Passing a value raises |
REMOVED
|
Returns:
| Type | Description |
|---|---|
AreaGroundMaterials
|
Cleaned material layers for the whole polygon.
|
Raises:
| Type | Description |
|---|---|
PolygonValidationError
|
If |
TiledRunError
|
If a read chunk fails or |
GeodataDependencyError
|
If the optional |
GroundMaterialsServiceError
|
If the merged and cleaned layers cannot be produced. |
TypeError
|
If the removed |
AreaGroundMaterials
dataclass
Result of ground-material fetch for a polygon area.
layers
instance-attribute
layers: Dict[str, dict]
Material layers keyed by name (e.g. 'vegetation', 'water', 'asphalt'), each a GeoJSON FeatureCollection.
polygon
instance-attribute
polygon: dict
The input GeoJSON polygon.
total_features
instance-attribute
total_features: int
Total features across all layers after dedup.
execution_time
instance-attribute
execution_time: float
Wall-clock seconds for the full pipeline.
overture_release
class-attribute
instance-attribute
overture_release: Optional[str] = None
Overture Maps release the layers were read from. The public index
pointer moves daily, so the same polygon can otherwise return different
ground layers on two days with no signal to the caller; pass the value
back as overture_release= to pin the run. Several releases are joined
with ", " on the rare run that straddles a refresh.
failed_tiles
class-attribute
instance-attribute
failed_tiles: List[Dict[str, Any]] = field(default_factory=list)
Tiles that failed every retry, as
{"tile_id", "row", "col", "error"}, the same shape
AreaVegetation.failed_tiles carries. A partial read is otherwise
invisible: the layers simply cover less ground than the polygon, which
reads as "there is nothing there". Empty means every tile was read.
read_margin_m
class-attribute
instance-attribute
read_margin_m: Optional[float] = None
Half extent, in metres, of the read rectangle every tile was fetched
with: 363 m for the wind analyses, 544 m otherwise. run_area refuses a
run whose analysis needs more than this.
analysis_type
class-attribute
instance-attribute
analysis_type: Optional[str] = None
The analysis type the read margin was taken from. None on layers
built by hand, which make no claim and are never refused.