import type { StyleConfig, DefaultLayerStyleId } from "@components/olmap/core/Controls/styleEditorTypes"; export type ApplyLayerStyleActionPayload = { layerId: DefaultLayerStyleId; resetToDefault: boolean; styleConfig?: Partial; }; export const APPLY_LAYER_STYLE_TOOL = "apply_layer_style"; const LAYER_LABELS: Record = { 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, ): 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) : params.styleConfig && typeof params.styleConfig === "object" ? (params.styleConfig as Record) : null; const styleConfig: Partial | 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} · 应用样式`; };