BuildingsAcquisitionError
Bases: Exception
Direct building acquisition failed in a way the caller must see.
BuildingsServiceClient
Bases: ScrubbedSessionState
Client for 3D building meshes, read from the public sources.
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. It implements the context-manager protocol.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_key | str | API key, accepted for compatibility with the other service clients. | required |
logger | Logger | Logger used for progress and warning messages. | required |
base_url | str | Base URL, accepted for compatibility with the other service clients. | required |
gateway_base_url | str | Accepted for compatibility and unused. | None |
telemetry | Telemetry | Accepted for compatibility and unused. | None |
acquisition | optional | Removed option. Passing any value raises TypeError. | REMOVED |
Attributes:
| Name | Type | Description |
|---|---|---|
logger | Logger | Logger used for progress and warning messages. |
base_url | str | Base URL the client was constructed with. |
close
close() -> NoneRelease the client's resources. Kept for API compatibility.
get_area
get_area( polygon: dict, *, config: Optional[BuildingsConfig] = None, on_progress: Optional[Callable[[TileProgress], None]] = None, max_tiles_override: Optional[int] = None, timeout: int = 60, total_timeout: int = 600, max_workers: int = DEFAULT_TILE_ACQUISITION_WORKERS, overture_release: Optional[str] = None, analysis_type: Optional[str] = None, acquisition: Any = REMOVED, ) -> AreaBuildings
Fetch and deduplicate buildings for a polygon area.
The whole site is read at once: a single rectangle up to 4 km2, and a grid of roughly 2 x 2 km read chunks above it, at most two in flight. The meshes come back in one site frame, anchored at the polygon bounding-box south-west corner, and run_area re-anchors them per tile. A polygon straddling a registered city's outline is read tile by tile instead, because a site-level read would give the city's bodies to the tiles outside it.
There is no partial answer on the site path. A chunk that fails raises TiledRunError, whose failed_tiles names the failed chunks and whose __cause__ is the first underlying error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
polygon | dict | GeoJSON Polygon. | required |
config | BuildingsConfig | Accepted for compatibility and unused: it shaped the removed POST /buildings body. | None |
on_progress | callable | Progress callback (TileProgress) -> None, once per read CHUNK on the site path. tile_id is the chunk id and total_count the chunk count. | None |
max_tiles_override | int | Override the maximum number of non-empty tiles allowed. | None |
timeout | int | Per-REQUEST budget in seconds (default 60), trimmed to what is left of total_timeout. | 60 |
total_timeout | int | Wall-clock deadline over the whole site read, in seconds (default 600). | 600 |
max_workers | int | Read chunks in flight on the site path. A CEILING of 2 applies, so this can only ask for FEWER. On the mixed-source per-tile path it is still the thread count. | DEFAULT_TILE_ACQUISITION_WORKERS |
overture_release | str | Pin the Overture footprints 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 tile grid and the READ MARGIN, the half extent of each read rectangle: 256 m for the two wind analyses and 384 m for every other one, which needs the shadow casters further out. Omit it for the widest margin, valid for every analysis. | None |
Returns:
| Type | Description |
|---|---|
AreaBuildings | Deduplicated buildings with coordinates in polygon-bbox-SW meter space, and origin naming that frame — pass the whole object to run_area(buildings=…) and it re-anchors from it, so one acquisition can serve several sub-areas. building_ids is always empty: the read path has no numeric building ids. failed_tiles is empty on the site path: a read that could not cover the polygon raises instead. |
Raises:
| Type | Description |
|---|---|
PolygonValidationError | If polygon is not a valid GeoJSON Polygon, or covers more non-empty tiles than allowed (see max_tiles_override). |
TiledRunError | If a read chunk fails on the site path. |
TypeError | If the removed acquisition argument is passed. |
get_by_tiles
get_by_tiles( tiles: TileGrid, *, config: Optional[BuildingsConfig] = None, on_progress: Optional[Any] = None, timeout: int = 60, total_timeout: int = 600, max_workers: int = DEFAULT_TILE_ACQUISITION_WORKERS, ) -> Dict[str, Optional[dict]]
Fetch buildings for each non-empty tile in a pre-generated grid.
Returns a per-tile mapping {tile_id: buildings_dict | None} intended for inspection or manual per-tile dispatch.
All tile IDs from the grid are present as keys in the returned dict. A None value means the fetch failed for that tile (distinguishable from "no buildings found", which would be an empty dict).
To combine get_by_tiles output into a single dict for visualisation (not for run_area) see merge_buildings.
Warnings
This shape is NOT a drop-in for InfraredClient.run_area's buildings= kwarg, which expects a flat {building_key: building_data} mapping (each value a dict with top-level coordinates, mesh_id, indices). Passing this method's per-tile output directly into run_area(buildings=...) will fail every tile with "missing or non-sequence coordinates". For the area pipeline use client.buildings.get_area(polygon).buildings, the canonical flat shape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tiles | TileGrid | Tile grid produced by tile generation for a polygon. | required |
config | BuildingsConfig | Accepted for compatibility and unused: it shaped the removed POST /buildings body. | None |
on_progress | callable | Progress callback (TileProgress) -> None. | None |
timeout | int | Per-tile timeout in seconds (default 60). | 60 |
total_timeout | int | Total wall-clock timeout in seconds (default 600). | 600 |
max_workers | int | Maximum parallel threads for tile execution (default 20). | DEFAULT_TILE_ACQUISITION_WORKERS |
Returns:
| Type | Description | |
|---|---|---|
| `dict[str, dict \ | None]` | Maps each non-empty tile's ID to its buildings dict, or None if the fetch failed for that tile. |
AreaBuildings
Bases: Payload
Result of get_area().
Frozen Pydantic model — field reassignment is blocked, but mutable containers (buildings dict) can still be mutated in-place (Pydantic v2 behavior), enabling the edit-before-run workflow.
Attributes:
| Name | Type | Description |
|---|---|---|
buildings | dict[str, [DotBimMesh](#infrared_sdk.buildings.DotBimMesh)] | Building meshes keyed by building identifier. |
attributes | dict[str, dict] | {height, min_height, num_floors, source_id} per building, under the same keys as buildings. Populated on both read paths (the site-level read and the per-tile read a mixed-source polygon falls back to). Empty when the meshes did not come from a direct read, which carries meshes and no attributes. Empty therefore means "not available on this path", never "this building has no height". |
building_ids | list[int] | Numeric building IDs from the API response. |
polygon | dict | The input GeoJSON polygon. |
total_buildings | int | Number of buildings in buildings. |
execution_time | float | Wall-clock seconds for the fetch. |
failed_tiles | list[dict] | Per-tile failure records for tiles that did not produce buildings after all retries (empty when every tile succeeded). Each entry has tile_id, row, col, error. Callers can use len(area.failed_tiles) to detect partial-coverage results. |
overture_release | (str, optional) | Overture Maps release the footprints were read from, when the direct acquisition path produced them (None on the service path, which does not report one). The public index pointer moves daily; pass the value back as overture_release= to pin a later run to the same snapshot. |
read_margin_m | (float, optional) | Half extent, in metres, of the read rectangle every tile was fetched with: 256 m for the wind analyses, 384 m otherwise (see analysis_type). run_area refuses a run whose analysis needs more than this. |
analysis_type | (str, optional) | The analysis type the read margin was taken from. None on an object built by hand, which makes no claim and is never refused. |
origin | (tuple, optional) | (lon, lat) of the site frame the meshes are stored in: the polygon bounding-box south-west corner. run_area(buildings= reads it and re-anchors from THIS frame, so acquiring once for a large polygon and running several sub-areas places the buildings correctly. A bare {id: mesh} map carries no origin and is read as being in the run polygon's own frame, which is the behaviour that has always applied. |
BuildingsConfig
Bases: CamelCasePayload
Configuration for tiled buildings retrieval.
Accepted for compatibility and unused: it shaped the removed buildings request.
Attributes:
| Name | Type | Description |
|---|---|---|
output_format | OutputFormat | Desired output format (default DotBim). |
compress | bool | Whether to request compressed responses. |
optimizations | (BuildingOptimizations, optional) | Optimizations of the removed per-tile request; no effect. |
BuildingsRequest
Bases: CamelCasePayload
Request body for a buildings query.
Kept for compatibility: the SDK no longer sends this request.
Attributes:
| Name | Type | Description |
|---|---|---|
coordinates | BuildingCoordinates | Centre of the query. |
size | BuildingSize | Extent of the query. |
return_building_ids | bool | Whether to return numeric building IDs (default False). |
output_format | OutputFormat | Desired output format (default DotBim). |
compress | bool | Whether to request a compressed response (default False). |
optimizations | (BuildingOptimizations, optional) | Optimisations to apply. |
DotBimMesh
Bases: Payload
A single DotBim mesh entry from the buildings API.
Follows the Payload base pattern (frozen, kebab-case aliases).
Attributes:
| Name | Type | Description |
|---|---|---|
mesh_id | int | Numeric identifier of the mesh. |
coordinates | list[float] | Flat [x, y, z, ...] coordinate array. |
indices | list[int] | Triangle index array. Required. |
Notes
indices is required. A mesh without it is silently dropped by the simulation service before any computation runs: no error, no warning, and a tile that reads as if the building had never been submitted, yet is billed in full. The SDK therefore refuses to build one.
merge_buildings
merge_buildings(buildings_map: Dict[str, Optional[dict]]) -> dict
Combine per-tile buildings dicts into one for visualization.
Merges all non-None values from buildings_map into a single dict. Each key in the individual buildings dicts whose value is a list is concatenated; other keys are taken from the last dict encountered.
Parameters:
| Name | Type | Description | Default | |
|---|---|---|---|---|
buildings_map | `dict[str, dict \ | None]` | Maps tile_id -> buildings dict (or None). | required |
Returns:
| Type | Description |
|---|---|
dict | Combined buildings dict, or empty dict if all are None. |