From 4e395e44858bc9a8f717a156861261a3c3142757 Mon Sep 17 00:00:00 2001 From: Daniel da Silva Date: Fri, 22 Sep 2023 15:05:10 +0100 Subject: [PATCH] Simplify use Stac Collection --- .../define/use-stac-collection-search.ts | 133 +++++++++--------- 1 file changed, 65 insertions(+), 68 deletions(-) diff --git a/app/scripts/components/analysis/define/use-stac-collection-search.ts b/app/scripts/components/analysis/define/use-stac-collection-search.ts index 4f63f08d1..2fed3097f 100644 --- a/app/scripts/components/analysis/define/use-stac-collection-search.ts +++ b/app/scripts/components/analysis/define/use-stac-collection-search.ts @@ -1,6 +1,5 @@ -import { DatasetLayer } from 'veda'; +import { useMemo } from 'react'; import { FeatureCollection, Polygon } from 'geojson'; -import { useEffect, useState } from 'react'; import axios from 'axios'; import { useQuery } from '@tanstack/react-query'; import booleanIntersects from '@turf/boolean-intersects'; @@ -8,14 +7,8 @@ import bboxPolygon from '@turf/bbox-polygon'; import { areIntervalsOverlapping } from 'date-fns'; import { allAvailableDatasetsLayers } from '.'; + import { utcString2userTzDate } from '$utils/date'; -import { - ActionStatus, - S_FAILED, - S_IDLE, - S_LOADING, - S_SUCCEEDED -} from '$utils/status'; interface UseStacSearchProps { start?: Date; @@ -32,73 +25,77 @@ export function useStacCollectionSearch({ }: UseStacSearchProps) { const readyToLoadDatasets = !!(start && end && aoi); - const [selectableDatasetLayers, setSelectableDatasetLayers] = useState< - DatasetLayer[] - >([]); - - const [stacSearchStatus, setStacSearchStatus] = - useState(S_IDLE); - - const { data: collectionData } = useQuery({ + const result = useQuery({ queryKey: ['stacCollection'], queryFn: async ({ signal }) => { - setStacSearchStatus(S_LOADING); - try { - const collectionResponse = await axios.get(collectionUrl, { - signal - }); - setStacSearchStatus(S_SUCCEEDED); - return collectionResponse.data.collections; - } catch (e) { - if (!signal?.aborted) { - setStacSearchStatus(S_FAILED); - } - } + const collectionResponse = await axios.get(collectionUrl, { + signal + }); + return collectionResponse.data.collections; }, enabled: readyToLoadDatasets }); - useEffect(() => { - if (!collectionData || !readyToLoadDatasets) return; + const selectableDatasetLayers = useMemo(() => { try { - setStacSearchStatus(S_LOADING); - const matchingCollectionIds = collectionData - .filter( - (col) => col.extent.spatial.bbox && col.extent.temporal.interval - ) - .map((col) => { - return { - id: col.id, - bbox: col.extent.spatial.bbox[0], - start: utcString2userTzDate(col.extent.temporal.interval[0][0]), - end: utcString2userTzDate(col.extent.temporal.interval[0][1]) - }; - }) - .filter((col) => { - return ( - aoi.features.some((feature) => - booleanIntersects(feature, bboxPolygon(col.bbox)) - ) && - areIntervalsOverlapping( - { start: new Date(start), end: new Date(end) }, - { - start: new Date(col.start), - end: new Date(col.end) - } - ) - ); - }) - .map((c) => c.id); - setSelectableDatasetLayers( - allAvailableDatasetsLayers.filter((l) => - matchingCollectionIds.includes(l.stacCol) - ) - ); + return getInTemporalAndSpatialExtent(result.data, aoi, { + start, + end + }); } catch (e) { - setStacSearchStatus(S_FAILED); + return []; + } + }, [result.data, aoi, start, end]); + + return { + selectableDatasetLayers: selectableDatasetLayers, + stacSearchStatus: result.status, + readyToLoadDatasets + }; +} + +function getInTemporalAndSpatialExtent(collectionData, aoi, timeRange) { + const matchingCollectionIds = collectionData.reduce((acc, col) => { + const id = col.id; + + // Is is a dataset defined in the app? + // If not, skip other calculations. + const isAppDataset = allAvailableDatasetsLayers.some( + (l) => l.stacCol === id + ); + + if ( + !isAppDataset || + !col.extent.spatial.bbox || + !col.extent.temporal.interval + ) { + return acc; + } + + const bbox = col.extent.spatial.bbox[0]; + const start = utcString2userTzDate(col.extent.temporal.interval[0][0]); + const end = utcString2userTzDate(col.extent.temporal.interval[0][1]); + + const isInAOI = aoi.features.some((feature) => + booleanIntersects(feature, bboxPolygon(bbox)) + ); + + const isInTOI = areIntervalsOverlapping( + { start: new Date(timeRange.start), end: new Date(timeRange.end) }, + { + start: new Date(start), + end: new Date(end) + } + ); + + if (isInAOI && isInTOI) { + return [...acc, id]; + } else { + return acc; } - setStacSearchStatus(S_SUCCEEDED); - }, [collectionData, start, end, aoi, readyToLoadDatasets]); + }, []); - return { selectableDatasetLayers, stacSearchStatus, readyToLoadDatasets }; + return allAvailableDatasetsLayers.filter((l) => + matchingCollectionIds.includes(l.stacCol) + ); }