Skip to content
Merged
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
162 changes: 120 additions & 42 deletions src/components/children.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { Card, HStack, Icon, Link, Stack, Text } from "@chakra-ui/react";
import type { ReactNode } from "react";
import {
Card,
Checkbox,
HStack,
Icon,
Link,
Stack,
Text,
} from "@chakra-ui/react";
import { useEffect, useState, type ReactNode } from "react";
import { LuFolderPlus, LuFolderSearch } from "react-icons/lu";
import { MarkdownHooks } from "react-markdown";
import type { StacCatalog, StacCollection } from "stac-ts";
Expand All @@ -8,6 +16,8 @@ import { useChildren } from "../hooks/stac-value";
import type { SetHref } from "../types/app";
import { CollectionSearch } from "./search/collection";
import Section from "./section";
import { useMap } from "react-map-gl/maplibre";
import type { BBox } from "geojson";

export function Children({
value,
Expand All @@ -18,51 +28,93 @@ export function Children({
}) {
const { collections } = useStacMap();
const children = useChildren(value, !!collections);
const { map } = useMap();
const selfHref = value?.links?.find((link) => link.rel === "self")?.href;
const [mapBbox, setMapBbox] = useState<BBox>();
const [filterByViewport, setFilterByViewport] = useState(true);
const [filteredCollections, setFilteredCollections] = useState(collections);

useEffect(() => {
if (map) {
map.on("moveend", () => {
if (map) {
setMapBbox(map.getBounds().toArray().flat() as BBox);
}
});
}
}, [map]);

useEffect(() => {
if (filterByViewport && mapBbox) {
setFilteredCollections(
collections?.filter((collection) =>
isCollectionInBbox(collection, mapBbox),
),
);
} else {
setFilteredCollections(collections);
}
}, [collections, filterByViewport, mapBbox]);

return (
<>
{collections && collections?.length > 0 && (
<>
<Section
title={
<HStack>
<Icon>
<LuFolderSearch></LuFolderSearch>
</Icon>{" "}
Collection search
</HStack>
}
>
<CollectionSearch
href={selfHref}
setHref={setHref}
collections={collections}
></CollectionSearch>
</Section>
{collections &&
filteredCollections &&
filteredCollections?.length > 0 && (
<>
<Section
title={
<HStack>
<Icon>
<LuFolderSearch></LuFolderSearch>
</Icon>{" "}
Collection search
</HStack>
}
>
<CollectionSearch
href={selfHref}
setHref={setHref}
collections={filteredCollections}
></CollectionSearch>
</Section>

<Section
title={
<HStack>
<Icon>
<LuFolderPlus></LuFolderPlus>
</Icon>{" "}
Collections ({collections.length})
</HStack>
}
>
<Stack>
{collections.map((collection) => (
<ChildCard
child={collection}
setHref={setHref}
key={"collection-" + collection.id}
></ChildCard>
))}
</Stack>
</Section>
</>
)}
<Section
title={
<HStack>
<Icon>
<LuFolderPlus></LuFolderPlus>
</Icon>{" "}
Collections (
{(filterByViewport &&
filteredCollections.length + "/" + collections.length) ||
collections.length}
)
</HStack>
}
>
<Stack>
<Checkbox.Root
mb={2}
size={"sm"}
checked={filterByViewport}
onCheckedChange={(e) => setFilterByViewport(!!e.checked)}
>
<Checkbox.HiddenInput></Checkbox.HiddenInput>
<Checkbox.Control></Checkbox.Control>
<Checkbox.Label>Filter by viewport</Checkbox.Label>
</Checkbox.Root>
{filteredCollections.map((collection) => (
<ChildCard
child={collection}
setHref={setHref}
key={"collection-" + collection.id}
></ChildCard>
))}
</Stack>
</Section>
</>
)}

{children && children.length > 0 && (
<Section title="Children">
Expand Down Expand Up @@ -114,3 +166,29 @@ export function ChildCard({
</Card.Root>
);
}

function isCollectionInBbox(collection: StacCollection, bbox: BBox) {
if (bbox[2] - bbox[0] >= 360) {
// A global bbox always contains every collection
return true;
}
const collectionBbox = collection?.extent?.spatial?.bbox?.[0];
if (collectionBbox) {
return (
!(
collectionBbox[0] < bbox[0] &&
collectionBbox[1] < bbox[1] &&
collectionBbox[2] > bbox[2] &&
collectionBbox[3] > bbox[3]
) &&
!(
collectionBbox[0] > bbox[2] ||
collectionBbox[1] > bbox[3] ||
collectionBbox[2] < bbox[0] ||
collectionBbox[3] < bbox[1]
)
);
} else {
return false;
}
}