---
title: Vegetation
source: https://infrared.city/docs/sdk/1.0/python/vegetation/
---

# Vegetation

Vegetation (tree) service client and types.

Provides `VegetationServiceClient` for fetching and deduplicating tree data from the Infrared API, and the `AreaVegetation` result type.

## VegetationServiceError

Bases: `Exception`

A vegetation operation failed in a way the caller must see.

Raised by the mesh converter and the direct tree acquisition when their input is malformed or an operation fails.

## VegetationServiceClient

Bases: `ScrubbedSessionState`

Client for vegetation (tree) data 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 can be used as a context manager.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `api_key` | `str` | API key. Accepted for compatibility and unused. | *required* |
| `logger` | `Logger` | Logger that receives progress and warning messages. | *required* |
| `base_url` | `str` | Service base URL. Accepted for compatibility and unused. | *required* |
| `gateway_base_url` | `str` | Gateway base URL. Accepted for compatibility and unused. | `None` |
| `telemetry` | `Telemetry` | Telemetry settings. Accepted for compatibility and unused. | `None` |
| `converter` | `object` | Removed. Passing any value raises `TypeError`. | `REMOVED` |
| `acquisition` | `object` | Removed. Passing any value raises `TypeError`. | `REMOVED` |

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `logger` | `Logger` | Logger that receives progress and warning messages. |
| `base_url` | `str` | Service base URL, as given at construction. |

### close

```python
close() -> None
```

Release the client's resources. Kept for API compatibility.

### convert_to_mesh

```python
convert_to_mesh(
feature_collection: dict, *, converter: Any = REMOVED
) -> List[dict]
```

Convert GeoJSON tree points to DotBim meshes.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `feature_collection` | `dict` | GeoJSON FeatureCollection with a `referencePoint` field `[lon, lat]` used as the metric coordinate origin. | *required* |
| `converter` | `object` | Removed. Passing any value raises `TypeError`. | `REMOVED` |

Returns:

| Type | Description |
| --- | --- |
| `list[dict]` | DotBim mesh dicts (`mesh_id`, `coordinates`, `indices`). |

Raises:

| Type | Description |
| --- | --- |
| `[VegetationServiceError](#infrared_sdk.vegetation.VegetationServiceError)` | On malformed input, a conversion error, or an SDK installation whose bundled conversion code does not match the SDK version. The method never returns an empty list in place of a failure. |
| `TypeError` | If the removed `converter` argument is passed. |

### get_area

```python
get_area(
polygon: dict,
*,
max_workers: int = 10,
timeout: int = 60,
total_timeout: int = 600,
on_progress: Optional[Callable[[TileProgress], None]] = None,
max_tiles_override: Optional[int] = None,
analysis_type: Optional[str] = None,
acquisition: Any = REMOVED,
) -> AreaVegetation
```

Read and deduplicate vegetation for a polygon area.

Tiles the polygon, range-reads the public world FlatGeobuf and any city overlay per tile in parallel, and deduplicates across overlapping tiles. Returns GeoJSON features (no DotBim conversion).

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `polygon` | `dict` | GeoJSON Polygon. | *required* |
| `max_workers` | `int` | Maximum number of parallel threads. | `10` |
| `timeout` | `int` | Per-tile timeout, in seconds. | `60` |
| `total_timeout` | `int` | Total wall-clock timeout, in seconds. | `600` |
| `on_progress` | `callable` | Progress callback `(TileProgress) -> None`. | `None` |
| `max_tiles_override` | `int` | Override the default maximum number of non-empty tiles. | `None` |
| `analysis_type` | `str` | The analysis this acquisition is for. It decides the tile grid and the read margin, `ceil(sqrt(2) * context_size_m / 2)` for the analysis: 363 m for the two wind analyses and 544 m for every other one. Omit it for the widest margin, valid for every analysis. | `None` |
| `acquisition` | `object` | Removed. Passing any value raises `TypeError`. | `REMOVED` |

Returns:

| Type | Description |
| --- | --- |
| `[AreaVegetation](#infrared_sdk.vegetation.AreaVegetation)` | Deduplicated GeoJSON tree features. Tiles that failed are listed in `failed_tiles`. |

Raises:

| Type | Description |
| --- | --- |
| `PolygonValidationError` | If the polygon is invalid, or `max_tiles_override` is not a non-negative integer. |
| `TiledRunError` | If every tile fails. |
| `TypeError` | If the removed `acquisition` argument is passed. |

## AreaVegetation  `dataclass`

Result of vegetation fetch for a polygon area.

### features  `instance-attribute`

```python
features: Dict[str, dict]
```

Tree GeoJSON features keyed by dedup key.

### polygon  `instance-attribute`

```python
polygon: dict
```

The input GeoJSON polygon.

### total_trees  `instance-attribute`

```python
total_trees: int
```

Number of unique trees after deduplication.

### execution_time  `instance-attribute`

```python
execution_time: float
```

Wall-clock seconds for the full fetch pipeline.

### failed_tiles  `class-attribute` `instance-attribute`

```python
failed_tiles: List[Dict[str, Any]] = field(default_factory=list)
```

Per-tile failure records (`tile_id`, `row`, `col`, `error`) for tiles that failed after all retries; empty when every tile succeeded. Use `len(area.failed_tiles)` to detect partial-coverage results. Mirrors `AreaBuildings.failed_tiles`.

### read_margin_m  `class-attribute` `instance-attribute`

```python
read_margin_m: Optional[float] = None
```

Half extent, in metres, of the read rectangle every tile was fetched with — `ceil(sqrt(2) * context_size_m / 2)` for `analysis_type` (363 m wind, 544 m otherwise). `run_area` refuses a run whose analysis needs more than this.

### analysis_type  `class-attribute` `instance-attribute`

```python
analysis_type: Optional[str] = None
```

The analysis type the read margin was taken from. `None` on features built by hand, which make no claim and are never refused.
