diff --git a/src/app.tsx b/src/app.tsx index 937545e..b2f1d06 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -9,10 +9,12 @@ import useStacValue from "./hooks/stac-value"; import type { BBox2D, Color } from "./types/map"; import type { DatetimeBounds, StacValue } from "./types/stac"; import { + isCog, isCollectionInBbox, isCollectionInDatetimeBounds, isItemInBbox, isItemInDatetimeBounds, + isVisual, } from "./utils/stac"; // TODO make this configurable by the user. @@ -30,6 +32,7 @@ export default function App() { const [datetimeBounds, setDatetimeBounds] = useState(); const [filter, setFilter] = useState(true); const [stacGeoparquetItemId, setStacGeoparquetItemId] = useState(); + const [cogTileHref, setCogTileHref] = useState(); // Derived state const { @@ -116,6 +119,17 @@ export default function App() { setItems(undefined); setDatetimeBounds(undefined); + let cogTileHref = undefined; + if (value && value.assets) { + for (const asset of Object.values(value.assets)) { + if (isCog(asset) && isVisual(asset)) { + cogTileHref = asset.href as string; + break; + } + } + } + setCogTileHref(cogTileHref); + if (value && (value.title || value.id)) { document.title = "stac-map | " + (value.title || value.id); } else { @@ -151,6 +165,7 @@ export default function App() { picked={picked} setPicked={setPicked} setStacGeoparquetItemId={setStacGeoparquetItemId} + cogTileHref={cogTileHref} > @@ -184,6 +199,8 @@ export default function App() { filteredItems={filteredItems} setItems={setItems} setDatetimeBounds={setDatetimeBounds} + cogTileHref={cogTileHref} + setCogTileHref={setCogTileHref} > diff --git a/src/components/assets.tsx b/src/components/assets.tsx index 03ef2ab..5c7372a 100644 --- a/src/components/assets.tsx +++ b/src/components/assets.tsx @@ -1,26 +1,41 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { LuDownload } from "react-icons/lu"; import { Button, ButtonGroup, Card, + Checkbox, Collapsible, DataList, HStack, Image, + Span, } from "@chakra-ui/react"; import type { StacAsset } from "stac-ts"; import Properties from "./properties"; import type { StacAssets } from "../types/stac"; +import { isCog, isVisual } from "../utils/stac"; -export default function Assets({ assets }: { assets: StacAssets }) { +export default function Assets({ + assets, + cogTileHref, + setCogTileHref, +}: { + assets: StacAssets; + cogTileHref: string | undefined; + setCogTileHref: (href: string | undefined) => void; +}) { return ( {Object.keys(assets).map((key) => ( {key} - + ))} @@ -28,11 +43,24 @@ export default function Assets({ assets }: { assets: StacAssets }) { ); } -function Asset({ asset }: { asset: StacAsset }) { +function Asset({ + asset, + cogTileHref, + setCogTileHref, +}: { + asset: StacAsset; + cogTileHref: string | undefined; + setCogTileHref: (href: string | undefined) => void; +}) { const [imageError, setImageError] = useState(false); + const [checked, setChecked] = useState(false); // eslint-disable-next-line const { href, roles, type, title, ...properties } = asset; + useEffect(() => { + setChecked(cogTileHref === asset.href); + }, [cogTileHref, asset.href]); + return ( @@ -64,7 +92,24 @@ function Asset({ asset }: { asset: StacAsset }) { )} - + + {isCog(asset) && isVisual(asset) && ( + { + setChecked(!!e.checked); + if (e.checked) setCogTileHref(asset.href); + else setCogTileHref(undefined); + }} + > + + + Visualize + + )} + + +