diff --git a/api/app/main.py b/api/app/main.py index 4779f481b..2d8ddc8ae 100644 --- a/api/app/main.py +++ b/api/app/main.py @@ -16,8 +16,7 @@ from app import health from app import hourlies from app.rocketchat_notifications import send_rocketchat_notification -from app.routers import (fba, forecasts, weather_models, c_haines, stations, hfi_calc, - fba_calc, sfms, morecast_v2, snow) +from app.routers import fba, forecasts, weather_models, c_haines, stations, hfi_calc, fba_calc, sfms, morecast_v2 from app.fire_behaviour.cffdrs import CFFDRS @@ -123,7 +122,6 @@ async def catch_exception_middleware(request: Request, call_next): api.include_router(fba.router, tags=["Auto Spatial Advisory"]) api.include_router(sfms.router, tags=["SFMS", "Auto Spatial Advisory"]) api.include_router(morecast_v2.router, tags=["Morecast v2"]) -api.include_router(snow.router, tags=['Snow']) @api.get('/ready') diff --git a/api/app/routers/snow.py b/api/app/routers/snow.py deleted file mode 100644 index 48e9e4537..000000000 --- a/api/app/routers/snow.py +++ /dev/null @@ -1,30 +0,0 @@ -""" Routers for Snow related data -""" - -import logging -from datetime import date, datetime -from fastapi import APIRouter, Depends -from app.auth import authentication_required, audit -from app.db.crud.snow import get_most_recent_processed_snow_by_date -from app.db.database import get_async_read_session_scope -from app.schemas.snow import ProcessedSnowModel, ProcessedSnowResponse -from app.utils.time import vancouver_tz - -logger = logging.getLogger(__name__) - -router = APIRouter( - prefix="/snow", - dependencies=[Depends(authentication_required), Depends(audit)], -) - - -@router.get('/most-recent-by-date/{for_date}', response_model=ProcessedSnowResponse | None) -async def get_most_recent_by_date(for_date: date, _=Depends(authentication_required)): - """ Returns the most recent processed snow record before or equal to the provided date. """ - logger.info('/snow/most-recent-by-date/') - tz_aware_datetime = vancouver_tz.localize(datetime.combine(for_date, datetime.min.time())) - async with get_async_read_session_scope() as session: - result = await get_most_recent_processed_snow_by_date(session, tz_aware_datetime) - if result is not None: - processed_snow = result[0] - return ProcessedSnowResponse(processed_snow=ProcessedSnowModel(for_date=processed_snow.for_date, processed_date=processed_snow.processed_date, snow_source=processed_snow.snow_source)) diff --git a/web/cypress/e2e/fba-map-page.cy.ts b/web/cypress/e2e/fba-map-page.cy.ts index 7a8b990ca..1379ef409 100644 --- a/web/cypress/e2e/fba-map-page.cy.ts +++ b/web/cypress/e2e/fba-map-page.cy.ts @@ -11,7 +11,6 @@ describe('Fire Behaviour Advisory Page', () => { }, { fixture: 'fba/vectors.json' } ).as('getVectors') - cy.intercept('GET', 'api/snow/most-recent-by-date/*', { fixture: 'fba/processedSnow.json' }).as('processedSnow') cy.visit(FIRE_BEHAVIOUR_ADVISORY_ROUTE) }) diff --git a/web/src/api/snow.ts b/web/src/api/snow.ts deleted file mode 100644 index be93024a6..000000000 --- a/web/src/api/snow.ts +++ /dev/null @@ -1,42 +0,0 @@ -import axios from 'api/axios' -import { DateTime } from 'luxon' - -enum SnowSource { - VIIRS = 'viirs' -} - -// The shape of processed snow data. -interface ProcessedSnowPayload { - for_date: string - processed_date: string - snow_source: SnowSource -} - -// Response object from our API. -interface ProcessedSnowResponse { - processed_snow: ProcessedSnowPayload -} - -// Client side representation of processed snow data. -export interface ProcessedSnow { - forDate: DateTime - processedDate: DateTime - snowSource: SnowSource -} - -export async function getMostRecentProcessedSnowByDate(forDate: DateTime): Promise { - if (!forDate) { - return null - } - const url = `snow/most-recent-by-date/${forDate.toISODate()}` - const { data } = await axios.get(url, {}) - if (data) { - const processedSnow = data.processed_snow - return { - forDate: DateTime.fromISO(processedSnow.for_date), - processedDate: DateTime.fromISO(processedSnow.processed_date), - snowSource: processedSnow.snow_source - } - } - return data -} diff --git a/web/src/features/fba/components/map/FBAMap.tsx b/web/src/features/fba/components/map/FBAMap.tsx index 7ab6c20ff..49733c636 100644 --- a/web/src/features/fba/components/map/FBAMap.tsx +++ b/web/src/features/fba/components/map/FBAMap.tsx @@ -27,14 +27,13 @@ import { fireShapeLabelStyler, stationStyler, hfiStyler, - snowStyler, fireCentreLineStyler } from 'features/fba/components/map/featureStylers' import { BC_EXTENT, CENTER_OF_BC } from 'utils/constants' import { DateTime } from 'luxon' import { PMTILES_BUCKET } from 'utils/env' import { RunType } from 'features/fba/pages/FireBehaviourAdvisoryPage' -import { buildPMTilesURL, buildSnowPMTilesURL } from 'features/fba/pmtilesBuilder' +import { buildPMTilesURL } from 'features/fba/pmtilesBuilder' import { isUndefined, cloneDeep, isNull } from 'lodash' import { Box } from '@mui/material' import Legend from 'features/fba/components/map/Legend' @@ -53,7 +52,6 @@ export interface FBAMapProps { fireShapeAreas: FireShapeArea[] runType: RunType advisoryThreshold: number - snowDate: DateTime | null zoomSource?: 'fireCenter' | 'fireShape' setZoomSource: React.Dispatch> } @@ -72,7 +70,6 @@ const FBAMap = (props: FBAMapProps) => { const { stations } = useSelector(selectFireWeatherStations) const [showShapeStatus, setShowShapeStatus] = useState(true) const [showHFI, setShowHFI] = useState(false) - const [showSnow, setShowSnow] = useState(false) const [map, setMap] = useState(null) const mapRef = useRef(null) as React.MutableRefObject const scaleRef = useRef(null) as React.MutableRefObject @@ -244,27 +241,6 @@ const FBAMap = (props: FBAMapProps) => { } }, [showHFI, mostRecentRunDate]) // eslint-disable-line react-hooks/exhaustive-deps - useEffect(() => { - if (!map) return - const layerName = 'snowVector' - removeLayerByName(map, layerName) - if (!isNull(props.snowDate)) { - const snowPMTilesSource = new olpmtiles.PMTilesVectorSource({ - url: buildSnowPMTilesURL(props.snowDate) - }) - - const latestSnowPMTilesLayer = new VectorTileLayer({ - source: snowPMTilesSource, - style: snowStyler, - zIndex: 40, - minZoom: 4, - properties: { name: layerName }, - visible: showSnow - }) - map.addLayer(latestSnowPMTilesLayer) - } - }, [props.snowDate]) // eslint-disable-line react-hooks/exhaustive-deps - useEffect(() => { // The React ref is used to attach to the div rendered in our // return statement of which this map's target is set to. @@ -331,17 +307,6 @@ const FBAMap = (props: FBAMapProps) => { map?.addLayer(stationsLayer) }, [stations]) // eslint-disable-line react-hooks/exhaustive-deps - // Generate a message to display about the snow layer in the legend. - const getSnowDateMessage = () => { - if (!showSnow) { - return null - } - if (isNull(props.snowDate)) { - return 'No data available' - } - return `as of ${props.snowDate?.toISODate()}` - } - return ( @@ -361,9 +326,6 @@ const FBAMap = (props: FBAMapProps) => { setShowShapeStatus={setShowShapeStatus} showHFI={showHFI} setShowHFI={setShowHFI} - showSnow={showSnow} - setShowSnow={setShowSnow} - snowDescription={getSnowDateMessage()} /> diff --git a/web/src/features/fba/components/map/Legend.tsx b/web/src/features/fba/components/map/Legend.tsx index 3f2ec357e..694aba1b2 100644 --- a/web/src/features/fba/components/map/Legend.tsx +++ b/web/src/features/fba/components/map/Legend.tsx @@ -98,9 +98,6 @@ interface LegendProps { setShowShapeStatus: React.Dispatch> showHFI: boolean setShowHFI: React.Dispatch> - showSnow: boolean - setShowSnow: React.Dispatch> - snowDescription: string | null } const Legend = ({ @@ -108,10 +105,7 @@ const Legend = ({ showShapeStatus, setShowShapeStatus, showHFI, - setShowHFI, - showSnow, - setShowSnow, - snowDescription + setShowHFI }: LegendProps) => { const handleLayerChange = ( layerName: string, @@ -148,13 +142,6 @@ const Legend = ({ onChange={() => handleLayerChange('hfiVector', showHFI, setShowHFI)} subItems={hfiSubItems} /> - handleLayerChange('snowVector', showSnow, setShowSnow)} - description={snowDescription} - renderEmptyDescription={true} - > ) } diff --git a/web/src/features/fba/components/map/fbaMap.test.tsx b/web/src/features/fba/components/map/fbaMap.test.tsx index d1dd90eba..d270ddb53 100644 --- a/web/src/features/fba/components/map/fbaMap.test.tsx +++ b/web/src/features/fba/components/map/fbaMap.test.tsx @@ -36,7 +36,6 @@ describe('FBAMap', () => { setZoomSource={function (): void { throw new Error('Function not implemented.') }} - snowDate={DateTime.now()} /> ) diff --git a/web/src/features/fba/components/map/featureStylers.ts b/web/src/features/fba/components/map/featureStylers.ts index 84339d5b7..81791507f 100644 --- a/web/src/features/fba/components/map/featureStylers.ts +++ b/web/src/features/fba/components/map/featureStylers.ts @@ -9,7 +9,6 @@ import { FireCenter, FireShape, FireShapeArea } from 'api/fbaAPI' const GREY_FILL = 'rgba(128, 128, 128, 0.8)' const EMPTY_FILL = 'rgba(0, 0, 0, 0.0)' -const SNOW_FILL = 'rgba(255, 255, 255, 0.75)' export const ADVISORY_ORANGE_FILL = 'rgba(255, 147, 38, 0.4)' export const ADVISORY_RED_FILL = 'rgba(128, 0, 0, 0.4)' @@ -230,15 +229,3 @@ export const hfiStyler = (feature: RenderFeature | ol.Feature): Style } return hfiStyle } - -// A styling function for the snow coverage pmtiles layer. -export const snowStyler = (feature: RenderFeature | ol.Feature): Style => { - const snow = feature.get('snow') - const snowStyle = new Style({}) - if (snow === 1) { - snowStyle.setFill(new Fill({ color: SNOW_FILL })) - } else { - snowStyle.setFill(new Fill({ color: EMPTY_FILL })) - } - return snowStyle -} diff --git a/web/src/features/fba/components/map/legend.test.tsx b/web/src/features/fba/components/map/legend.test.tsx index 2e614409e..242b246f8 100644 --- a/web/src/features/fba/components/map/legend.test.tsx +++ b/web/src/features/fba/components/map/legend.test.tsx @@ -8,7 +8,6 @@ describe('Legend', () => { const onToggleLayer = jest.fn() const setShowZoneStatus = jest.fn() const setShowHFI = jest.fn() - const setShowSnow = jest.fn() const { getByTestId } = render( { setShowHFI={setShowHFI} showHFI={false} showShapeStatus={true} - showSnow={false} - setShowSnow={setShowSnow} - snowDescription="foo" /> ) const legendComponent = getByTestId('asa-map-legend') @@ -39,7 +35,6 @@ describe('Legend', () => { const onToggleLayer = jest.fn() const setShowZoneStatus = jest.fn() const setShowHFI = jest.fn() - const setShowSnow = jest.fn() const { getByTestId } = render( { setShowHFI={setShowHFI} showHFI={false} showShapeStatus={true} - showSnow={false} - setShowSnow={setShowSnow} - snowDescription="foo" /> ) diff --git a/web/src/features/fba/pages/FireBehaviourAdvisoryPage.tsx b/web/src/features/fba/pages/FireBehaviourAdvisoryPage.tsx index 3ed3d091d..8f9545dde 100644 --- a/web/src/features/fba/pages/FireBehaviourAdvisoryPage.tsx +++ b/web/src/features/fba/pages/FireBehaviourAdvisoryPage.tsx @@ -28,7 +28,6 @@ import { fetchFireShapeAreas } from 'features/fba/slices/fireZoneAreasSlice' import { fetchfireZoneElevationInfo } from 'features/fba/slices/fireZoneElevationInfoSlice' import { fetchfireZoneTPIStats } from 'features/fba/slices/fireZoneTPIStatsSlice' import { StyledFormControl } from 'components/StyledFormControl' -import { getMostRecentProcessedSnowByDate } from 'api/snow' import InfoPanel from 'features/fba/components/infoPanel/InfoPanel' import FireZoneUnitSummary from 'features/fba/components/infoPanel/FireZoneUnitSummary' import { fetchProvincialSummary } from 'features/fba/slices/provincialSummarySlice' @@ -63,22 +62,10 @@ const FireBehaviourAdvisoryPage: React.FunctionComponent = () => { : DateTime.now().setZone(`UTC${PST_UTC_OFFSET}`).plus({ days: 1 }) ) const [runType, setRunType] = useState(RunType.FORECAST) - const [snowDate, setSnowDate] = useState(null) const { mostRecentRunDate } = useSelector(selectRunDates) const { fireShapeAreas } = useSelector(selectFireShapeAreas) const [selectedFireZoneTPIStats, setSelectedFireZoneTPIStats] = useState(null) - // Query our API for the most recently processed snow coverage date <= the currently selected date. - const fetchLastProcessedSnow = async (selectedDate: DateTime) => { - const data = await getMostRecentProcessedSnowByDate(selectedDate) - if (isNull(data)) { - setSnowDate(null) - } else { - const newSnowDate = data.forDate - setSnowDate(newSnowDate) - } - } - useEffect(() => { const findCenter = (id: string | null): FireCenter | undefined => { return fireCenters.find(center => center.id.toString() == id) @@ -119,7 +106,6 @@ const FireBehaviourAdvisoryPage: React.FunctionComponent = () => { if (!isNull(doiISODate)) { dispatch(fetchSFMSRunDates(runType, doiISODate)) } - fetchLastProcessedSnow(dateOfInterest) }, [dateOfInterest]) // eslint-disable-line react-hooks/exhaustive-deps useEffect(() => { @@ -241,7 +227,6 @@ const FireBehaviourAdvisoryPage: React.FunctionComponent = () => { advisoryThreshold={ADVISORY_THRESHOLD} setSelectedFireShape={setSelectedFireShape} fireShapeAreas={fireShapeAreas} - snowDate={snowDate} zoomSource={zoomSource} setZoomSource={setZoomSource} /> diff --git a/web/src/features/fba/pmtilesBuilder.ts b/web/src/features/fba/pmtilesBuilder.ts index b39c61b6f..17968728d 100644 --- a/web/src/features/fba/pmtilesBuilder.ts +++ b/web/src/features/fba/pmtilesBuilder.ts @@ -16,15 +16,3 @@ export const buildPMTilesURL = (for_date: DateTime, run_type: RunType, run_date: return PMTilesURL } - -/** - * Builds the URL for snow coverage pmtiles layers. - * @param snowDate The target date for snow coverage. - * @returns A URL to the snow coverage PMTiles stored in S3 - */ -export const buildSnowPMTilesURL = (snowDate: DateTime) => { - const snowPMTilesUrl = `${PMTILES_BUCKET}snow/${snowDate.toISODate()}/snowCoverage${snowDate.toISODate({ - format: 'basic' - })}.pmtiles` - return snowPMTilesUrl -}