Skip to content

Commit 502e576

Browse files
committed
refactor: coalesce items at the provider level
1 parent c30a7fd commit 502e576

File tree

4 files changed

+61
-19
lines changed

4 files changed

+61
-19
lines changed

src/app.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,7 @@ export default function App() {
5858
return (
5959
<QueryClientProvider client={queryClient}>
6060
<MapProvider>
61-
<StacMapProvider
62-
href={href}
63-
fileUpload={fileUpload}
64-
temporalFilter={undefined} // TODO re-add temporal filtering: https://github.com/developmentseed/stac-map/issues/123
65-
>
61+
<StacMapProvider href={href} fileUpload={fileUpload}>
6662
<Box zIndex={0} position={"absolute"} top={0} left={0}>
6763
<FileUpload.RootProvider value={fileUpload} unstyled={true}>
6864
<FileUpload.Dropzone

src/components/map.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export default function Map() {
4646
value,
4747
collections,
4848
items,
49-
linkedItems,
49+
filteredItems,
5050
picked,
5151
setPicked,
5252
stacGeoparquetTable,
@@ -100,7 +100,7 @@ export default function Map() {
100100
}),
101101
new GeoJsonLayer({
102102
id: "items",
103-
data: (items || linkedItems) as Feature[] | undefined,
103+
data: (filteredItems || items) as Feature[] | undefined,
104104
filled: true,
105105
stroked: true,
106106
getFillColor: fillColor,

src/context.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Table } from "apache-arrow";
22
import { createContext } from "react";
33
import type { StacCollection, StacItem } from "stac-ts";
44
import type { StacGeoparquetMetadata, StacValue } from "./types/stac";
5+
import type { TemporalFilter } from "./types/datetime";
56

67
export const StacMapContext = createContext<StacMapContextType | null>(null);
78

@@ -14,10 +15,7 @@ interface StacMapContextType {
1415
/// Collections either loaded from the collections endpoint or linked from the value.
1516
collections: StacCollection[] | undefined;
1617

17-
/// STAC items linked form the value.
18-
linkedItems: StacItem[] | undefined;
19-
20-
/// STAC items for visualization, often from search.
18+
/// STAC items, either linked or from a search.
2119
items: StacItem[] | undefined;
2220

2321
/// Set the items.
@@ -40,4 +38,13 @@ interface StacMapContextType {
4038

4139
/// Set the picked item.
4240
setPicked: (value: StacItem | undefined) => void;
41+
42+
/// The temporal filter for items.
43+
temporalFilter: TemporalFilter | undefined;
44+
45+
/// Sets the temporal filter.
46+
setTemporalFilter: (temporalFilter: TemporalFilter | undefined) => void;
47+
48+
/// Filtered items.
49+
filteredItems: StacItem[] | undefined;
4350
}

src/provider.tsx

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { UseFileUploadReturn } from "@chakra-ui/react";
2-
import { useEffect, useState, type ReactNode } from "react";
2+
import { useEffect, useMemo, useState, type ReactNode } from "react";
33
import type { StacItem } from "stac-ts";
44
import { StacMapContext } from "./context";
55
import useStacGeoparquet from "./hooks/stac-geoparquet";
@@ -9,14 +9,16 @@ import type { TemporalFilter } from "./types/datetime";
99
export function StacMapProvider({
1010
href,
1111
fileUpload,
12-
temporalFilter,
1312
children,
1413
}: {
1514
href: string | undefined;
1615
fileUpload: UseFileUploadReturn;
17-
temporalFilter: TemporalFilter | undefined;
1816
children: ReactNode;
1917
}) {
18+
const [unlinkedItems, setUnlinkedItems] = useState<StacItem[]>();
19+
const [picked, setPicked] = useState<StacItem>();
20+
const [temporalFilter, setTemporalFilter] = useState<TemporalFilter>();
21+
2022
// TODO we should probably consolidate useStacValue and useStacGeoparquet into
2123
// a single hook, since they're coupled.
2224
const {
@@ -34,8 +36,10 @@ export function StacMapProvider({
3436
setId: setStacGeoparquetItemId,
3537
item: stacGeoparquetItem,
3638
} = useStacGeoparquet(parquetPath, temporalFilter);
37-
const [items, setItems] = useState<StacItem[]>();
38-
const [picked, setPicked] = useState<StacItem>();
39+
40+
const items = useMemo(() => {
41+
return unlinkedItems || linkedItems;
42+
}, [unlinkedItems, linkedItems]);
3943

4044
useEffect(() => {
4145
if (value?.title || value?.id) {
@@ -44,30 +48,65 @@ export function StacMapProvider({
4448
document.title = "stac-map";
4549
}
4650

47-
setItems(undefined);
51+
setUnlinkedItems(undefined);
4852
setPicked(undefined);
4953
}, [value]);
5054

5155
useEffect(() => {
5256
setPicked(stacGeoparquetItem);
5357
}, [stacGeoparquetItem]);
5458

59+
const filteredItems = useMemo(() => {
60+
if (items && temporalFilter) {
61+
return items.filter((item) =>
62+
isItemWithinTemporalFilter(item, temporalFilter),
63+
);
64+
} else {
65+
return undefined;
66+
}
67+
}, [items, temporalFilter]);
68+
5569
return (
5670
<StacMapContext.Provider
5771
value={{
5872
value,
5973
collections,
60-
linkedItems,
6174
items,
62-
setItems,
75+
setItems: setUnlinkedItems,
6376
picked,
6477
setPicked,
6578
stacGeoparquetTable,
6679
stacGeoparquetMetadata,
6780
setStacGeoparquetItemId,
81+
temporalFilter,
82+
setTemporalFilter,
83+
filteredItems,
6884
}}
6985
>
7086
{children}
7187
</StacMapContext.Provider>
7288
);
7389
}
90+
91+
function isItemWithinTemporalFilter(
92+
item: StacItem,
93+
temporalFilter: TemporalFilter,
94+
) {
95+
const start = item.properties?.start_datetime
96+
? new Date(item.properties.start_datetime)
97+
: item.properties?.datetime
98+
? new Date(item.properties.datetime)
99+
: null;
100+
if (!start) {
101+
return false;
102+
}
103+
const end = item.properties?.end_datetime
104+
? new Date(item.properties.end_datetime)
105+
: item.properties?.datetime
106+
? new Date(item.properties.datetime)
107+
: null;
108+
if (!end) {
109+
return false;
110+
}
111+
return start >= temporalFilter.start && end <= temporalFilter.end;
112+
}

0 commit comments

Comments
 (0)