brails.types.asset_inventory module

This module defines classes associated with asset inventories.

AssetInventory()

A class representing a collection of Assets managed as an inventory.

Asset(asset_id, coordinates[, features])

A spatial asset with geometry coordinates, and attributes.

class brails.types.asset_inventory.Asset(asset_id, coordinates, features=None)

Bases: object

A spatial asset with geometry coordinates, and attributes.

To import the Asset class, use:

from brails.types.asset_inventory import Asset
Parameters:
  • asset_id (str or int) – Unique identifier for the asset.

  • coordinates (list[list[float]]) – Geometry coordinates of the asset, typically as a list of [x, y] pairs.

  • features (dict[str, Any], optional) – Additional attributes/features of the asset. Defaults to None.

add_features(additional_features, overwrite=True)

Update the existing features in the asset.

Parameters:
  • additional_features (dict[str, Any]) – New features to merge into the asset’s features.

  • overwrite (bool, optional) – Whether to overwrite existing features. Defaults to True.

Returns:

A tuple containing two values:

  • updated (bool): True if any features were added or updated, False otherwise.

  • n_pw (int): Number of possible worlds.

Return type:

tuple[bool, int]

Examples

>>> asset = Asset(
...     asset_id='123',
...     coordinates=[[-122.4194, 37.7749], [-122.4180, 37.7755]]
... )
>>> updated, n_pw = asset.add_features({'roof_type': 'gable'})
>>> print(updated, n_pw)
True 1
>>> print(asset.features)
{'roof_type': 'gable'}
>>> updated, n_pw = asset.add_features(
...     {'possible_heights': [10, 15, 20], 'roof_type': 'hip'},
...     overwrite=True
... )
>>> print(updated, n_pw)
True 3
>>> print(asset.features)
{'roof_type': 'hip', 'possible_heights': [10, 15, 20]}
>>> # When overwrite=False, existing keys are not updated
>>> updated, n_pw = asset.add_features(
...     {'roof_type': 'flat', 'color': 'red'},
...     overwrite=False
... )
>>> print(updated, n_pw)
True 1
>>> print(asset.features)
{'roof_type': 'hip',
'possible_heights': [10, 15, 20],
'color': 'red'}
get_centroid()

Get the centroid of the asset geometry.

Returns:

[[x, y]] if centroid can be calculated, [[None, None]] otherwise.

Return type:

list[list[float]]

Examples

>>> asset = Asset(
...     asset_id='123',
...     coordinates=[[-122.4194, 37.7749], [-122.4190, 37.7750]]
... )
>>> asset.get_centroid()
[[-122.41919999999999, 37.774950000000004]]
>>> empty_asset = Asset(asset_id='empty', coordinates=[])
Coordinates input is empty for empty; defaulting to an empty list.
>>> empty_asset.get_centroid()
[[None, None]]
print_info()

Print the asset’s coordinates and feature attributes.

This method outputs the spatial coordinates and all associated feature key-value pairs of the asset to the console.

Returns:

None

Example

>>> asset = Asset(
...     asset_id='123',
...     coordinates=[[-122.4194, 37.7749], [-122.4180, 37.7755]],
...     features={'roof_type': 'gable'}
... )
>>> asset.print_info()
Coordinates:  [[-122.4194, 37.7749], [-122.4180, 37.7755]]
Features:  {'roof_type': 'gable'}
remove_features(features_to_remove)

Remove specified features from the asset.

Parameters:

features_to_remove (Iterable[str]) – An iterable of feature keys to remove from the Asset features. Accepts iterable types such as list, tuple, set, or dict_keys.

Returns:

True if at least one feature was removed; False otherwise.

Return type:

bool

Raises:

TypeError – If features_to_remove is not an iterable of strings.

Example

>>> asset = Asset(
...     asset_id='123',
...     coordinates=[[-122.4194, 37.7749], [-122.4180, 37.7755]]
... )
>>> asset.features = {'color': 'red', 'height': 10}
>>> asset.remove_features(['color'])
True
>>> asset.features
{'height': 10}
class brails.types.asset_inventory.AssetInventory

Bases: object

A class representing a collection of Assets managed as an inventory.

This class provides methods to add, manipulate, join, write and query a collaction of :class:Asset objects.

To import the AssetInventory class, use:

from brails.types.asset_inventory import AssetInventory
add_asset(asset_id, asset)

Add an Asset to the inventory.

Parameters:
  • asset_id (str or int) – The unique identifier for the asset.

  • asset (Asset) – The asset to be added.

Returns:

True if the asset was added successfully, False otherwise.

Return type:

bool

Raises:

TypeError – If asset is not an instance of Asset.

Examples

>>> asset = Asset(
...     asset_id='001',
...     coordinates=[[-122.4194, 37.7749]],
...     features={'type': 'building'}
... )
>>> inventory = AssetInventory()
>>> success = inventory.add_asset('001', asset)
>>> print(success)
True
>>> # Adding the same asset_id again will fail
>>> success = inventory.add_asset('001', asset)
>>> print(success)
False
add_asset_coordinates(asset_id, coordinates)

Add an Asset to the inventory by adding its coordinate information.

Parameters:
  • asset_id (str or int) – The unique identifier for the asset.

  • coordinates (list[list[float]]) – A two-dimensional list representing the geometry in [[lon1, lat1], [lon2, lat2], ..., [lonN, latN]] format.

Returns:

True if the asset was added successfully, False otherwise.

Return type:

bool

Examples

>>> inventory = AssetInventory()
>>> coords = [[-122.42, 37.77], [-122.43, 37.78], [-122.44, 37.79]]
>>> success = inventory.add_asset_coordinates('A123', coords)
>>> print(success)
True
>>> # Attempt to add the same asset_id again
>>> success = inventory.add_asset_coordinates('A123', coords)
>>> print(success)
False
add_asset_features(asset_id, new_features, overwrite=True)

Add new asset features to the Asset with the specified asset_id.

Parameters:
  • asset_id (str or int) – The unique identifier for the asset.

  • new_features (dict) – A dictionary of features to add to the asset.

  • overwrite (bool) – Whether to overwrite existing features with the same keys. Defaults to True.

Returns:

True if features were successfully added, False if the asset does not exist or the operation fails.

Return type:

bool

Examples

>>> inventory = AssetInventory()
>>> inventory.add_asset_coordinates(
...     'A123',
...     [[-122.4194, 37.7749], [-122.4180, 37.7755]]
... )
True
>>> features = {'height': 10, 'material': 'concrete'}
>>> success = inventory.add_asset_features('A123', features)
>>> print(success)
True
>>> # Add features without overwriting existing keys
>>> more_features = {'material': 'steel', 'color': 'red'}
>>> success = inventory.add_asset_features(
...     'A123',
...     more_features,
...     overwrite=False
... )
>>> print(success)
True
>>> asset = inventory.inventory['A123']
>>> print(asset.features)
{'height': 10, 'material': 'concrete', 'color': 'red'}
add_asset_features_from_csv(file_path, id_column)

Read inventory data from a CSV file and add it to the inventory.

Parameters:
  • file_path (str) – The path to the CSV file

  • id_column (str) – The name of column that contains id values. If None, new indicies will be assigned

Returns:

True if assets were addded, False otherwise.

Return type:

bool

add_model_predictions(predictions, feature_key)

Add model predictions to the inventory.

This method goes through the inventory and updates each item by adding the corresponding model prediction as a new feature under the specified key. Items without a matching prediction are left unchanged.

Parameters:
  • predictions (dict) – A dictionary where keys correspond to inventory items and values represent the predicted features to be added.

  • feature_key (str) – The key under which the predictions will be stored as a new feature in each inventory item.

Returns:

None

Raises:
  • TypeError – If predictions is not a dictionary or feature_key is not a string.

  • ValueError – If none of the keys in predictions exist in the inventory.

Example

Suppose the inventory contains assets with IDs 1, 3, and 12. To add predicted roof types for these assets:

>>> predictions = {1: 'gable', 3: 'flat', 12: 'hip'}
>>> inventory.add_model_predictions(
        predictions,
        feature_key='roof_type'
    )

After this call, each asset with an ID in predictions will have a new feature roof_type set to the corresponding predicted value.

change_feature_names(feature_name_mapping)

Rename feature names in AssetInventory via user-specified mapping.

Parameters:

feature_name_mapping (dict) – A dictionary where keys are the original feature names and values are the new feature names.

Raises:

TypeError – If the mapping is not a dictionary or contains invalid key-value pairs.

Example

First create an AssetInventory with two assets with IDs asset1 and asset2.

>>> inventory = AssetInventory()
>>> asset1 = Asset(
...     asset_id='asset1',
...     coordinates=[
...         [-122.4194, 37.7749],
...         [-122.4194, 37.7849],
...         [-122.4094, 37.7849],
...         [-122.4094, 37.7749],
...         [-122.4194, 37.7749]
...     ],
...     features={'old_name': 100, 'unchanged': 50}
... )
>>> inventory.add_asset('asset1', asset1)
>>> asset2 = Asset(
...     asset_id='asset2',
...     coordinates=[[-122.4194, 37.7749], [-122.4094, 37.7849]],
...     features={'old_name': 200}
... )
>>> inventory.add_asset('asset2', asset2)

Then, change the names of the features of these assets.

>>> inventory.change_feature_names({'old_name': 'new_name'})
>>> inventory.inventory['asset1'].features
{'new_name': 100, 'unchanged': 50}
>>> inventory.inventory['asset2'].features
{'new_name': 200}
convert_polygons_to_centroids()

Convert polygon geometries in the inventory to their centroid points.

Iterates through the asset inventory and replaces the coordinates of each polygon or linestring geometry with the coordinates of its centroid. Point geometries are left unchanged.

This function is useful for spatial operations that require point representations of larger geometries(e.g., matching, distance calculations).

Note

  • Polygon coordinates are wrapped in a list to ensure proper GeoJSON structure.

  • Linestrings are converted to points at their centroid unless the geometry is invalid or ambiguous.

Modifies:
self.inventory (dict):

Updates the coordinates field of each asset in-place by replacing polygons and linestrings with their centroid.

Example

>>> inventory = AssetInventory()
>>> inventory.add_asset_coordinates(
...     'asset1',
...     [
...         [-122.4194, 37.7749],
...         [-122.4194, 37.7849],
...         [-122.4094, 37.7849],
...         [-122.4094, 37.7749],
...         [-122.4194, 37.7749]
...     ]  # Polygon
... )
>>> inventory.add_asset_coordinates(
...     'asset2',
...     [
...         [-122.4194, 37.7749],
...         [-122.4094, 37.7849]
...     ]  # LineString
... )
>>> inventory.convert_polygons_to_centroids()
>>> inventory.get_asset_coordiates('asset1')
[[-122.4144, 37.7799]]
>>> inventory.get_asset_coordiates('asset2')
[[-122.4144, 37.7799]]
get_asset_coordinates(asset_id)

Get the coordinates of a particular asset.

Parameters:

asset_id (str or int) – The unique identifier for the asset.

Returns:

  • bool – Indicates whether the asset was found.

  • list – A list of coordinate pairs in the format [[lon1, lat1], [lon2, lat2], ..., [lonN, latN]] if found, or an empty list if the asset does not exist.

Return type:

tuple[bool, list]

Example

>>> inventory = AssetInventory({
...     "A101": Asset(
...     coordinates=[[30.123, -97.456], [30.124, -97.457]]
...     ),
...     "B202": Asset(
...     coordinates=[[40.789, -74.123], [40.790, -74.124]]
...     )
... })
>>> inventory.get_asset_coordinates("A101")
(True, [[30.123, -97.456], [30.124, -97.457]])
>>> inventory.get_asset_coordinates("Z999")
(False, [])
get_asset_features(asset_id)

Get features of a particular asset.

Parameters:

asset_id (str or int) – The unique identifier for the asset.

Returns:

A tuple where the first element is a boolean indicating whether the asset was found, and the second element is a dictionary containing the asset’s features if the asset is present. Returns an empty dictionary if the asset is not found.

Return type:

tuple[bool, Dict]

Examples

>>> inventory = AssetInventory()
>>> asset = Asset(
...     asset_id='001',
...     coordinates=[[-122.4194, 37.7749]],
...     features={'height': 10, 'material': 'concrete'}
... )
>>> inventory.add_asset('001', asset)
True
>>> found, features = inventory.get_asset_features('001')
>>> found
True
>>> features
{'height': 10, 'material': 'concrete'}
>>> found, features = inventory.get_asset_features('nonexistent')
>>> found
False
>>> features
{}
get_asset_ids()

Retrieve the IDs of all assets in the inventory.

Returns:

A list of asset IDs, which may be strings or integers.

Return type:

list[str or int]

Example

>>> inventory = AssetInventory()
>>> _ = inventory.add_asset_coordinates(
...     'asset1',
...     [[-122.4194, 37.7749], [-122.4180, 37.7750]]
... )
>>> _ = inventory.add_asset_coordinates(
...     2,
...     [[-74.0060, 40.7128], [-74.0055, 40.7130]]
... )
>>> inventory.get_asset_ids()
['asset1', 2]
get_coordinates()

Get geometry(coordinates) and keys of all assets in the inventory.

Returns:

A tuple containing:

  • A list of coordinates for each asset, where each coordinate is represented as a list of [longitude, latitude] pairs.

  • A list of asset keys corresponding to each asset.

Return type:

tuple[list[list[list[float, float]]], list[str or int]]

Example

>>> inventory = AssetInventory()
>>> _ = inventory.add_asset_coordinates(
...     'asset1',
...     [[-122.4194, 37.7749], [-122.4180, 37.7750]]
... )
>>> _ = inventory.add_asset_coordinates(
...     'asset2',
...     [[-74.0060, 40.7128], [-74.0055, 40.7130]]
... )
>>> coords, keys = inventory.get_coordinates()
>>> coords
[[[-122.4194, 37.7749], [-122.4180, 37.7750]],
 [[-74.0060, 40.7128], [-74.0055, 40.7130]]]
>>> keys
['asset1', 'asset2']
get_dataframe()

Convert the asset inventory into two structured DataFrames and count.

This method processes the internal asset inventory and returns:

  • A DataFrame containing the features of each asset, with support for multiple possible worlds(realizations).

  • A DataFrame containing centroid coordinates(longitude and latitude) for spatial operations.

  • The total number of assets in the inventory.

The method flattens feature lists into separate columns if multiple possible worlds exist. It also derives centroid coordinates from the GeoJSON geometry for each asset.

Returns:

  • Asset feature DataFrame (indexed by asset ID).

  • Asset geometry DataFrame with ‘Lat’ and ‘Lon’ columns.

  • Total number of assets (int).

Return type:

Tuple[pd.DataFrame, pd.DataFrame, int]

Raises:

ValueError – If a feature list’s length does not match the expected number of possible worlds.

get_extent(buffer='default')

Calculate the geographical extent of the inventory.

Parameters:

buffer (str or list[float]) –

A string or a list of 4 floats.

  • 'default' applies preset buffer values.

  • 'none' applies zero buffer values.

  • A list of 4 floats defines custom buffer values for each edge of the bounding box in the order: [minlon buffer, minlat buffer, maxlon buffer, maxlat buffer].

Returns:

A Shapely polygon representing the extent of the inventory, with buffer applied.

Return type:

shapely.geometry.box

Raises:

ValueError – If the buffer input is invalid.

Example

>>> inventory = AssetInventory()
>>> _ = inventory.add_asset('asset1', Asset(
...     asset_id='asset1',
...     coordinates=[[-122.4194, 37.7749]],
...     features={'type': 'building'}
... ))
>>> _ = inventory.add_asset('asset2', Asset(
...     asset_id='asset2',
...     coordinates=[[-74.0060, 40.7128]],
...     features={'type': 'bridge'}
... ))
>>> # Get extent with default buffer:
>>> extent_default = inventory.get_extent(buffer='default')
>>> print(extent_default.bounds)
(-122.4196, 37.7748, -74.0058, 40.712900000000005)
>>> # Get extent with no buffer:
>>> extent_none = inventory.get_extent(buffer='none')
>>> print(extent_none.bounds)
(-122.4194, 37.7749, -74.006, 40.7128)
>>> # Get extent with a custom buffer:
>>> extent_custom = inventory.get_extent(
...     buffer=[0.1, 0.1, 0.1, 0.1]
... )
>>> print(extent_custom.bounds)
(-122.51939999999999, 37.6749, -73.906, 40.8128)
get_geojson()

Generate a GeoJSON representation of the assets in the inventory.

The function constructs a valid GeoJSON FeatureCollection, where each asset is represented as a Feature. Each feature contains:

  • A geometry field defining a Point, LineString, or Polygon based on the asset’s coordinates.

  • A properties field containing asset-specific metadata.

Additionally, the GeoJSON output includes:

  • A timestamp indicating when the data was created.

  • The BRAILS package version (if available).

  • A Coordinate Reference System (crs) definition set to CRS84.

Returns:

A dictionary formatted as a GeoJSON FeatureCollection containing all assets in the inventory.

Return type:

dict

Note

Assets without geometry are excluded from the generated GeoJSON representation.

Example

>>> inventory = AssetInventory()
>>> _ = inventory.add_asset_coordinates(
...     'asset1',
...     coordinates=[[-122.4194, 37.7749]]
... )
>>> _ = inventory.add_asset_coordinates(
...     'asset2',
...     coordinates=[[-74.0060, 40.7128], [-73.935242, 40.730610]]
... )
>>> inventory_geojson = inventory.get_geojson()
>>> print(inventory_geojson)
{'type': 'FeatureCollection',
 'generated': '2025-08-11 02:49:47.520953',
 'brails_version': '4.0',
 'crs': {'type': 'name',
         'properties': {'name': 'urn:ogc:def:crs:OGC:1.3:CRS84'}},
 'features': [{'type': 'Feature', 'properties': {},
               'geometry': {'type': 'Point',
                            'coordinates': [-122.4194, 37.7749]}},
              {'type': 'Feature', 'properties': {},
               'geometry': {
                   'type': 'LineString',
                   'coordinates': [[-74.006, 40.7128],
                                   [-73.935242, 40.73061]]
                   }
               }
              ]
 }
get_multi_keys()

Identify features that contain multiple realizations across assets.

Iterates through all assets and returns two lists:

  • Keys associated with multi-valued features(i.e., lists).

  • All unique feature keys present in the inventory.

Returns:

  • A list of keys corresponding to multi-realization features.

  • A complete list of all unique feature keys in the inventory.

Return type:

Tuple[List[str], List[str]]

get_n_pw()

Get the number of possible worlds (realizations) in the inventory.

Returns:

The number of possible worlds stored in the inventory.

Return type:

int

get_random_sample(nsamples, seed=None)

Generate a smaller asset inventory with a random selection of assets.

This method randomly selects nsamples assets from the existing inventory and returns a new AssetInventory instance containing only these sampled assets. The randomness can be controlled using an optional seed for reproducibility.

Parameters:
  • nsamples (int) – The number of assets to randomly sample from the inventory. Must be a positive integer not exceeding the total number of assets.

  • seed (int or float or str or bytes or bytearray or None, optional) – A seed value for the random generator to ensure reproducibility. If None, the system default (current system time) is used.

Returns:

A new AssetInventory instance containing the randomly selected subset of assets.

Return type:

AssetInventory

Raises:

ValueError – If nsamples is not a positive integer or exceeds the number of assets in the inventory.

Example

>>> inventory = AssetInventory()
>>> _ = inventory.add_asset('asset1', Asset(
...     asset_id='asset1',
...     coordinates=[[-122.4194, 37.7749]],
...     features={'type': 'building'}
... ))
>>> _ = inventory.add_asset('asset2', Asset(
...     asset_id='asset2',
...     coordinates=[[-74.0060, 40.7128]],
...     features={'type': 'bridge'}
... ))
>>> _ = inventory.add_asset('asset3', Asset(
...     asset_id='asset3',
...     coordinates=[[2.3522, 48.8566]],
...     features={'type': 'tower'}
... ))
>>> sample_inventory = inventory.get_random_sample(
...     nsamples=2,
...     seed=42
... )
>>> sorted(sample_inventory.get_asset_ids())
['asset1', 'asset3']
get_world_realization(id=0)

Extract a single realization(possible world) from an inventory.

This method generates a new AssetInventory instance where all features containing multiple possible worlds are reduced to a single realization specified by id. Features that are not lists are copied as-is .

Parameters:

id (int, default=0) – The index of the realization to extract. Must be within the range of available possible worlds(0-based indexing).

Returns:

A new inventory object representing the selected realization.

Return type:

AssetInventory

Raises:
  • Exception – If id > 0 but the inventory only contains a single realization.

  • Exception – If any feature has fewer realizations than the specified id.

join(inventory_to_join, method='GetPointsInPolygons')

Merge with another AssetInventory using specified spatial join method.

Parameters:
  • inventory_to_join (AssetInventory) – The inventory to be joined with the current one.

  • method (str) – The spatial join method to use. Defaults to GetPointsInPolygons. The method defines how the join operation is executed between inventories.

Raises:

TypeError – If inventory_to_join is not an instance of AssetInventory or if method is not a string.

Returns:

This method modifies the AssetInventory instance in place.

Return type:

None

Example

>>> polygon1_asset = Asset('polygon1', [
...     [-122.40, 37.75],
...     [-122.40, 37.76],
...     [-122.39, 37.76],
...     [-122.39, 37.75],
...     [-122.40, 37.75]
... ])
>>> polygon2_asset = Asset('polygon2', [
...     [-122.38, 37.77],
...     [-122.38, 37.78],
...     [-122.37, 37.78],
...     [-122.37, 37.77],
...     [-122.38, 37.77]
... ])
>>> poly_inventory = AssetInventory()
>>> _ = poly_inventory.add_asset(
...     asset_id='polygon1',
...     asset=polygon1_asset
... )
>>> _ = poly_inventory.add_asset(
...     asset_id='polygon2',
...     asset=polygon2_asset
... )
>>> poly_inventory.print_info()
AssetInventory
Inventory stored in:  dict
Key:  polygon1 Asset:
    Coordinates:  [[-122.4, 37.75], [-122.4, 37.76],
                   [-122.39, 37.76], [-122.39, 37.75],
                   [-122.4, 37.75]]
    Features:  {}
Key:  polygon2 Asset:
    Coordinates:  [[-122.38, 37.77], [-122.38, 37.78],
                   [-122.37, 37.78], [-122.37, 37.77],
                   [-122.38, 37.77]]
    Features:  {}
>>> # This point lies within polygon1's boundaries:
>>> point_inventory = AssetInventory()
>>> _ = point_inventory.add_asset(
...     asset_id = 'point1',
...     asset = Asset(
...         'point1',
...         [[-122.395, 37.755]],
...         features={'FFE':6.8}
...     )
... )
>>> poly_inventory.join(point_inventory)
Joining inventories using GetPointsInPolygons method...
Identified a total of 1 matched points.
Inventories successfully joined.
>>> poly_inventory.print_info()
AssetInventory
Inventory stored in:  dict
Key:  polygon1 Asset:
    Coordinates:  [[-122.4, 37.75], [-122.4, 37.76],
                   [-122.39, 37.76], [-122.39, 37.75],
                   [-122.4, 37.75]]
    Features:  {'FFE': 6.8}
Key:  polygon2 Asset:
    Coordinates:  [[-122.38, 37.77], [-122.38, 37.78],
                   [-122.37, 37.78], [-122.37, 37.77],
                   [-122.38, 37.77]]
    Features:  {}
print_info()

Print summary information about the AssetInventory.

This method outputs the name of the class , the type of data structure used to store the inventory, and basic information about each asset in the inventory, including its key and features.

Returns:

None

Example

>>> inventory = AssetInventory()
>>> _ = inventory.add_asset(
...     asset_id='building1',
...     asset=Asset(
...         'building1',
...         [[-122.40, 37.75], [-122.40, 37.76],
...          [-122.39, 37.76], [-122.39, 37.75],
...          [-122.40, 37.75]],
...         features={'height': 12.5}
...     )
... )
>>> _ = inventory.add_asset(
...     asset_id='building2',
...     asset=Asset(
...         'building2',
...         [[-122.38, 37.77], [-122.38, 37.78],
...          [-122.37, 37.78], [-122.37, 37.77],
...          [-122.38, 37.77]],
...         features={'height': 8.0}
...     )
... )
>>> inventory.print_info()
AssetInventory
Inventory stored in:  dict
Key:  building1 Asset:
    Coordinates:  [[-122.4, 37.75], [-122.4, 37.76],
                   [-122.39, 37.76], [-122.39, 37.75],
                   [-122.4, 37.75]]
    Features:  {'height': 12.5}
Key:  building2 Asset:
    Coordinates:  [[-122.38, 37.77], [-122.38, 37.78],
                   [-122.37, 37.78], [-122.37, 37.77],
                   [-122.38, 37.77]]
    Features:  {'height': 8.0}
read_from_csv(file_path, keep_existing, str_type='building', id_column=None)

Read inventory data from a CSV file and add it to the inventory.

Parameters:
  • file_path (str) – The path to the CSV file

  • keep_existing (bool) – If False, the inventory will be initialized

  • str_type (str) – building or bridge

  • id_column (str) – The name of column that contains id values. If None, new indices will be assigned

Returns:

True if assets were addded, False otherwise.

Return type:

bool

remove_asset(asset_id)

Remove an asset from the inventory.

Parameters:

asset_id (str or int) – The unique identifier for the asset.

Returns:

True if asset was removed, False otherwise.

Return type:

bool

Example

>>> inventory = AssetInventory()
>>> _ = inventory.add_asset(
...     asset_id='building1',
...     asset=Asset(
...         'building1',
...         [[-122.40, 37.75], [-122.40, 37.76],
...          [-122.39, 37.76], [-122.39, 37.75],
...          [-122.40, 37.75]],
...         features={'height': 12.5}
...     )
... )
>>> inventory.remove_asset('building1')
True
>>> inventory.print_info()
AssetInventory
Inventory stored in:  dict
remove_features(features_to_remove)

Remove specified features from all assets in the inventory.

Parameters:

features_to_remove (Iterable[str]) – An iterable of feature keys to remove from each Asset. Accepts types such as list, tuple, dict_keys, etc.

Returns:

True if at least one feature was removed from any asset, False otherwise.

Return type:

bool

Raises:

TypeError – If features_to_remove is not an iterable of strings.

Example

>>> inventory = AssetInventory()
>>> _ = inventory.add_asset(
...     asset_id='building1',
...     asset=Asset(
...         'building1',
...         [[-122.40, 37.75], [-122.40, 37.76],
...          [-122.39, 37.76], [-122.39, 37.75],
...          [-122.40, 37.75]],
...         features={'height': 12.5, 'floors': 3}
...     )
... )
>>> _ = inventory.add_asset(
...     asset_id='building2',
...     asset=Asset(
...         'building2',
...         [[-122.38, 37.77], [-122.38, 37.78],
...          [-122.37, 37.78], [-122.37, 37.77],
...          [-122.38, 37.77]],
...         features={'height': 8.0, 'floors': 2}
...     )
... )
>>> inventory.remove_features(['floors'])
True
>>> inventory.print_info()
AssetInventory
Inventory stored in:  dict
Key:  building1 Asset:
    Coordinates:  [[-122.4, 37.75], [-122.4, 37.76],
                   [-122.39, 37.76], [-122.39, 37.75],
                   [-122.4, 37.75]]
    Features:  {'height': 12.5}
Key:  building2 Asset:
    Coordinates:  [[-122.38, 37.77], [-122.38, 37.78],
                   [-122.37, 37.78], [-122.37, 37.77],
                   [-122.38, 37.77]]
    Features:  {'height': 8.0}
update_world_realization(id, world_realization)

Update the current AssetInventory with a specific world realization.

This method integrates feature values from a single-world world_realization inventory into the current multi-world inventory by updating the realization at the specified index id.

Parameters:
  • id (int) – The index of the world(realization) to update. Must be less than self.n_pw.

  • world_realization (AssetInventory) – An AssetInventory instance representing a single realization of the world. All features in this inventory must be scalar (i.e., not lists).

Raises:

Exception

  • If the specified id is not within the valid range of realizations. - If world_realization contains features with multiple realizations.

write_to_geojson(output_file='')

Write inventory to a GeoJSON file and return the GeoJSON dictionary.

This method generates a GeoJSON representation of the asset inventory, writes it to the specified file path (if provided), and returns the GeoJSON object.

Parameters:

output_file (str, optional) – Path to the output GeoJSON file. If empty, no file is written.

Returns:

A dictionary containing the GeoJSON FeatureCollection.

Return type:

Dict

Examples

Define an AssetInventory consisting of a single asset.

>>> inventory = AssetInventory()
>>> inventory.add_asset(
...     asset_id='asset1',
...     asset=Asset(
...         'asset1',
...         [
...             [-122.40, 37.75],
...             [-122.40, 37.76],
...             [-122.39, 37.76],
...             [-122.39, 37.75],
...             [-122.40, 37.75]
...         ],
...         features={'name': 'Building A', 'roofHeight': 22.6}
...     )
... )

Write the AssetInventory data into a GeoJSON dictionary.

>>> geojson_dict = inventory.write_to_geojson()
>>> print(geojson_dict['features'])
[{'type': 'Feature', 'properties': {'name': 'Building A',
'roofHeight': 22.6}, 'geometry': {'type': 'Polygon', 'coordinates':
[[[-122.4, 37.75], [-122.4, 37.76], [-122.39, 37.76],
[-122.39, 37.75], [-122.4, 37.75]]]}, 'id': '0'}]

Write the AssetInventory data in a GeoJSON dictionary and a file named output.geojson.

>>> geojson_written = inventory.write_to_geojson('output.geojson')
Wrote 1 assets to {../output.geojson}
brails.types.asset_inventory.clean_floats(obj)

Recursively convert float values that are mathematically integers to int.

This function traverses a nested structure (e.g., dict, list, JSON-like object) and converts any float that is numerically equivalent to an integer into an int, improving the readability and cleanliness of the output, especially for serialization.

Parameters:

obj (Any) – A JSON-like object (dict, list, or primitive value) to process.

Returns:

The input object with eligible floats converted to integers.

Return type:

Any