/** * 地图工具函数 */ import { Style, Text, Circle, Fill, Stroke, Icon } from 'ol/style' import { Feature } from 'ol' import type { MarkerData, DetectorInfo } from '../types/map.types' import { STATUS_DICT, STATUS_PRIORITY, STATUS_ORDER } from '../constants/map.constants' /** * 从字典中查找状态信息 */ export const findStatusInfo = ( dict: (typeof STATUS_DICT)[keyof typeof STATUS_DICT], value: string ) => { return dict.find((item) => item.value === value) } /** * 获取状态映射 */ export const getStatusMapping = (type: keyof typeof STATUS_DICT, value: string): string => { const info = findStatusInfo(STATUS_DICT[type], value) return info ? `${type}_${value}` : '' } // 获取状态优先级,越小优先级越高 export const getStatusPriority = (statusStr: string | keyof typeof STATUS_PRIORITY): number => { return STATUS_PRIORITY[statusStr] || 0 } /** * 根据字典数据获取设备最高优先级状态 */ export const getHighestPriorityStatus = (markerData: { gasStatus?: number batteryStatus?: number fenceStatus?: number onlineStatus?: number }): keyof typeof STATUS_PRIORITY => { const statuses: string[] = [] // 收集非正常状态 if (markerData.gasStatus !== 0) { const gasStatusStr = getStatusMapping('gasStatus', String(markerData.gasStatus)) gasStatusStr && statuses.push(gasStatusStr) } if (markerData.batteryStatus !== 0) { const batteryStatusStr = getStatusMapping('batteryStatus', String(markerData.batteryStatus)) statuses.push(batteryStatusStr) } if (markerData.fenceStatus !== 0) { const fenceStatusStr = getStatusMapping('fenceStatus', String(markerData.fenceStatus)) fenceStatusStr && statuses.push(fenceStatusStr) } // 检查各种状态 const onlineStatus = String(markerData.onlineStatus) === '0' ? 'offline' : null if (onlineStatus) { statuses.push(onlineStatus) } // console.log('statuses', statuses) // 如果没有报警状态,则为正常 if (statuses.length === 0) return 'normal' // 返回优先级最高的状态 return statuses.reduce((prev, current) => STATUS_PRIORITY[prev] < STATUS_PRIORITY[current] ? prev : current ) as keyof typeof STATUS_PRIORITY } /** * 根据字典数据获取状态颜色 */ export const getStatusColor = (status: string | keyof typeof STATUS_PRIORITY): string => { if (status === 'normal') return '#67c23a' if (status === 'offline') return STATUS_DICT.onlineStatus[0].cssClass const [type, value] = status.split('_') as [keyof typeof STATUS_DICT, string] const info = findStatusInfo(STATUS_DICT[type], value) return info?.cssClass || '#67c23a' } /** * 根据字典数据获取状态标签 */ export const getStatusLabel = (status: string | keyof typeof STATUS_PRIORITY): string => { if (status === 'normal') return '正常' if (status === 'offline') return STATUS_DICT.onlineStatus[0].label const [type, value] = status.split('_') as [keyof typeof STATUS_DICT, string] const info = findStatusInfo(STATUS_DICT[type], value) return info?.label || '正常' } export const getLabelWithTypeValue = (type: string, value: number | undefined): string => { if (value === undefined) return '-' const info = findStatusInfo(STATUS_DICT[type], String(value)) return info?.label || '-' } /** * 创建位置图标SVG */ export const createLocationIconSVG = (color: string, size: number = 24) => { return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(` `)}` } /** * 创建标记样式 */ export const createMarkerStyle = ( statusStr: keyof typeof STATUS_PRIORITY, isCluster: boolean = false, clusterSize?: number ) => { // 如果是字符串,说明是状态值 // const statusStr:string = // typeof markerData === 'string' // ? (markerData as keyof typeof STATUS_PRIORITY) // : getHighestPriorityStatus(markerData) const color = getStatusColor(statusStr) if (isCluster && clusterSize) { // 聚合标记样式 return new Style({ image: new Circle({ radius: Math.min(20 + clusterSize * 2, 40), fill: new Fill({ color: color + '80' // 添加透明度 }), stroke: new Stroke({ color: color, width: 2 }) }), text: new Text({ text: clusterSize.toString(), fill: new Fill({ color: '#ffffff' }), font: 'bold 14px Arial' }) }) } else { // 单个标记样式 - 使用位置图标 return new Style({ image: new Icon({ src: createLocationIconSVG(color, 24), scale: 1, anchor: [0.5, 0.8], // 锚点设置在底部中心 anchorXUnits: 'fraction', anchorYUnits: 'fraction' }) }) } } /** * 生成探测器列表项HTML */ export const createDetectorListItem = (detector: DetectorInfo) => `