Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create new raster paint layer module and factor out BaseTimeseriesPropos #1105

Merged
merged 2 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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<string, any>;
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,
Expand All @@ -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 <ZarrPaintLayer {...props} assetUrl={assetUrl} />;
return <RasterPaintLayer {...props} assetUrl={assetUrl} />;
}
Original file line number Diff line number Diff line change
@@ -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<string, any>;
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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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<string, any>;
zoomExtent?: number[];
bounds?: number[];
onStatusChange?: (result: { status: ActionStatus; id: string }) => void;
isPositionSet?: boolean;
stacApiEndpoint?: string;
tileApiEndpoint?: string;
}

enum STATUS_KEY {
Global,
Layer,
Expand Down
140 changes: 5 additions & 135 deletions app/scripts/components/common/map/style-generators/zarr-timeseries.tsx
Original file line number Diff line number Diff line change
@@ -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<string, any>;
stacApiEndpoint?: string;
tileApiEndpoint?: string;
zoomExtent?: number[];
onStatusChange?: (result: { status: ActionStatus; id: string }) => void;
}

interface ZarrPaintLayerProps extends BaseGeneratorParams {
id: string;
date?: Date;
sourceParams?: Record<string, any>;
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,
Expand All @@ -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 <ZarrPaintLayer {...props} assetUrl={assetUrl} />;
return <RasterPaintLayer {...props} assetUrl={assetUrl} />;
}
31 changes: 31 additions & 0 deletions app/scripts/components/common/map/types.d.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -42,3 +43,33 @@ export type AoIFeature = Feature<Polygon> & {
selected: boolean;
id: string;
};

export interface BaseTimeseriesProps extends BaseGeneratorParams {
id: string;
stacCol: string;
date: Date;
sourceParams?: Record<string, any>;
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;
}

Loading