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

Ab/add zarr timeseries #538

Merged
merged 30 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2c70a11
Adding zarr layers
abarciauskas-bgse May 6, 2023
1a7f07e
Create stac override
abarciauskas-bgse May 7, 2023
dc8157f
Add static stac file
abarciauskas-bgse May 7, 2023
b794822
Move static STAC
abarciauskas-bgse May 7, 2023
f3f686d
Remove useEffect for tilesUrl and fix data loading
abarciauskas-bgse May 7, 2023
32e3249
Fix gitignore
abarciauskas-bgse May 8, 2023
c969de2
haveSourceParamsChanged should depend on date
abarciauskas-bgse May 8, 2023
3d01863
Add cmip6 zarr and modify color maps
abarciauskas-bgse May 9, 2023
7b24654
Add geos FWI data
abarciauskas-bgse May 11, 2023
a2a830c
Use day as time_density
abarciauskas-bgse May 11, 2023
15d5abf
Refactoring
abarciauskas-bgse May 12, 2023
5e2b784
Add assetUrl to component
abarciauskas-bgse May 12, 2023
6b305d2
Add titiler xarray host
abarciauskas-bgse May 15, 2023
057aed6
Revert change to gitignore
abarciauskas-bgse May 15, 2023
d297992
Update .env
abarciauskas-bgse May 16, 2023
a7ee609
Add parcel resolver thematics to gitignore
abarciauskas-bgse May 16, 2023
b2422ac
Fix lint errors
abarciauskas-bgse May 16, 2023
54f5eb0
Remove unused instance of MapboxMap
abarciauskas-bgse May 16, 2023
eaf2ae7
Make description shorter
abarciauskas-bgse May 16, 2023
5eff10d
Change co2 range
abarciauskas-bgse May 16, 2023
4cd8a80
Revert mapbox style id
danielfdsilva May 17, 2023
f8b15c1
Pass layer data to layer components instead of specifying
danielfdsilva May 17, 2023
f366f13
Fix STAC endpoint
abarciauskas-bgse Jun 8, 2023
c5df6d0
Merge branch 'main' into ab/add-zarr-timeseries
abarciauskas-bgse Jul 5, 2023
0e3ca14
Revert change to vector-timeseries
abarciauskas-bgse Jul 5, 2023
f194734
Match updates to interface in main
abarciauskas-bgse Jul 5, 2023
a9e1559
Add assetUrl
abarciauskas-bgse Jul 5, 2023
3eb5766
Revert change to gitignore
abarciauskas-bgse Jul 5, 2023
9f16169
Fix lint errors
abarciauskas-bgse Jul 5, 2023
f71364a
Simplify zarr layer handling
danielfdsilva Jul 10, 2023
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
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ [email protected]

API_RASTER_ENDPOINT='https://staging-raster.delta-backend.com'
API_STAC_ENDPOINT='https://staging-stac.delta-backend.com'
API_XARRAY_ENDPOINT='https://dev-titiler-xarray.delta-backend.com/tilejson.json'

# If the app is being served in from a subfolder, the domain url must be set.
# For example, if the app is served from /mysite:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ function Scrollytelling(props) {
<Basemap />
{isMapLoaded &&
resolvedLayers.map((resolvedLayer, lIdx) => {
if (!resolvedLayer) return null;
if (!resolvedLayer || !mapRef.current) return null;

const { runtimeData, Component: LayerCmp, layer } = resolvedLayer;
const isHidden =
Expand Down
60 changes: 33 additions & 27 deletions app/scripts/components/common/mapbox/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, {
MutableRefObject,
ReactNode,
forwardRef,
useCallback,
Expand Down Expand Up @@ -105,7 +106,10 @@ const getMapPositionOptions = (position) => {
return opts;
};

function MapboxMapComponent(props: MapboxMapProps, ref) {
function MapboxMapComponent(
props: MapboxMapProps,
ref: MutableRefObject<MapboxMapRef>
) {
/* eslint-disable react/prop-types */
const {
className,
Expand Down Expand Up @@ -371,21 +375,19 @@ function MapboxMapComponent(props: MapboxMapProps, ref) {
title={baseLayerResolvedData.name}
description={baseLayerResolvedData.description}
{...baseLayerResolvedData.legend}
/>
/>
{compareLayerResolvedData?.legend &&
isComparing &&
(baseLayerResolvedData.id !== compareLayerResolvedData.id) &&
<LayerLegend
id={`compare-${compareLayerResolvedData.id}`}
title={compareLayerResolvedData.name}
description={compareLayerResolvedData.description}
{...compareLayerResolvedData.legend}
/>}
isComparing &&
baseLayerResolvedData.id !== compareLayerResolvedData.id && (
<LayerLegend
id={`compare-${compareLayerResolvedData.id}`}
title={compareLayerResolvedData.name}
description={compareLayerResolvedData.description}
{...compareLayerResolvedData.legend}
/>
)}
</LayerLegendContainer>
)}



)}

{/*
Maps container
Expand All @@ -409,17 +411,20 @@ function MapboxMapComponent(props: MapboxMapProps, ref) {
labelsOption={labelsOption}
boundariesOption={boundariesOption}
/>
{isMapLoaded && baseLayerResolvedData && BaseLayerComponent && (
<BaseLayerComponent
id={`base-${baseLayerResolvedData.id}`}
stacCol={baseLayerResolvedData.stacCol}
mapInstance={mapRef.current}
date={date}
sourceParams={baseLayerResolvedData.sourceParams}
zoomExtent={baseLayerResolvedData.zoomExtent}
onStatusChange={onBaseLayerStatusChange}
/>
)}
{mapRef.current &&
isMapLoaded &&
baseLayerResolvedData &&
BaseLayerComponent && (
<BaseLayerComponent
id={`base-${baseLayerResolvedData.id}`}
stacCol={baseLayerResolvedData.stacCol}
mapInstance={mapRef.current}
date={date}
sourceParams={baseLayerResolvedData.sourceParams}
zoomExtent={baseLayerResolvedData.zoomExtent}
onStatusChange={onBaseLayerStatusChange}
/>
)}
<SimpleMap
className='root'
mapRef={mapRef}
Expand Down Expand Up @@ -455,14 +460,15 @@ function MapboxMapComponent(props: MapboxMapProps, ref) {
labelsOption={labelsOption}
boundariesOption={boundariesOption}
/>
{isMapCompareLoaded &&
{mapCompareRef.current &&
isMapCompareLoaded &&
compareLayerResolvedData &&
CompareLayerComponent && (
<CompareLayerComponent
id={`compare-${compareLayerResolvedData.id}`}
stacCol={compareLayerResolvedData.stacCol}
mapInstance={mapCompareRef.current}
date={compareToDate}
date={compareToDate ?? undefined}
sourceParams={compareLayerResolvedData.sourceParams}
zoomExtent={compareLayerResolvedData.zoomExtent}
onStatusChange={onCompareLayerStatusChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ const LOG = true;

const FIT_BOUNDS_PADDING = 32;

interface MapLayerRasterTimeseriesProps {
export interface MapLayerRasterTimeseriesProps {
id: string;
stacCol: string;
date?: Date;
mapInstance: MapboxMap;
sourceParams: object;
zoomExtent?: [number, number];
sourceParams?: Record<string, any>;
zoomExtent?: number[];
onStatusChange?: (result: { status: ActionStatus; id: string }) => void;
isHidden: boolean;
isHidden?: boolean;
idSuffix?: string;
}

Expand Down
27 changes: 22 additions & 5 deletions app/scripts/components/common/mapbox/layers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,22 @@ import {
DatasetDatumFn,
DatasetDatumFnResolverBag,
DatasetDatumReturnType,
DatasetLayerCompareNormalized
DatasetLayerCompareNormalized,
DatasetLayerType
} from 'veda';
import { MapLayerRasterTimeseries, StacFeature } from './raster-timeseries';
import { MapLayerVectorTimeseries } from './vector-timeseries';
import {
MapLayerRasterTimeseries,
MapLayerRasterTimeseriesProps,
StacFeature
} from './raster-timeseries';
import {
MapLayerVectorTimeseries,
MapLayerVectorTimeseriesProps
} from './vector-timeseries';
import {
MapLayerZarrTimeseries,
MapLayerZarrTimeseriesProps
} from './zarr-timeseries';

import { userTzDate2utcString, utcString2userTzDate } from '$utils/date';
import { AsyncDatasetLayer } from '$context/layer-data';
Expand All @@ -29,11 +41,16 @@ import { HintedError } from '$utils/hinted-error';

export const getLayerComponent = (
isTimeseries: boolean,
layerType: 'raster' | 'vector'
): FunctionComponent<any> | null => {
layerType: DatasetLayerType
): FunctionComponent<
| MapLayerRasterTimeseriesProps
| MapLayerVectorTimeseriesProps
| MapLayerZarrTimeseriesProps
> | null => {
if (isTimeseries) {
if (layerType === 'raster') return MapLayerRasterTimeseries;
if (layerType === 'vector') return MapLayerVectorTimeseries;
if (layerType === 'zarr') return MapLayerZarrTimeseries;
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ import { useCustomMarker } from './custom-marker';
import { ActionStatus, S_FAILED, S_LOADING, S_SUCCEEDED } from '$utils/status';
import { userTzDate2utcString } from '$utils/date';

interface MapLayerVectorTimeseriesProps {
export interface MapLayerVectorTimeseriesProps {
id: string;
stacCol: string;
date?: Date;
mapInstance: MapboxMap;
sourceParams: object;
zoomExtent?: [number, number];
sourceParams?: Record<string, any>;
zoomExtent?: number[];
onStatusChange?: (result: { status: ActionStatus; id: string }) => void;
isHidden: boolean;
isHidden?: boolean;
idSuffix?: string;
}

Expand Down
157 changes: 157 additions & 0 deletions app/scripts/components/common/mapbox/layers/zarr-timeseries.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import { useEffect, useMemo, useState } from 'react';
import qs from 'qs';
import { Map as MapboxMap, RasterSource, RasterLayer } from 'mapbox-gl';

import { requestQuickCache } from './utils';
import { useMapStyle } from './styles';

import { ActionStatus, S_FAILED, S_LOADING, S_SUCCEEDED } from '$utils/status';

const tilerUrl = process.env.API_XARRAY_ENDPOINT;

export interface MapLayerZarrTimeseriesProps {
id: string;
stacCol: string;
date?: Date;
mapInstance: MapboxMap;
sourceParams?: Record<string, any>;
zoomExtent?: number[];
onStatusChange?: (result: { status: ActionStatus; id: string }) => void;
isHidden?: boolean;
idSuffix?: string;
}

export function MapLayerZarrTimeseries(props: MapLayerZarrTimeseriesProps) {
const {
id,
stacCol,
date,
mapInstance,
sourceParams,
zoomExtent,
onStatusChange,
isHidden,
idSuffix = ''
} = props;

const { updateStyle } = useMapStyle();
const [assetUrl, setAssetUrl] = useState('');

const [minZoom] = zoomExtent ?? [0, 20];

const generatorId = 'zarr-timeseries' + idSuffix;

//
// Get the asset url
//
useEffect(() => {
const controller = new AbortController();

async function load() {
try {
onStatusChange?.({ status: S_LOADING, id });
const data = await requestQuickCache({
url: `${process.env.API_STAC_ENDPOINT}/collections/${stacCol}`,
method: 'GET',
controller
});

setAssetUrl(data.assets.zarr.href);
onStatusChange?.({ status: S_SUCCEEDED, id });
} catch (error) {
if (!controller.signal.aborted) {
setAssetUrl('');
onStatusChange?.({ status: S_FAILED, id });
}
return;
}
}

load();

return () => {
controller.abort();
};
}, [mapInstance, id, stacCol, date, onStatusChange]);

//
// Generate Mapbox GL layers and sources for raster timeseries
//
const haveSourceParamsChanged = useMemo(
() => JSON.stringify(sourceParams),
[sourceParams]
);

useEffect(
() => {
if (!tilerUrl) return;

const tileParams = qs.stringify({
url: assetUrl,
time_slice: date,
...sourceParams
});

const zarrSource: RasterSource = {
type: 'raster',
url: `${tilerUrl}?${tileParams}`
};

const zarrLayer: RasterLayer = {
id: id,
type: 'raster',
source: id,
layout: {
visibility: isHidden ? 'none' : 'visible'
},
paint: {
'raster-opacity': Number(!isHidden),
'raster-opacity-transition': {
duration: 320
}
},
minzoom: minZoom,
metadata: {
layerOrderPosition: 'raster'
}
};

const sources = {
[id]: zarrSource
};
const layers = [zarrLayer];

updateStyle({
generatorId,
sources,
layers
});
},
// sourceParams not included, but using a stringified version of it to detect changes (haveSourceParamsChanged)
[
updateStyle,
id,
date,
assetUrl,
minZoom,
haveSourceParamsChanged,
isHidden,
generatorId
]
);

//
// 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 @@ -16,7 +16,7 @@ export const BASEMAP_STYLES = [
id: 'satellite',
label: 'Satellite',
mapboxId: 'cldu1cb8f00ds01p6gi583w1m',
thumbnailUrl: `https://api.mapbox.com/styles/v1/covid-nasa/cldac5c2c003k01oebmavw4q3/static/-9.14,38.7,10.5,0/480x320?access_token=${process.env.MAPBOX_TOKEN}`
thumbnailUrl: `https://api.mapbox.com/styles/v1/covid-nasa/cldu1cb8f00ds01p6gi583w1m/static/-9.14,38.7,10.5,0/480x320?access_token=${process.env.MAPBOX_TOKEN}`
},
{
id: 'dark',
Expand Down
Loading
Loading