128 lines
3.4 KiB
TypeScript
128 lines
3.4 KiB
TypeScript
import { atom } from "jotai";
|
|
|
|
import { LatLngBoundsExpression } from "leaflet";
|
|
|
|
type LayerSettings = {
|
|
visible: boolean;
|
|
opacity: number;
|
|
zIndex: number;
|
|
};
|
|
|
|
export type WMSLayerConfig = {
|
|
type: "wms";
|
|
url?: string;
|
|
layers?: string;
|
|
format?: string;
|
|
transparent?: boolean;
|
|
bounds?: LatLngBoundsExpression | null;
|
|
};
|
|
|
|
export type Source = {
|
|
id: number | string;
|
|
source: string;
|
|
};
|
|
|
|
export type LayerMode = "basic" | "choropleth";
|
|
|
|
export type ActiveLayer = {
|
|
id: string;
|
|
name: string;
|
|
source: Source;
|
|
settings: LayerSettings;
|
|
layer: WMSLayerConfig;
|
|
mode?: LayerMode;
|
|
};
|
|
|
|
export const activeLayersAtom = atom<ActiveLayer[]>([]);
|
|
|
|
export const addLayerAtom = atom(null, (get, set, layer: Omit<ActiveLayer, "settings">) => {
|
|
set(activeLayersAtom, [
|
|
...get(activeLayersAtom),
|
|
{
|
|
...layer,
|
|
settings: {
|
|
visible: true,
|
|
opacity: 1,
|
|
zIndex: get(activeLayersAtom).length + 1,
|
|
},
|
|
},
|
|
]);
|
|
});
|
|
|
|
export const toggleLayerAtom = atom(null, (get, set, layerId: string) => {
|
|
set(activeLayersAtom, (prev) =>
|
|
prev.map((layer) =>
|
|
layer.id === layerId
|
|
? {
|
|
...layer,
|
|
settings: { ...layer.settings, visible: !layer.settings.visible },
|
|
}
|
|
: layer
|
|
)
|
|
);
|
|
});
|
|
|
|
export const removeLayerAtom = atom(null, (get, set, layerId: string) => {
|
|
set(activeLayersAtom, (prev) => prev.filter((layer) => layer.id !== layerId));
|
|
});
|
|
|
|
export const setLayerOpacityAtom = atom(null, (get, set, { layerId, opacity }: { layerId: string; opacity: number }) => {
|
|
set(activeLayersAtom, (prev) => prev.map((layer) => (layer.id === layerId ? { ...layer, settings: { ...layer.settings, opacity } } : layer)));
|
|
});
|
|
|
|
export const reorderLayersAtom = atom(null, (get, set, { fromIndex, toIndex }: { fromIndex: number; toIndex: number }) => {
|
|
const layers = [...get(activeLayersAtom)];
|
|
const [moved] = layers.splice(fromIndex, 1);
|
|
layers.splice(toIndex, 0, moved);
|
|
|
|
const updated = layers.map((layer, index) => ({
|
|
...layer,
|
|
settings: {
|
|
...layer.settings,
|
|
zIndex: index + 1,
|
|
},
|
|
}));
|
|
|
|
set(activeLayersAtom, updated);
|
|
});
|
|
|
|
export const enableAllLayersAtom = atom(null, (get, set) => {
|
|
set(activeLayersAtom, (prev) =>
|
|
prev.map((layer) => ({
|
|
...layer,
|
|
settings: { ...layer.settings, visible: true },
|
|
}))
|
|
);
|
|
});
|
|
|
|
export const disableAllLayersAtom = atom(null, (get, set) => {
|
|
set(activeLayersAtom, (prev) =>
|
|
prev.map((layer) => ({
|
|
...layer,
|
|
settings: { ...layer.settings, visible: false },
|
|
}))
|
|
);
|
|
});
|
|
|
|
export const toggleAllLayersAtom = atom(null, (get, set) => {
|
|
const allVisible = get(activeLayersAtom).every((layer) => layer.settings.visible);
|
|
set(activeLayersAtom, (prev) =>
|
|
prev.map((layer) => ({
|
|
...layer,
|
|
settings: { ...layer.settings, visible: !allVisible },
|
|
}))
|
|
);
|
|
});
|
|
|
|
export const allLayersVisibleAtom = atom((get) => get(activeLayersAtom).every((layer) => layer.settings.visible));
|
|
|
|
export const anyLayersVisibleAtom = atom((get) => get(activeLayersAtom).some((layer) => layer.settings.visible));
|
|
|
|
export const removeAllLayersAtom = atom(null, (get, set) => {
|
|
set(activeLayersAtom, []); // Clear all layers from the activeLayersAtom
|
|
});
|
|
|
|
export const setLayerModeAtom = atom(null, (get, set, { layerId, mode }: { layerId: string; mode: LayerMode }) => {
|
|
set(activeLayersAtom, (prev) => prev.map((layer) => (layer.id === layerId ? { ...layer, mode } : layer)));
|
|
});
|