Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions docs/tutorials/use_pointcloud_data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@

# Tutorial: Incorporate ALS Point Cloud Data into a FastFuels Domain
This tutorial demonstrates how to incorporate airborne laser scanning (ALS / LiDAR) point cloud data into an existing FastFuels domain. It utilizes a point cloud–derived canopy structure to inform the tree inventory and canopy fuel grids, enabling higher‐fidelity fuels representation.

## Prerequisites

Before starting this tutorial, make sure you have:
- FastFuels SDK installed (`pip install fastfuels-sdk`)
- A valid FastFuels API key
- Basic familiarity with Python and GeoPandas

## What You'll Learn

By the end of this tutorial, you'll know how to:
- Create an ALS point cloud within a FastFuels domain
- Generate a tree inventory informed by the ALS data

## Step 1: Create a FastFuels Domain

For the polygon created by the coordinates:
```python
import geopandas as gpd
from shapely.geometry import Polygon

# Define the polygon coordinates for Lubrecht area
coordinates = [
[-113.43635167116199,46.89738742250387],
[-113.44842074255764,46.8894785976307],
[-113.44763362920567,46.88740657162339],
[-113.44993666456837,46.8858524995899],
[-113.44923700825561,46.88429838253265],
[-113.44273603501621,46.88389988372731],
[-113.43538964373204,46.882365635689325],
[-113.42005550954369,46.88523484307359],
[-113.42329141999039,46.88919967571519],
[-113.42361209580038,46.892566564773205],
[-113.4263524163587,46.89527586047467],
[-113.42696461563226,46.895973083547176],
[-113.42853884233625,46.89916027357725],
[-113.42711037736427,46.90210825569156],
[-113.42798494775504,46.90336309078498],
[-113.42932595568779,46.903004569469715],
[-113.43241610440292,46.90099282206219],
[-113.43445676864847,46.8980248588519],
[-113.43635167116199,46.89738742250387]
]

# Create a GeoDataFrame
polygon = Polygon(coordinates)
roi = gpd.GeoDataFrame(
geometry=[polygon],
crs="EPSG:4326" # WGS 84 coordinate system
)

from fastfuels_sdk.domains import Domain

domain = Domain.from_geodataframe(
geodataframe=roi,
name="Blue Mountain ROI",
description="Test area in Lubrecht Experimental Forest",
horizontal_resolution=2.0, # 2-meter horizontal resolution
vertical_resolution=1.0 # 1-meter vertical resolution
)

print(f"Created domain with ID: {domain.id}")
```

## Step 2: Create an ALS point cloud within FastFuels

Next, use 3DEP data to generate a feature point cloud:

```python
# 1.
from fastfuels_sdk.pointclouds import PointClouds

# 2. Correct Method Name & 3. Added Required 'sources' argument
als_pointcloud = (
PointClouds.from_domain_id(domain.id)
.create_als_point_cloud(sources=["3DEP"])
)

# This works because create_als_point_cloud returns the child object
als_pointcloud.wait_until_completed()

```

## Step 3: Create Tree Inventory using the point cloud data

Create a tree inventory and generate the canopy fuel grid:

```python
from fastfuels_sdk.inventories import Inventories
from fastfuels_sdk.grids import TreeGridBuilder

# Create tree inventory
# Note: Ensure Step 2 (Point Cloud creation) is fully completed before running this
tree_inventory = Inventories.from_domain_id(
domain.id
).create_tree_inventory_from_point_cloud()
tree_inventory.wait_until_completed()
```

## Next Steps
For additional guidance and complementary workflows, refer back to the “Create and Export QUIC-Fire Inputs with FastFuels SDK” tutorial.
4 changes: 3 additions & 1 deletion fastfuels_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
)
from fastfuels_sdk.exports import Export
from fastfuels_sdk.convenience import export_roi, export_roi_to_quicfire

from fastfuels_sdk.pointclouds import PointClouds, AlsPointCloud

__all__ = [
"Domain",
Expand All @@ -34,4 +34,6 @@
"Export",
"export_roi",
"export_roi_to_quicfire",
"PointClouds",
"AlsPointCloud",
]
31 changes: 31 additions & 0 deletions fastfuels_sdk/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
SurfaceGridApi,
TopographyGridApi,
FeatureGridApi,
PointCloudApi,
AlsPointCloudApi,
)

_client: Optional[ApiClient] = None
Expand All @@ -32,6 +34,8 @@
_surface_grid_api: Optional[SurfaceGridApi] = None
_topography_grid_api: Optional[TopographyGridApi] = None
_feature_grid_api: Optional[FeatureGridApi] = None
_point_cloud_api: Optional[PointCloudApi] = None
_als_point_cloud_api: Optional[AlsPointCloudApi] = None


def set_api_key(api_key: str) -> None:
Expand All @@ -46,6 +50,7 @@ def set_api_key(api_key: str) -> None:
global _client, _domains_api, _inventories_api, _tree_inventory_api
global _features_api, _road_feature_api, _water_feature_api
global _grids_api, _tree_grid_api, _surface_grid_api, _topography_grid_api, _feature_grid_api
global _point_cloud_api, _als_point_cloud_api

_client = None
_domains_api = None
Expand All @@ -59,6 +64,8 @@ def set_api_key(api_key: str) -> None:
_surface_grid_api = None
_topography_grid_api = None
_feature_grid_api = None
_point_cloud_api = None
_als_point_cloud_api = None

os.environ["FASTFUELS_API_KEY"] = api_key

Expand Down Expand Up @@ -244,3 +251,27 @@ def get_feature_grid_api() -> FeatureGridApi:
if _feature_grid_api is None:
_feature_grid_api = FeatureGridApi(ensure_client())
return _feature_grid_api


def get_point_cloud_api() -> PointCloudApi:
"""Get the cached PointCloudApi instance, creating it if necessary.

Returns:
The PointCloudApi instance
"""
global _point_cloud_api
if _point_cloud_api is None:
_point_cloud_api = PointCloudApi(ensure_client())
return _point_cloud_api


def get_als_point_cloud_api() -> AlsPointCloudApi:
"""Get the cached AlsPointCloudApi instance, creating it if necessary.

Returns:
The AlsPointCloudApi instance
"""
global _als_point_cloud_api
if _als_point_cloud_api is None:
_als_point_cloud_api = AlsPointCloudApi(ensure_client())
return _als_point_cloud_api
38 changes: 30 additions & 8 deletions fastfuels_sdk/client_library/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# Define package exports
__all__ = [
"APIKeysApi",
"AlsPointCloudApi",
"ApplicationsApi",
"CookiesApi",
"DomainsApi",
Expand All @@ -27,6 +28,7 @@
"GridsApi",
"IndexApi",
"InventoriesApi",
"PointCloudApi",
"RoadFeatureApi",
"SurfaceGridApi",
"TopographyGridApi",
Expand All @@ -43,7 +45,13 @@
"ApiAttributeError",
"ApiException",
"Access",
"AlsPointCloud",
"AlsPointCloudSource",
"ApiResourcesInventoriesTreeSchemaUploadResponse",
"ApiResourcesPointcloudsAlsSchemaProcessingError",
"ApiResourcesPointcloudsAlsSchemaUploadResponse",
"Application",
"CreateAlsPointCloudRequest",
"CreateApplicationRequest",
"CreateDomainRequest",
"CreateDomainRequestFeature",
Expand All @@ -66,6 +74,8 @@
"FeatureGridAttribute",
"FeatureType",
"Features",
"Fueldepth",
"Fuelload",
"GeoJSONFeature",
"GeoJSONFeatureCollection",
"GeoJSONStyleProperties",
Expand All @@ -90,22 +100,23 @@
"MultiPolygon",
"Operator",
"Point",
"PointCloud",
"Polygon",
"ProcessingError",
"RoadFeature",
"RoadFeatureSource",
"Scope",
"SurfaceGrid",
"SurfaceGridAttribute",
"SurfaceGridFBFMSource",
"SurfaceGridFuelDepthSource",
"SurfaceGridFuelLoadSource",
"SurfaceGridFuelMoistureSource",
"SurfaceGridInterpolationMethod",
"SurfaceGridLandfireFBFM40FuelLoadSource",
"SurfaceGridLandfireFBFM40Group",
"SurfaceGridLandfireFBFM40SAVRSource",
"SurfaceGridLandfireFBFM40Source",
"SurfaceGridLandfireFCCSFuelLoadSource",
"SurfaceGridLandfireFCCSGroup",
"SurfaceGridLandfireFCCSSource",
"SurfaceGridModification",
"SurfaceGridModificationAction",
"SurfaceGridModificationCondition",
Expand All @@ -121,6 +132,7 @@
"SurfaceGridUniformFBFM40Value",
"SurfaceGridUniformValue",
"SurfaceGridUniformValueBySizeClass",
"ThreeDEPSource",
"TopographyGrid",
"TopographyGrid3DEPSource",
"TopographyGrid3DEPSourceAspect",
Expand Down Expand Up @@ -160,7 +172,6 @@
"TreeMapSource",
"TreeMapVersion",
"UpdateDomainRequest",
"UploadResponse",
"ValidationError",
"ValidationErrorLocInner",
"WaterFeature",
Expand All @@ -169,6 +180,7 @@

# import apis into sdk package
from fastfuels_sdk.client_library.api.api_keys_api import APIKeysApi as APIKeysApi
from fastfuels_sdk.client_library.api.als_point_cloud_api import AlsPointCloudApi as AlsPointCloudApi
from fastfuels_sdk.client_library.api.applications_api import ApplicationsApi as ApplicationsApi
from fastfuels_sdk.client_library.api.cookies_api import CookiesApi as CookiesApi
from fastfuels_sdk.client_library.api.domains_api import DomainsApi as DomainsApi
Expand All @@ -177,6 +189,7 @@
from fastfuels_sdk.client_library.api.grids_api import GridsApi as GridsApi
from fastfuels_sdk.client_library.api.index_api import IndexApi as IndexApi
from fastfuels_sdk.client_library.api.inventories_api import InventoriesApi as InventoriesApi
from fastfuels_sdk.client_library.api.point_cloud_api import PointCloudApi as PointCloudApi
from fastfuels_sdk.client_library.api.road_feature_api import RoadFeatureApi as RoadFeatureApi
from fastfuels_sdk.client_library.api.surface_grid_api import SurfaceGridApi as SurfaceGridApi
from fastfuels_sdk.client_library.api.topography_grid_api import TopographyGridApi as TopographyGridApi
Expand All @@ -197,7 +210,13 @@

# import models into sdk package
from fastfuels_sdk.client_library.models.access import Access as Access
from fastfuels_sdk.client_library.models.als_point_cloud import AlsPointCloud as AlsPointCloud
from fastfuels_sdk.client_library.models.als_point_cloud_source import AlsPointCloudSource as AlsPointCloudSource
from fastfuels_sdk.client_library.models.api_resources_inventories_tree_schema_upload_response import ApiResourcesInventoriesTreeSchemaUploadResponse as ApiResourcesInventoriesTreeSchemaUploadResponse
from fastfuels_sdk.client_library.models.api_resources_pointclouds_als_schema_processing_error import ApiResourcesPointcloudsAlsSchemaProcessingError as ApiResourcesPointcloudsAlsSchemaProcessingError
from fastfuels_sdk.client_library.models.api_resources_pointclouds_als_schema_upload_response import ApiResourcesPointcloudsAlsSchemaUploadResponse as ApiResourcesPointcloudsAlsSchemaUploadResponse
from fastfuels_sdk.client_library.models.application import Application as Application
from fastfuels_sdk.client_library.models.create_als_point_cloud_request import CreateAlsPointCloudRequest as CreateAlsPointCloudRequest
from fastfuels_sdk.client_library.models.create_application_request import CreateApplicationRequest as CreateApplicationRequest
from fastfuels_sdk.client_library.models.create_domain_request import CreateDomainRequest as CreateDomainRequest
from fastfuels_sdk.client_library.models.create_domain_request_feature import CreateDomainRequestFeature as CreateDomainRequestFeature
Expand All @@ -220,6 +239,8 @@
from fastfuels_sdk.client_library.models.feature_grid_attribute import FeatureGridAttribute as FeatureGridAttribute
from fastfuels_sdk.client_library.models.feature_type import FeatureType as FeatureType
from fastfuels_sdk.client_library.models.features import Features as Features
from fastfuels_sdk.client_library.models.fueldepth import Fueldepth as Fueldepth
from fastfuels_sdk.client_library.models.fuelload import Fuelload as Fuelload
from fastfuels_sdk.client_library.models.geo_json_feature import GeoJSONFeature as GeoJSONFeature
from fastfuels_sdk.client_library.models.geo_json_feature_collection import GeoJSONFeatureCollection as GeoJSONFeatureCollection
from fastfuels_sdk.client_library.models.geo_json_style_properties import GeoJSONStyleProperties as GeoJSONStyleProperties
Expand All @@ -244,22 +265,23 @@
from fastfuels_sdk.client_library.models.multi_polygon import MultiPolygon as MultiPolygon
from fastfuels_sdk.client_library.models.operator import Operator as Operator
from fastfuels_sdk.client_library.models.point import Point as Point
from fastfuels_sdk.client_library.models.point_cloud import PointCloud as PointCloud
from fastfuels_sdk.client_library.models.polygon import Polygon as Polygon
from fastfuels_sdk.client_library.models.processing_error import ProcessingError as ProcessingError
from fastfuels_sdk.client_library.models.road_feature import RoadFeature as RoadFeature
from fastfuels_sdk.client_library.models.road_feature_source import RoadFeatureSource as RoadFeatureSource
from fastfuels_sdk.client_library.models.scope import Scope as Scope
from fastfuels_sdk.client_library.models.surface_grid import SurfaceGrid as SurfaceGrid
from fastfuels_sdk.client_library.models.surface_grid_attribute import SurfaceGridAttribute as SurfaceGridAttribute
from fastfuels_sdk.client_library.models.surface_grid_fbfm_source import SurfaceGridFBFMSource as SurfaceGridFBFMSource
from fastfuels_sdk.client_library.models.surface_grid_fuel_depth_source import SurfaceGridFuelDepthSource as SurfaceGridFuelDepthSource
from fastfuels_sdk.client_library.models.surface_grid_fuel_load_source import SurfaceGridFuelLoadSource as SurfaceGridFuelLoadSource
from fastfuels_sdk.client_library.models.surface_grid_fuel_moisture_source import SurfaceGridFuelMoistureSource as SurfaceGridFuelMoistureSource
from fastfuels_sdk.client_library.models.surface_grid_interpolation_method import SurfaceGridInterpolationMethod as SurfaceGridInterpolationMethod
from fastfuels_sdk.client_library.models.surface_grid_landfire_fbfm40_fuel_load_source import SurfaceGridLandfireFBFM40FuelLoadSource as SurfaceGridLandfireFBFM40FuelLoadSource
from fastfuels_sdk.client_library.models.surface_grid_landfire_fbfm40_group import SurfaceGridLandfireFBFM40Group as SurfaceGridLandfireFBFM40Group
from fastfuels_sdk.client_library.models.surface_grid_landfire_fbfm40_savr_source import SurfaceGridLandfireFBFM40SAVRSource as SurfaceGridLandfireFBFM40SAVRSource
from fastfuels_sdk.client_library.models.surface_grid_landfire_fbfm40_source import SurfaceGridLandfireFBFM40Source as SurfaceGridLandfireFBFM40Source
from fastfuels_sdk.client_library.models.surface_grid_landfire_fccs_fuel_load_source import SurfaceGridLandfireFCCSFuelLoadSource as SurfaceGridLandfireFCCSFuelLoadSource
from fastfuels_sdk.client_library.models.surface_grid_landfire_fccs_group import SurfaceGridLandfireFCCSGroup as SurfaceGridLandfireFCCSGroup
from fastfuels_sdk.client_library.models.surface_grid_landfire_fccs_source import SurfaceGridLandfireFCCSSource as SurfaceGridLandfireFCCSSource
from fastfuels_sdk.client_library.models.surface_grid_modification import SurfaceGridModification as SurfaceGridModification
from fastfuels_sdk.client_library.models.surface_grid_modification_action import SurfaceGridModificationAction as SurfaceGridModificationAction
from fastfuels_sdk.client_library.models.surface_grid_modification_condition import SurfaceGridModificationCondition as SurfaceGridModificationCondition
Expand All @@ -275,6 +297,7 @@
from fastfuels_sdk.client_library.models.surface_grid_uniform_fbfm40_value import SurfaceGridUniformFBFM40Value as SurfaceGridUniformFBFM40Value
from fastfuels_sdk.client_library.models.surface_grid_uniform_value import SurfaceGridUniformValue as SurfaceGridUniformValue
from fastfuels_sdk.client_library.models.surface_grid_uniform_value_by_size_class import SurfaceGridUniformValueBySizeClass as SurfaceGridUniformValueBySizeClass
from fastfuels_sdk.client_library.models.three_dep_source import ThreeDEPSource as ThreeDEPSource
from fastfuels_sdk.client_library.models.topography_grid import TopographyGrid as TopographyGrid
from fastfuels_sdk.client_library.models.topography_grid3_dep_source import TopographyGrid3DEPSource as TopographyGrid3DEPSource
from fastfuels_sdk.client_library.models.topography_grid3_dep_source_aspect import TopographyGrid3DEPSourceAspect as TopographyGrid3DEPSourceAspect
Expand Down Expand Up @@ -314,7 +337,6 @@
from fastfuels_sdk.client_library.models.tree_map_source import TreeMapSource as TreeMapSource
from fastfuels_sdk.client_library.models.tree_map_version import TreeMapVersion as TreeMapVersion
from fastfuels_sdk.client_library.models.update_domain_request import UpdateDomainRequest as UpdateDomainRequest
from fastfuels_sdk.client_library.models.upload_response import UploadResponse as UploadResponse
from fastfuels_sdk.client_library.models.validation_error import ValidationError as ValidationError
from fastfuels_sdk.client_library.models.validation_error_loc_inner import ValidationErrorLocInner as ValidationErrorLocInner
from fastfuels_sdk.client_library.models.water_feature import WaterFeature as WaterFeature
Expand Down
2 changes: 2 additions & 0 deletions fastfuels_sdk/client_library/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# import apis into api package
from fastfuels_sdk.client_library.api.api_keys_api import APIKeysApi
from fastfuels_sdk.client_library.api.als_point_cloud_api import AlsPointCloudApi
from fastfuels_sdk.client_library.api.applications_api import ApplicationsApi
from fastfuels_sdk.client_library.api.cookies_api import CookiesApi
from fastfuels_sdk.client_library.api.domains_api import DomainsApi
Expand All @@ -10,6 +11,7 @@
from fastfuels_sdk.client_library.api.grids_api import GridsApi
from fastfuels_sdk.client_library.api.index_api import IndexApi
from fastfuels_sdk.client_library.api.inventories_api import InventoriesApi
from fastfuels_sdk.client_library.api.point_cloud_api import PointCloudApi
from fastfuels_sdk.client_library.api.road_feature_api import RoadFeatureApi
from fastfuels_sdk.client_library.api.surface_grid_api import SurfaceGridApi
from fastfuels_sdk.client_library.api.topography_grid_api import TopographyGridApi
Expand Down
Loading