Skip to content

Upload disturbance polygons as a feature - #746

Open
lindsaywiard wants to merge 2 commits into
mainfrom
744-upload-disturbance-polygons-as-a-feature
Open

lindsaywiard wants to merge 2 commits into
mainfrom
744-upload-disturbance-polygons-as-a-feature

Conversation

@lindsaywiard

Copy link
Copy Markdown
Collaborator

A user with a fire perimeter or treatment units, and no FDist raster, had to rasterize the polygons before the API could use them as a disturbance. This adds a disturbance feature: the user uploads a file of polygons, each carrying an FDist code. A later change lets a fuel model request point at the feature.

Changes

  • lib/landfire/config.py: add VALID_FDIST_CODES, every code 100 * D_TYPE + 10 * D_SEVERITY + D_TIME with D_TYPE 1-7, D_SEVERITY 1-3 and D_TIME 1-3, and export it from lib.landfire.
  • features/schema.py, features/router.py: add disturbance to FeatureType and mount the new router at /disturbance.
  • features/disturbance/schema.py: the request body is a GeoJSON FeatureCollection of Polygon and MultiPolygon features with at least one feature.
    • Each feature needs an integer properties.fdist that is a valid code; 0 is not accepted.
    • name, type, year and severity are optional labels, stored as given and never checked against the code. Other properties are ignored.
    • The body needs an integer mapping_year (1900 to 2100), the year the last digit of each FDist code is counted back from. It is stored in the feature's source.
  • features/disturbance/validate.py: reads the CRS from the crs block (any CRS is accepted, EPSG:4326 when there is none, 422 if it can't be parsed), builds the GeoDataFrame, and ensures at least one polygon intersects the domain. It also computes the bounds in the file's own CRS.
  • features/disturbance/router.py: POST /domains/{domain_id}/features/disturbance/geojson. As with layerset, it writes synchronously with no worker job or weekly dispatch budget. It saves the GeoParquet to {domain_id}/{feature_id}.parquet in the features bucket and a feature record with status completed and a georeference.
  • features/disturbance/examples.py: documented examples (minimal, with labels, with metadata) over the Blackfoot test domain.
  • The endpoint docs explain the code: the last digit counts back from mapping_year (1 for that year, 2 for the previous four years, 3 for five to nine years earlier). Where polygons overlap, the more recent disturbance wins and the later feature in the file wins a tie.

Tests

  • Schema: valid and invalid codes, strict integers, optional labels, the mapping_year range, geometry types, and the documented examples parsing.
  • Validation (unit tests on a make_domain_data domain): URN and bare CRS forms, the lat/lon default, a different UTM zone, an unparseable CRS, bounds in the file's CRS, no overlap, partial overlap, one polygon inside, and the nullable year column.
  • Router (integration): creating a feature with and without metadata, the 404 cases, no owner_id in the response, the georeference, lat/lon input, and 422 for an empty collection, a missing or out-of-range mapping_year, an invalid fdist and no overlap. The documented examples are translated onto the test domain and each creates a feature.

@lindsaywiard lindsaywiard linked an issue Oct 21, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upload disturbance polygons as a feature

1 participant