Skip to content

Commit

Permalink
Task/zone units frontend (#3204)
Browse files Browse the repository at this point in the history
- Generalizes the concept of `FireZone` to `FireShape` throughout the codebase
- Adds migration for adding fire zone unit shape type
- Adds migration for calculating fire zone unit combustible area
- Points frontend layers to the fire zone unit pmtiles files
  • Loading branch information
conbrad authored Nov 1, 2023
1 parent b781237 commit 38ec422
Show file tree
Hide file tree
Showing 18 changed files with 219 additions and 150 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
shell: bash
run: |
oc login "${{ secrets.OPENSHIFT_CLUSTER }}" --token="${{ secrets.OC4_DEV_TOKEN }}"
EPHEMERAL_STORAGE=True bash openshift/scripts/oc_provision_db.sh ${SUFFIX} apply
EPHEMERAL_STORAGE=True CPU_REQUEST=75m CPU_LIMIT=2000m bash openshift/scripts/oc_provision_db.sh ${SUFFIX} apply
prepare-dev-database-backups:
name: Prepare Dev Database Backups
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""compute zone unit combustible area
Revision ID: d5115b761e39
Revises: 5b745fe0bd7a
Create Date: 2023-10-31 12:24:36.889483
"""
from alembic import op
import sqlalchemy as sa
import geoalchemy2
from sqlalchemy.orm.session import Session
from app.auto_spatial_advisory.calculate_combustible_land_area import calculate_combustible_area_by_fire_zone, get_fuel_types_from_object_store

# revision identifiers, used by Alembic.
revision = 'd5115b761e39'
down_revision = 'f2e027a47a3f'
branch_labels = None
depends_on = None

shape_type_table = sa.Table('advisory_shape_types', sa.MetaData(),
sa.Column('id', sa.Integer),
sa.Column('name', sa.String))

shape_table = sa.Table('advisory_shapes', sa.MetaData(),
sa.Column('id', sa.Integer),
sa.Column('source_identifier', sa.String),
sa.Column('shape_type', sa.Integer),
sa.Column('geom', geoalchemy2.Geometry))


def get_fire_zone_unit_shape_type_id(session: Session):
statement = shape_type_table.select().where(shape_type_table.c.name == 'fire_zone_unit')
result = session.execute(statement).fetchone()
return result.id


def get_fire_zone_units(session: Session, fire_zone_type_id: int):
statement = shape_table.select().where(shape_table.c.shape_type == fire_zone_type_id)
result = session.execute(statement).fetchall()
return result


def upgrade():
session = Session(bind=op.get_bind())

with get_fuel_types_from_object_store() as fuel_types:
# fetch all fire zones from DB
fire_zone_shape_type_id = get_fire_zone_unit_shape_type_id(session)
zone_units = get_fire_zone_units(session, fire_zone_shape_type_id)

zone_areas = calculate_combustible_area_by_fire_zone(fuel_types, zone_units)
for tuple in zone_areas:
op.execute('UPDATE advisory_shapes SET combustible_area={} WHERE source_identifier LIKE \'{}\''.format(
tuple[1], tuple[0])
)


def downgrade():
session = Session(bind=op.get_bind())
fire_zone_shape_id = get_fire_zone_unit_shape_type_id(session)
zones = get_fire_zone_units(session, fire_zone_shape_id)

for zone in zones:
op.execute('UPDATE advisory_shapes SET combustible_area = NULL WHERE source_identifier LIKE \'{}\''.format(
str(zone.source_identifier)
))
20 changes: 10 additions & 10 deletions api/app/routers/fba.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
get_run_datetimes,
get_zonal_elevation_stats)
from app.db.models.auto_spatial_advisory import RunTypeEnum
from app.schemas.fba import (ClassifiedHfiThresholdFuelTypeArea, FireCenterListResponse, FireZoneAreaListResponse,
FireZoneArea, FireZoneElevationStats, FireZoneElevationStatsByThreshold,
from app.schemas.fba import (ClassifiedHfiThresholdFuelTypeArea, FireCenterListResponse, FireShapeAreaListResponse,
FireShapeArea, FireZoneElevationStats, FireZoneElevationStatsByThreshold,
FireZoneElevationStatsListResponse, SFMSFuelType, HfiThreshold)
from app.auth import authentication_required, audit
from app.wildfire_one.wfwx_api import (get_auth_header, get_fire_centers)
Expand All @@ -39,12 +39,12 @@ async def get_all_fire_centers(_=Depends(authentication_required)):
return FireCenterListResponse(fire_centers=fire_centers)


@router.get('/fire-zone-areas/{run_type}/{run_datetime}/{for_date}',
response_model=FireZoneAreaListResponse)
async def get_zones(run_type: RunType, run_datetime: datetime, for_date: date, _=Depends(authentication_required)):
""" Return area of each zone, and percentage of area of zone with high hfi. """
@router.get('/fire-shape-areas/{run_type}/{run_datetime}/{for_date}',
response_model=FireShapeAreaListResponse)
async def get_shapes(run_type: RunType, run_datetime: datetime, for_date: date, _=Depends(authentication_required)):
""" Return area of each zone unit shape, and percentage of area of zone unit shape with high hfi. """
async with get_async_read_session_scope() as session:
zones = []
shapes = []

rows = await get_hfi_area(session,
RunTypeEnum(run_type.value),
Expand All @@ -55,13 +55,13 @@ async def get_zones(run_type: RunType, run_datetime: datetime, for_date: date, _
for row in rows:
combustible_area = row.combustible_area # type: ignore
hfi_area = row.hfi_area # type: ignore
zones.append(FireZoneArea(
mof_fire_zone_id=row.source_identifier, # type: ignore
shapes.append(FireShapeArea(
fire_shape_id=row.source_identifier, # type: ignore
threshold=row.threshold, # type: ignore
combustible_area=row.combustible_area, # type: ignore
elevated_hfi_area=row.hfi_area, # type: ignore
elevated_hfi_percentage=hfi_area / combustible_area * 100))
return FireZoneAreaListResponse(zones=zones)
return FireShapeAreaListResponse(shapes=shapes)


@router.get('/hfi-fuels/{run_type}/{for_date}/{run_datetime}/{zone_id}',
Expand Down
16 changes: 8 additions & 8 deletions api/app/schemas/fba.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,30 @@ class FireCenterListResponse(BaseModel):
fire_centers: List[FireCentre]


class FireZoneArea(BaseModel):
class FireShapeArea(BaseModel):
""" A zone is a grouping of planning areas within a fire centre. """
mof_fire_zone_id: int
fire_shape_id: int
threshold: int
combustible_area: float
elevated_hfi_area: float
elevated_hfi_percentage: float


class FireZoneAreaListResponse(BaseModel):
class FireShapeAreaListResponse(BaseModel):
""" Response for all planning areas, in a list """
zones: List[FireZoneArea]
shapes: List[FireShapeArea]


class FireZoneHighHfiAreas(BaseModel):
class FireShapeHighHfiAreas(BaseModel):
""" A fire zone and the area exceeding HFI thresholds. """
mof_fire_zone_id: int
fire_shape_id: int
advisory_area: float
warn_area: float


class FireZoneHighHfiAreasListResponse(BaseModel):
class FireShapeHighHfiAreasListResponse(BaseModel):
""" Response for all fire zones and their areas exceeding high HFI thresholds. """
zones: List[FireZoneHighHfiAreas]
zones: List[FireShapeHighHfiAreas]


class HfiThresholdAreaByFuelType(BaseModel):
Expand Down
2 changes: 1 addition & 1 deletion api/app/tests/fba/test_fba_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from app.tests.utils.mock_jwt_decode_role import MockJWTDecodeWithRole

get_fire_centres_url = '/api/fba/fire-centers'
get_fire_zone_areas_url = '/api/fba/fire-zone-areas/forecast/2022-09-27/2022-09-27'
get_fire_zone_areas_url = '/api/fba/fire-shape-areas/forecast/2022-09-27/2022-09-27'
decode_fn = "jwt.decode"


Expand Down
18 changes: 9 additions & 9 deletions web/src/api/fbaAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export interface FireCenter {
stations: FireCenterStation[]
}

export interface FireZone {
mof_fire_zone_id: number
export interface FireShape {
fire_shape_id: number
mof_fire_zone_name: string
mof_fire_centre_name?: string
area_sqm?: number
Expand All @@ -31,8 +31,8 @@ export interface FireZoneThresholdFuelTypeArea {
area: number
}

export interface FireZoneArea {
mof_fire_zone_id: number
export interface FireShapeArea {
fire_shape_id: number
threshold: number
combustible_area: number
elevated_hfi_area: number
Expand All @@ -56,8 +56,8 @@ export interface FireZoneElevationInfoResponse {
hfi_elevation_info: ElevationInfoByThreshold[]
}

export interface ZoneAreaListResponse {
zones: FireZoneArea[]
export interface FireShapeAreaListResponse {
shapes: FireShapeArea[]
}

export interface HfiThresholdFuelTypeArea {
Expand Down Expand Up @@ -85,12 +85,12 @@ export async function getFBAFireCenters(): Promise<FBAResponse> {
return data
}

export async function getFireZoneAreas(
export async function getFireShapeAreas(
run_type: RunType,
run_datetime: string,
for_date: string
): Promise<ZoneAreaListResponse> {
const url = `/fba/fire-zone-areas/${run_type.toLowerCase()}/${encodeURI(run_datetime)}/${for_date}`
): Promise<FireShapeAreaListResponse> {
const url = `/fba/fire-shape-areas/${run_type.toLowerCase()}/${encodeURI(run_datetime)}/${for_date}`
const { data } = await axios.get(url, {})
return data
}
Expand Down
6 changes: 3 additions & 3 deletions web/src/app/rootReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import hfiStationsReducer from 'features/hfiCalculator/slices/stationsSlice'
import hfiReadyReducer, { HFIReadyState } from 'features/hfiCalculator/slices/hfiReadySlice'
import fbaCalculatorSlice from 'features/fbaCalculator/slices/fbaCalculatorSlice'
import fireCentersSlice from 'commonSlices/fireCentersSlice'
import fireZoneAreasSlice from 'features/fba/slices/fireZoneAreasSlice'
import fireShapeAreasSlice from 'features/fba/slices/fireZoneAreasSlice'
import valueAtCoordinateSlice from 'features/fba/slices/valueAtCoordinateSlice'
import runDatesSlice from 'features/fba/slices/runDatesSlice'
import hfiFuelTypesSlice from 'features/fba/slices/hfiFuelTypesSlice'
Expand All @@ -34,7 +34,7 @@ const rootReducer = combineReducers({
hfiReady: hfiReadyReducer,
fbaCalculatorResults: fbaCalculatorSlice,
fireCenters: fireCentersSlice,
fireZoneAreas: fireZoneAreasSlice,
fireShapeAreas: fireShapeAreasSlice,
runDates: runDatesSlice,
valueAtCoordinate: valueAtCoordinateSlice,
hfiFuelTypes: hfiFuelTypesSlice,
Expand Down Expand Up @@ -63,7 +63,7 @@ export const selectToken = (state: RootState) => state.authentication.token
export const selectFireBehaviourCalcResult = (state: RootState) => state.fbaCalculatorResults
export const selectHFIStations = (state: RootState) => state.hfiStations
export const selectFireCenters = (state: RootState) => state.fireCenters
export const selectFireZoneAreas = (state: RootState) => state.fireZoneAreas
export const selectFireShapeAreas = (state: RootState) => state.fireShapeAreas
export const selectRunDates = (state: RootState) => state.runDates
export const selectValueAtCoordinate = (state: RootState) => state.valueAtCoordinate
export const selectHFIFuelTypes = (state: RootState) => state.hfiFuelTypes
Expand Down
10 changes: 5 additions & 5 deletions web/src/features/fba/components/ZoneSummaryPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { styled } from '@mui/material/styles'
import CombustibleAreaViz from 'features/fba/components/viz/CombustibleAreaViz'
import { Grid, IconButton, Typography } from '@mui/material'
import { isUndefined } from 'lodash'
import { ElevationInfoByThreshold, FireZone, FireZoneArea, FireZoneThresholdFuelTypeArea } from 'api/fbaAPI'
import { ElevationInfoByThreshold, FireShape, FireShapeArea, FireZoneThresholdFuelTypeArea } from 'api/fbaAPI'
import ElevationInfoViz from 'features/fba/components/viz/ElevationInfoViz'
import FuelTypesBreakdown from 'features/fba/components/viz/FuelTypesBreakdown'
import CloseIcon from '@mui/icons-material/Close'
Expand All @@ -29,10 +29,10 @@ const CentreName = styled(Typography)({
})

interface Props {
selectedFireZone: FireZone | undefined
selectedFireZone: FireShape | undefined
fuelTypeInfo: Record<number, FireZoneThresholdFuelTypeArea[]>
hfiElevationInfo: ElevationInfoByThreshold[]
fireZoneAreas: FireZoneArea[]
fireShapeAreas: FireShapeArea[]
showSummaryPanel: boolean
setShowSummaryPanel: React.Dispatch<React.SetStateAction<boolean>>
}
Expand Down Expand Up @@ -63,8 +63,8 @@ const ZoneSummaryPanel = React.forwardRef((props: Props, ref: React.ForwardedRef
</Grid>
<Grid item>
<CombustibleAreaViz
fireZoneAreas={props.fireZoneAreas.filter(
area => area.mof_fire_zone_id == props.selectedFireZone?.mof_fire_zone_id
fireZoneAreas={props.fireShapeAreas.filter(
area => area.fire_shape_id == props.selectedFireZone?.fire_shape_id
)}
/>
</Grid>
Expand Down
Loading

0 comments on commit 38ec422

Please sign in to comment.