satupeta-main/app/(modules)/maps/state/active-layers.ts
2026-01-27 09:31:12 +07:00

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)));
});