/** * 高德地图点标记绘制相关 */ import { map, AMap } from './index' import { useToolboxStore } from '@/stores/toolbox' import util from './util' import * as echarts from 'echarts' import exceedIcon from '@/assets/exceed.png' import exceptionIcon from '@/assets/exception.png' import offlineIcon from '@/assets/offline.png' const toolboxStore = useToolboxStore() var _massMarks = undefined // 状态图标配置 const statusIcons = { exceed: exceedIcon, // 油烟浓度超标 exception: exceptionIcon, // 供电异常 offline: offlineIcon, // 设备或网络异常 online: createCustomMarkerOnline(), // 在线状态 offlineStatus: createCustomMarkerOffline(), // 离线状态 } /** * 绘制海量点标记 * @param {Array} shops 店铺对象数组 * @param {Object} shops[].shop 店铺基本信息 * @param {string} shops[].shop.name 店铺名称 * @param {string} shops[].shop.address 店铺地址 * @param {number} shops[].shop.latitude 纬度 * @param {number} shops[].shop.longitude 经度 * @param {string} shops[].shop.ringCodeLevel 最新环信码等级 * @param {string} shops[].shop.ringCodePublishTime 最新环信码发布时间 * @param {boolean} shops[].shop.isOnline 在线状态 * @param {number} shops[].shop.exceptionStatus 异常状态(0: 油烟浓度超标, 1: 供电异常, 2: 设备或网络异常, 3: 无异常) * @param {Array} shops[].recentData 近1小时的监测数据 * @param {string} shops[].recentData[].sampleTime 数据采样时间 * @param {number} shops[].recentData[].oilSmokeConcentration 油烟浓度 * @param {number} shops[].recentData[].purifierCurrent 净化器电流 * @param {number} shops[].recentData[].fanCurrent 风机电流 */ function drawMassMarks(shops) { // 配置样式 const massMarksStyle = [ { url: statusIcons.exceed, size: new AMap.Size(20, 20), anchor: new AMap.Pixel(10, 10), }, { url: statusIcons.exception, size: new AMap.Size(20, 20), anchor: new AMap.Pixel(10, 10), }, { url: statusIcons.offline, size: new AMap.Size(20, 20), anchor: new AMap.Pixel(10, 10), }, { url: statusIcons.online, size: new AMap.Size(32, 32), anchor: new AMap.Pixel(10, 10), }, { url: statusIcons.offlineStatus, size: new AMap.Size(32, 32), anchor: new AMap.Pixel(10, 10), }, ] // 准备海量点数据 const massMarksData = shops.map((shop, index) => { // 根据异常状态和在线状态获取样式索引 let styleIndex = 3 // 默认在线状态 if (shop.shop.exceptionStatus !== undefined) { switch (shop.shop.exceptionStatus) { case 0: // 油烟浓度超标 styleIndex = 0 break case 1: // 供电异常 styleIndex = 1 break case 2: // 设备或网络异常 styleIndex = 2 break case 3: // 无异常,根据在线状态决定 styleIndex = shop.shop.isOnline ? 3 : 4 break default: styleIndex = shop.shop.isOnline ? 3 : 4 } } else { // 没有异常状态时,根据在线状态决定 styleIndex = shop.shop.isOnline ? 3 : 4 } return { id: index, name: shop.shop.name, lnglat: [shop.shop.longitude, shop.shop.latitude], style: styleIndex, // 样式索引,对应 massMarksStyle extData: shop, // 存储完整的店铺信息 } }) // 清除现有的海量点标记 if (window.massMarks) { window.massMarks.clear() } // 创建新的海量点标记 window.massMarks = new AMap.MassMarks(massMarksData, { zIndex: 111, cursor: 'pointer', style: massMarksStyle, }) // 添加点击事件 window.massMarks.on('click', function (e) { const shop = e.data.extData showShopInfoWindow(shop) }) var marker = new AMap.Marker({ content: ' ', map: map, offset: new AMap.Pixel(13, 12), }) var timeout window.massMarks.on('mouseover', (e) => { if (timeout) { clearTimeout(timeout) } marker.setPosition(e.data.lnglat) marker.setLabel({ content: e.data.name }) map.add(marker) timeout = setTimeout(() => { map.remove(marker) }, 2000) }) // 添加到地图 window.massMarks.setMap(map) util.setBound(massMarksData.map((item) => item.lnglat)) } /** * 根据环信码等级获取颜色 * @param {string} level 环信码等级 * @returns {string} 颜色值 */ function getColorByRingCodeLevel(level) { switch (level + '') { case '0': return '#52c41a' // 绿色 case '1': return '#faad14' // 黄色 case '2': return '#f5222d' // 红色 default: return '#8c8c8c' // 灰色 } } /** * 根据环信码等级获取中文 * @param {string} level 环信码等级 * @returns {string} 中文表示 */ function getRingCodeLevelText(level) { switch (level + '') { case '0': return '绿色' case '1': return '黄色' case '2': return '红色' default: return '未知' } } /** * 根据异常状态获取中文 * @param {number} status 异常状态 * @returns {string} 中文表示 */ function getExceptionStatusText(status) { switch (status + '') { case '0': return '油烟浓度超标' case '1': return '供电异常' case '2': return '设备或网络异常' case '3': return '无异常' default: return '未知状态' } } /** * 根据异常状态获取颜色 * @param {number} status 异常状态 * @returns {string} 颜色值 */ function getColorByExceptionStatus(status) { switch (status + '') { case '0': return '#f5222d' // 油烟浓度超标 - 红色 case '1': return '#faad14' // 供电异常 - 黄色 case '2': return '#8c8c8c' // 设备或网络异常 - 灰色 case '3': return '#52c41a' // 无异常 - 绿色 default: return '#8c8c8c' // 灰色 } } /** * 创建自定义标记 * @param {string} color 标记颜色 * @returns {string} 标记的SVG URL */ function createCustomMarker(color) { const svg = ` ` return 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svg))) } /** * 创建在线状态的SVG标记(油烟监测设备形象) * @returns {string} 标记的SVG URL */ function createCustomMarkerOnline() { const svg = ` ` return 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svg))) } /** * 创建离线状态的SVG标记(油烟监测设备形象) * @returns {string} 标记的SVG URL */ function createCustomMarkerOffline() { const svg = ` ` return 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svg))) } /** * 显示店铺信息窗口 * @param {Object} shop 店铺对象 */ function showShopInfoWindow(shop) { // 准备信息窗口内容 // 获取在线状态文本 const onlineStatusText = shop.shop.isOnline ? '在线' : '离线' // 获取异常状态文本 const exceptionStatusText = getExceptionStatusText(shop.shop.exceptionStatus) // 获取异常状态颜色 const exceptionStatusColor = getColorByExceptionStatus(shop.shop.exceptionStatus) // 根据状态获取对应的图标 let statusIcon = statusIcons.online // 默认在线图标 if (shop.shop.exceptionStatus !== undefined) { switch (shop.shop.exceptionStatus) { case 0: statusIcon = statusIcons.exceed break case 1: statusIcon = statusIcons.exception break case 2: statusIcon = statusIcons.offline break case 3: statusIcon = shop.shop.isOnline ? statusIcons.online : statusIcons.offlineStatus break default: statusIcon = shop.shop.isOnline ? statusIcons.online : statusIcons.offlineStatus } } else { statusIcon = shop.shop.isOnline ? statusIcons.online : statusIcons.offlineStatus } // 根据在线状态获取图标 const onlineIcon = shop.shop.isOnline ? statusIcons.online : statusIcons.offlineStatus // 根据异常状态获取图标 let exceptionIcon = statusIcons.online // 默认在线图标 if (shop.shop.exceptionStatus !== undefined) { switch (shop.shop.exceptionStatus) { case 0: exceptionIcon = statusIcons.exceed break case 1: exceptionIcon = statusIcons.exception break case 2: exceptionIcon = statusIcons.offline break case 3: exceptionIcon = statusIcons.online break default: exceptionIcon = statusIcons.online } } const content = `
地址:${shop.shop.address}
在线状态:${onlineStatusText}
异常状态:${exceptionStatusText}
环信码等级:${getRingCodeLevelText(shop.shop.ringCodeLevel)}
环信码发布时间:${shop.shop.ringCodePublishTime}