Skip to content
View as Markdown llms.txt

Buildings

Buildings service and data types.

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() -> None

Release 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]

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=<this object>) 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.