Skip to content

Commit

Permalink
Add filter grid scale to header when "sketching"
Browse files Browse the repository at this point in the history
  • Loading branch information
underbluewaters committed Dec 11, 2024
1 parent fb336d5 commit 0808adf
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 16 deletions.
63 changes: 62 additions & 1 deletion packages/client/src/formElements/FilterInputContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,38 @@ import { MapContext } from "../dataLayers/MapContextManager";
import { FormElementDetailsFragment } from "../generated/graphql";
import useDebounce from "../useDebounce";

// TODO: this should be derived from the metadata once the service is updated
export type Stop = {
h3Resolution: number;
zoomLevel: number;
gridSize: number;
};

/**
* These stops represent the zoom levels at which each h3 resolution should be
* displayed. The algorithm will fill in the gaps, starting at the highest zoom
* level and working its way down to MIN_ZOOM.
*/
export const stops: Stop[] = [
{ h3Resolution: 11, zoomLevel: 14, gridSize: 44 },
{ h3Resolution: 10, zoomLevel: 13, gridSize: 116 },
{ h3Resolution: 9, zoomLevel: 12, gridSize: 306 },
{ h3Resolution: 8, zoomLevel: 10, gridSize: 810 },
{ h3Resolution: 7, zoomLevel: 8, gridSize: 2100 },
{ h3Resolution: 6, zoomLevel: 6, gridSize: 5700 },
].sort((a, b) => b.zoomLevel - a.zoomLevel);

export function zoomToStop(zoom: number, stops: Stop[]): Stop {
let stop = stops[0];
for (let i = 0; i < stops.length; i++) {
if (zoom > stops[i].zoomLevel) {
break;
}
stop = stops[i];
}
return stop;
}

export type FilterGeostatsAttribute = Pick<
GeostatsAttribute,
"attribute" | "type" | "max" | "min" | "values"
Expand Down Expand Up @@ -49,6 +81,11 @@ export const FilterInputServiceContext = createContext<{
updatingCount: boolean;
count: number;
fullCellCount: number;
stopInformation?: {
resolution: number;
area: number;
unit: string;
};
}>({
loading: false,
getAttributeDetails: () => null,
Expand Down Expand Up @@ -147,12 +184,36 @@ export function FilterInputServiceContextProvider({
}
}, [mapContext.manager, state.metadata, serviceLocation]);

const [zoom, setZoom] = useState(0);
useEffect(() => {
const map = mapContext.manager?.map;
if (map) {
const listener = () => {
setZoom(map.getZoom());
};
map.on("zoom", listener);
return () => {
map.off("zoom", listener);
};
}
}, [mapContext.manager?.map]);

const stopInformation = useMemo(() => {
const stop = zoomToStop(Math.floor(zoom), stops);
return {
resolution: stop.h3Resolution,
area: stop.gridSize > 1000 ? stop.gridSize / 1000 : stop.gridSize,
unit: stop.gridSize > 1000 ? "kilometer" : "meter",
};
}, [zoom]);

const value = useMemo(() => {
return {
...state,
getAttributeDetails,
stopInformation,
};
}, [state, getAttributeDetails]);
}, [state, getAttributeDetails, stopInformation]);

const debouncedStartingProperties = useDebounce(startingProperties, 100);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,62 @@ import { Trans } from "react-i18next";
import { FilterInputServiceContext } from "../../formElements/FilterInputContext";
import Spinner from "../../components/Spinner";

const NumberFormatter = new Intl.NumberFormat("en-US", {
maximumFractionDigits: 1,
});

export default function FilteredPlanningUnitCountHeader() {
const context = useContext(FilterInputServiceContext);
return (
<div
className={`w-full flex items-center p-2 px-4 border-b bg-gray-50 text-sm ${
className={`border-b bg-gray-50 text-sm ${
context.updatingCount ? "opacity-50" : "opacity-100"
}`}
>
<div className="flex-1">
<Trans ns="sketching">
<b className="font-semibold">
{context?.count.toLocaleString() || 0} cells
</b>{" "}
matching criteria
</Trans>
</div>
<div
className={`ml-2 flex items-center transition-opacity delay-500 ${
context.updatingCount ? "opacity-100" : "opacity-0"
}`}
>
<Spinner />
<div className={`w-full flex items-center p-2 px-4 `}>
<div className="flex-1">
<Trans ns="sketching">
<b className="font-semibold">
{context?.count.toLocaleString() || 0} cells
</b>{" "}
matching criteria
</Trans>
</div>
<div
className={`ml-2 flex items-center transition-opacity delay-500 ${
context.updatingCount ? "opacity-100" : "opacity-0"
}`}
>
<Spinner />
</div>
</div>
{context.stopInformation && (
<div className={`w-full flex items-center pb-2 px-4`}>
{context.stopInformation.resolution === 11 ? (
<div>
<Trans ns="sketching">
Full resolution cells are being shown, roughly equivalent to a{" "}
<b>
{context.stopInformation.area.toString()}{" "}
{context.stopInformation.unit}
</b>{" "}
square grid.
</Trans>
</div>
) : (
<div>
<Trans ns="sketching">
Downsampled cells are displayed, roughly equivalent to a{" "}
<b>
{NumberFormatter.format(context.stopInformation.area)}{" "}
{context.stopInformation.unit}
</b>{" "}
square grid. Zoom in to see the full resolution cells.
</Trans>
</div>
)}
</div>
)}
</div>
);
}

0 comments on commit 0808adf

Please sign in to comment.