diff --git a/app/scripts/components/common/map/style-generators/cmr-timeseries.tsx b/app/scripts/components/common/map/style-generators/cmr-timeseries.tsx index 4c6df749c..0d1a20a5f 100644 --- a/app/scripts/components/common/map/style-generators/cmr-timeseries.tsx +++ b/app/scripts/components/common/map/style-generators/cmr-timeseries.tsx @@ -1,27 +1,9 @@ import React from 'react'; -import { BaseGeneratorParams } from '../types'; -import { ZarrPaintLayer } from './zarr-timeseries'; +import { CMRTimeseriesProps } from '../types'; +import { RasterPaintLayer } from './raster-paint-layer'; import { useCMR } from './hooks'; -import { ActionStatus } from '$utils/status'; -interface AssetUrlReplacement { - from: string; - to: string; -} - -export interface CMRTimeseriesProps extends BaseGeneratorParams { - id: string; - stacCol: string; - date?: Date; - sourceParams?: Record; - stacApiEndpoint?: string; - tileApiEndpoint?: string; - assetUrlReplacements?: AssetUrlReplacement; - zoomExtent?: number[]; - onStatusChange?: (result: { status: ActionStatus; id: string }) => void; -} - -export function CMRTimeseries(props:CMRTimeseriesProps) { +export function CMRTimeseries(props: CMRTimeseriesProps) { const { id, stacCol, @@ -33,5 +15,5 @@ export function CMRTimeseries(props:CMRTimeseriesProps) { const stacApiEndpointToUse = stacApiEndpoint?? process.env.API_STAC_ENDPOINT; const assetUrl = useCMR({ id, stacCol, stacApiEndpointToUse, date, assetUrlReplacements, stacApiEndpoint, onStatusChange }); - return ; + return ; } \ No newline at end of file diff --git a/app/scripts/components/common/map/style-generators/raster-paint-layer.tsx b/app/scripts/components/common/map/style-generators/raster-paint-layer.tsx new file mode 100644 index 000000000..d89c4970f --- /dev/null +++ b/app/scripts/components/common/map/style-generators/raster-paint-layer.tsx @@ -0,0 +1,122 @@ +import { useEffect, useMemo } from 'react'; +import qs from 'qs'; +import { RasterSource, RasterLayer } from 'mapbox-gl'; + +import { BaseGeneratorParams } from '../types'; +import useMapStyle from '../hooks/use-map-style'; +import useGeneratorParams from '../hooks/use-generator-params'; + +interface RasterPaintLayerProps extends BaseGeneratorParams { + id: string; + date?: Date; + sourceParams?: Record; + tileApiEndpoint?: string; + zoomExtent?: number[]; + assetUrl: string; +} + +export function RasterPaintLayer(props: RasterPaintLayerProps) { + const { + id, + tileApiEndpoint, + date, + sourceParams, + zoomExtent, + assetUrl, + hidden, + opacity + } = props; + + const { updateStyle } = useMapStyle(); + const [minZoom] = zoomExtent ?? [0, 20]; + const generatorId = `zarr-timeseries-${id}`; + + // + // Generate Mapbox GL layers and sources for raster timeseries + // + const haveSourceParamsChanged = useMemo( + () => JSON.stringify(sourceParams), + [sourceParams] + ); + + const generatorParams = useGeneratorParams(props); + + useEffect( + () => { + if (!assetUrl) return; + + const tileParams = qs.stringify({ + url: assetUrl, + time_slice: date, + ...sourceParams + }); + + const zarrSource: RasterSource = { + type: 'raster', + url: `${tileApiEndpoint}?${tileParams}` + }; + + const rasterOpacity = typeof opacity === 'number' ? opacity / 100 : 1; + + const zarrLayer: RasterLayer = { + id: id, + type: 'raster', + source: id, + paint: { + 'raster-opacity': hidden ? 0 : rasterOpacity, + 'raster-opacity-transition': { + duration: 320 + } + }, + minzoom: minZoom, + metadata: { + layerOrderPosition: 'raster' + } + }; + + const sources = { + [id]: zarrSource + }; + const layers = [zarrLayer]; + + updateStyle({ + generatorId, + sources, + layers, + params: generatorParams + }); + }, + // sourceParams not included, but using a stringified version of it to + // detect changes (haveSourceParamsChanged) + [ + updateStyle, + id, + date, + assetUrl, + minZoom, + tileApiEndpoint, + haveSourceParamsChanged, + generatorParams + // generatorParams includes hidden and opacity + // hidden, + // opacity, + // generatorId, // - dependent on id + // sourceParams, // tracked by haveSourceParamsChanged + ] + ); + + // + // Cleanup layers on unmount. + // + useEffect(() => { + return () => { + updateStyle({ + generatorId, + sources: {}, + layers: [] + }); + }; + }, [updateStyle, generatorId]); + + return null; +} \ No newline at end of file diff --git a/app/scripts/components/common/map/style-generators/raster-timeseries.tsx b/app/scripts/components/common/map/style-generators/raster-timeseries.tsx index c0c640e68..79f322869 100644 --- a/app/scripts/components/common/map/style-generators/raster-timeseries.tsx +++ b/app/scripts/components/common/map/style-generators/raster-timeseries.tsx @@ -11,7 +11,7 @@ import { } from 'mapbox-gl'; import { useTheme } from 'styled-components'; import { featureCollection, point } from '@turf/helpers'; -import { BaseGeneratorParams, StacFeature } from '../types'; +import { RasterTimeseriesProps, StacFeature } from '../types'; import useMapStyle from '../hooks/use-map-style'; import { FIT_BOUNDS_PADDING, @@ -36,19 +36,6 @@ import { // Whether or not to print the request logs. const LOG = true; -export interface RasterTimeseriesProps extends BaseGeneratorParams { - id: string; - stacCol: string; - date: Date; - sourceParams?: Record; - zoomExtent?: number[]; - bounds?: number[]; - onStatusChange?: (result: { status: ActionStatus; id: string }) => void; - isPositionSet?: boolean; - stacApiEndpoint?: string; - tileApiEndpoint?: string; -} - enum STATUS_KEY { Global, Layer, diff --git a/app/scripts/components/common/map/style-generators/zarr-timeseries.tsx b/app/scripts/components/common/map/style-generators/zarr-timeseries.tsx index 381ca776e..bf5908ba5 100644 --- a/app/scripts/components/common/map/style-generators/zarr-timeseries.tsx +++ b/app/scripts/components/common/map/style-generators/zarr-timeseries.tsx @@ -1,140 +1,10 @@ -import React, { useEffect, useMemo } from 'react'; -import qs from 'qs'; -import { RasterSource, RasterLayer } from 'mapbox-gl'; -import useMapStyle from '../hooks/use-map-style'; -import useGeneratorParams from '../hooks/use-generator-params'; -import { BaseGeneratorParams } from '../types'; +import React from 'react'; +import { BaseTimeseriesProps } from '../types'; import { useZarr } from './hooks'; -import { ActionStatus } from '$utils/status'; +import { RasterPaintLayer } from './raster-paint-layer'; -export interface ZarrTimeseriesProps extends BaseGeneratorParams { - id: string; - stacCol: string; - date?: Date; - sourceParams?: Record; - stacApiEndpoint?: string; - tileApiEndpoint?: string; - zoomExtent?: number[]; - onStatusChange?: (result: { status: ActionStatus; id: string }) => void; -} - -interface ZarrPaintLayerProps extends BaseGeneratorParams { - id: string; - date?: Date; - sourceParams?: Record; - tileApiEndpoint?: string; - zoomExtent?: number[]; - assetUrl: string; -} - -export function ZarrPaintLayer(props: ZarrPaintLayerProps) { - const { - id, - tileApiEndpoint, - date, - sourceParams, - zoomExtent, - assetUrl, - hidden, - opacity - } = props; - - const { updateStyle } = useMapStyle(); - const [minZoom] = zoomExtent ?? [0, 20]; - const generatorId = `zarr-timeseries-${id}`; - - // - // Generate Mapbox GL layers and sources for raster timeseries - // - const haveSourceParamsChanged = useMemo( - () => JSON.stringify(sourceParams), - [sourceParams] - ); - - const generatorParams = useGeneratorParams(props); - - useEffect( - () => { - if (!assetUrl) return; - - const tileParams = qs.stringify({ - url: assetUrl, - time_slice: date, - ...sourceParams - }); - - const zarrSource: RasterSource = { - type: 'raster', - url: `${tileApiEndpoint}?${tileParams}` - }; - - const rasterOpacity = typeof opacity === 'number' ? opacity / 100 : 1; - - const zarrLayer: RasterLayer = { - id: id, - type: 'raster', - source: id, - paint: { - 'raster-opacity': hidden ? 0 : rasterOpacity, - 'raster-opacity-transition': { - duration: 320 - } - }, - minzoom: minZoom, - metadata: { - layerOrderPosition: 'raster' - } - }; - - const sources = { - [id]: zarrSource - }; - const layers = [zarrLayer]; - - updateStyle({ - generatorId, - sources, - layers, - params: generatorParams - }); - }, - // sourceParams not included, but using a stringified version of it to - // detect changes (haveSourceParamsChanged) - [ - updateStyle, - id, - date, - assetUrl, - minZoom, - tileApiEndpoint, - haveSourceParamsChanged, - generatorParams - // generatorParams includes hidden and opacity - // hidden, - // opacity, - // generatorId, // - dependent on id - // sourceParams, // tracked by haveSourceParamsChanged - ] - ); - - // - // Cleanup layers on unmount. - // - useEffect(() => { - return () => { - updateStyle({ - generatorId, - sources: {}, - layers: [] - }); - }; - }, [updateStyle, generatorId]); - - return null; -} - -export function ZarrTimeseries(props:ZarrTimeseriesProps) { +export function ZarrTimeseries(props: BaseTimeseriesProps) { const { id, stacCol, @@ -145,5 +15,5 @@ export function ZarrTimeseries(props:ZarrTimeseriesProps) { const stacApiEndpointToUse = stacApiEndpoint?? process.env.API_STAC_ENDPOINT; const assetUrl = useZarr({id, stacCol, stacApiEndpointToUse, date, onStatusChange}); - return ; + return ; } \ No newline at end of file diff --git a/app/scripts/components/common/map/types.d.ts b/app/scripts/components/common/map/types.d.ts index b6a54f80b..5cfb1fd84 100644 --- a/app/scripts/components/common/map/types.d.ts +++ b/app/scripts/components/common/map/types.d.ts @@ -1,5 +1,6 @@ import { Feature, Polygon } from 'geojson'; import { AnyLayer, AnySourceImpl } from 'mapbox-gl'; +import { ActionStatus } from '$utils/status'; export interface ExtendedMetadata { layerOrderPosition?: LayerOrderPosition; @@ -42,3 +43,33 @@ export type AoIFeature = Feature & { selected: boolean; id: string; }; + +export interface BaseTimeseriesProps extends BaseGeneratorParams { + id: string; + stacCol: string; + date: Date; + sourceParams?: Record; + stacApiEndpoint?: string; + tileApiEndpoint?: string; + zoomExtent?: number[]; + onStatusChange?: (result: { status: ActionStatus; id: string }) => void; +} + +// export interface ZarrTimeseriesProps extends BaseTimeseriesProps { +// // No additional properties, using BaseTimeseriesProps as is +// } + +export interface RasterTimeseriesProps extends BaseTimeseriesProps { + bounds?: number[]; + isPositionSet?: boolean; +} + +interface AssetUrlReplacement { + from: string; + to: string; +} + +export interface CMRTimeseriesProps extends BaseTimeseriesProps { + assetUrlReplacements?: AssetUrlReplacement; +} +