151 lines
5.1 KiB
TypeScript
151 lines
5.1 KiB
TypeScript
import type { StyleConfig, DefaultLayerStyleId } from "@components/olmap/core/Controls/styleEditorTypes";
|
|
|
|
export type ApplyLayerStyleActionPayload = {
|
|
layerId: DefaultLayerStyleId;
|
|
resetToDefault: boolean;
|
|
styleConfig?: Partial<StyleConfig>;
|
|
};
|
|
|
|
export const APPLY_LAYER_STYLE_TOOL = "apply_layer_style";
|
|
|
|
const LAYER_LABELS: Record<DefaultLayerStyleId, string> = {
|
|
junctions: "节点",
|
|
pipes: "管道",
|
|
};
|
|
|
|
const asString = (value: unknown): string | undefined =>
|
|
typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
|
|
const asNumber = (value: unknown): number | undefined =>
|
|
typeof value === "number" && Number.isFinite(value)
|
|
? value
|
|
: typeof value === "string" && value.trim() && Number.isFinite(Number(value))
|
|
? Number(value)
|
|
: undefined;
|
|
|
|
const asBoolean = (value: unknown): boolean | undefined =>
|
|
typeof value === "boolean"
|
|
? value
|
|
: typeof value === "string"
|
|
? value === "true"
|
|
? true
|
|
: value === "false"
|
|
? false
|
|
: undefined
|
|
: undefined;
|
|
|
|
const asNumberArray = (value: unknown): number[] | undefined =>
|
|
Array.isArray(value)
|
|
? value
|
|
.map((item) => asNumber(item))
|
|
.filter((item): item is number => item !== undefined)
|
|
: undefined;
|
|
|
|
const asStringArray = (value: unknown): string[] | undefined =>
|
|
Array.isArray(value)
|
|
? value
|
|
.map((item) => asString(item))
|
|
.filter((item): item is string => item !== undefined)
|
|
: undefined;
|
|
|
|
export const normalizeStyleLayerId = (value: unknown): DefaultLayerStyleId | null => {
|
|
const normalized = asString(value)?.toLowerCase();
|
|
if (normalized === "junctions" || normalized === "pipes") {
|
|
return normalized;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
export const getStyleLayerLabel = (layerId: DefaultLayerStyleId): string =>
|
|
LAYER_LABELS[layerId];
|
|
|
|
export const parseApplyLayerStylePayload = (
|
|
params: Record<string, unknown>,
|
|
): ApplyLayerStyleActionPayload | null => {
|
|
const layerId = normalizeStyleLayerId(params.layer_id ?? params.layerId);
|
|
if (!layerId) {
|
|
return null;
|
|
}
|
|
|
|
const resetToDefault = Boolean(
|
|
asBoolean(params.reset_to_default ?? params.resetToDefault),
|
|
);
|
|
const rawStyleConfig =
|
|
params.style_config && typeof params.style_config === "object"
|
|
? (params.style_config as Record<string, unknown>)
|
|
: params.styleConfig && typeof params.styleConfig === "object"
|
|
? (params.styleConfig as Record<string, unknown>)
|
|
: null;
|
|
|
|
const styleConfig: Partial<StyleConfig> | undefined = rawStyleConfig
|
|
? {
|
|
property: asString(rawStyleConfig.property),
|
|
classificationMethod: asString(
|
|
rawStyleConfig.classification_method ?? rawStyleConfig.classificationMethod,
|
|
),
|
|
segments: asNumber(rawStyleConfig.segments),
|
|
minSize: asNumber(rawStyleConfig.min_size ?? rawStyleConfig.minSize),
|
|
maxSize: asNumber(rawStyleConfig.max_size ?? rawStyleConfig.maxSize),
|
|
minStrokeWidth: asNumber(
|
|
rawStyleConfig.min_stroke_width ?? rawStyleConfig.minStrokeWidth,
|
|
),
|
|
maxStrokeWidth: asNumber(
|
|
rawStyleConfig.max_stroke_width ?? rawStyleConfig.maxStrokeWidth,
|
|
),
|
|
fixedStrokeWidth: asNumber(
|
|
rawStyleConfig.fixed_stroke_width ?? rawStyleConfig.fixedStrokeWidth,
|
|
),
|
|
colorType: asString(rawStyleConfig.color_type ?? rawStyleConfig.colorType),
|
|
singlePaletteIndex: asNumber(
|
|
rawStyleConfig.single_palette_index ?? rawStyleConfig.singlePaletteIndex,
|
|
),
|
|
gradientPaletteIndex: asNumber(
|
|
rawStyleConfig.gradient_palette_index ?? rawStyleConfig.gradientPaletteIndex,
|
|
),
|
|
rainbowPaletteIndex: asNumber(
|
|
rawStyleConfig.rainbow_palette_index ?? rawStyleConfig.rainbowPaletteIndex,
|
|
),
|
|
showLabels: asBoolean(rawStyleConfig.show_labels ?? rawStyleConfig.showLabels),
|
|
showId: asBoolean(rawStyleConfig.show_id ?? rawStyleConfig.showId),
|
|
opacity: asNumber(rawStyleConfig.opacity),
|
|
adjustWidthByProperty: asBoolean(
|
|
rawStyleConfig.adjust_width_by_property ??
|
|
rawStyleConfig.adjustWidthByProperty,
|
|
),
|
|
customBreaks: asNumberArray(
|
|
rawStyleConfig.custom_breaks ?? rawStyleConfig.customBreaks,
|
|
),
|
|
customColors: asStringArray(
|
|
rawStyleConfig.custom_colors ?? rawStyleConfig.customColors,
|
|
),
|
|
}
|
|
: undefined;
|
|
|
|
const hasStyleOverrides =
|
|
styleConfig &&
|
|
Object.values(styleConfig).some((value) =>
|
|
Array.isArray(value) ? value.length > 0 : value !== undefined,
|
|
);
|
|
|
|
if (!resetToDefault && !hasStyleOverrides) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
layerId,
|
|
resetToDefault,
|
|
styleConfig: hasStyleOverrides ? styleConfig : undefined,
|
|
};
|
|
};
|
|
|
|
export const describeApplyLayerStyle = (
|
|
payload: ApplyLayerStyleActionPayload,
|
|
): string => {
|
|
const layerLabel = getStyleLayerLabel(payload.layerId);
|
|
if (payload.resetToDefault) {
|
|
return `${layerLabel} · 重置默认样式`;
|
|
}
|
|
const property = payload.styleConfig?.property;
|
|
return property ? `${layerLabel} · ${property}` : `${layerLabel} · 应用样式`;
|
|
};
|