<!-- Description: 综合大屏-布控地图 Author: 李亚光 Date: 2024-07-18 --> <script lang="ts" setup> import baseOverView from '../fullScreen-components/baseOverView.vue' import pipeNetworkType from '../fullScreen-components/pipeNetworkType.vue' import monitorDeviceCount from '../fullScreen-components/monitorDeviceCount.vue' import allAlarmStatus from '../fullScreen-components/allAlarmStatus.vue' import deptAlarmCount from '../fullScreen-components/deptAlarmCount.vue' import deviceRunStatus from '../fullScreen-components/deviceRunStatus.vue' import { mapData } from './mapData' import detailInfo from './detailInfoDialog.vue' import AMap from '@/components/map/index.vue' // 地图实例 const mapRef = ref() const zoomStatus = ref('') // 当前缩放状态 // administration行政 demonstration95示范区 const showStatus = ref('administration') // 地图挂载完毕执行 const drawBj = () => { const style = { fillColor: 'transparent', strokeOpacity: 1, fillOpacity: 0.3, strokeColor: '#2b8cbe', strokeWeight: 2, strokeStyle: 'solid', strokeDasharray: [5, 5], activeFillColor: '#3CA4D2', dbclickSetCenter: true, zIndex: 1, } mapData.forEach((item: any) => { // 绘制北京各个区边界 mapRef.value.addPolygon(item.data, { ...style, name: item.name, dbclickCenter: item.center, }) }) } // 图例展示 // const legend = ref(['点', '线']) // 双击多边形(行政区或九五示范区)掉起弹窗 const detail = ref() const detailRef = ref() const polygonClick = (data: any) => { if (zoomStatus.value === 'hidden') { return } console.log(data, '双击行政区') data.map.setCenter(data.style.dbclickCenter) data.map.setZoom(9.6) // 定义弹窗 detail.value = new mapRef.value.AMap.InfoWindow({ closeWhenClickMap: true, // 是否在鼠标点击地图后关闭信息窗体 autoMove: true, // 是否自动调整窗体到视野内 isCustom: true, // 自定义信息窗体 content: detailRef.value.$el, // 窗体内容(vue组件) offset: new mapRef.value.AMap.Pixel(9, -5), // 偏移 }) // 打开信息窗口 detail.value.open(data.map, data.event.lnglat) // 初始化信息窗口 detailRef.value.initDialog({ overlay: data.event.target, infoWindow: detail.value, info: data.style, flag: 'district', // 行政区或95示范区 }) } // 绘制管线 const drawLine = () => { // 模拟海量点数据 const data = [ [115.918546, 39.812809], [115.929436, 39.814813], [115.932418, 39.815577], [115.934778, 39.816881], [115.939913, 39.817421], [115.942935, 39.817867], [115.946041, 39.818535], [115.946609, 39.819261], [115.947517, 39.820288], [115.948852, 39.820757], [115.949681, 39.821012], [115.949213, 39.821635], [115.949137, 39.821666], [115.948514, 39.821778], [115.94831, 39.82186], ] mapRef.value.addPolyline({ path: data, style: { strokeColor: '#BAAF04', strokeWeight: 4, strokeStyle: 'solid', zIndex: 95, zoomLevels: [10.5, 18], }, }) // 判断图例设置(没有显示的直接就隐藏) if (!legend.value.includes('线')) { mapRef.value.lineAllList.forEach((line: any) => { line.hide() }) } } // 点击管线(选中管线高亮) const lineClick = (data: any) => { console.log(data, '点击管线(选中管线高亮)') if (data.polyline.getOptions().strokeWeight === 4.5) { // 取消高亮 data.polyline.setOptions({ strokeColor: '#BAAF04', strokeWeight: 4, }) } else { // 高亮 data.polyline.setOptions({ strokeColor: '#EAFA03', strokeWeight: 4.5, }) } } // 绘制阀门,调压站等点标记 const drawMarker = () => { const style = [ { url: 'https://a.amap.com/jsapi_demos/static/images/mass0.png', // 图标地址 anchor: new mapRef.value.AMap.Pixel(4, 4), // 图标显示位置偏移量,基准点为图标左上角 size: new mapRef.value.AMap.Size(7, 7), // 图标的尺寸 zIndex: 99, // 每种样式图标的叠加顺序,数字越大越靠前 }, { url: 'https://a.amap.com/jsapi_demos/static/images/mass1.png', anchor: new mapRef.value.AMap.Pixel(4, 4), size: new mapRef.value.AMap.Size(11, 11), zIndex: 99, }, ] const data = [ { lnglat: [115.94831, 39.82186], // 经纬度 name: '天安门', style: 1, // 该数据的取值为样式数组对应的对象索引 }, { lnglat: [115.932418, 39.815577], name: '南锣鼓巷', style: 2, }, ] mapRef.value.addMassMarks({ path: data, zIndex: 111, zooms: [10.5, 20], style, }) // 判断图例设置(没有显示的直接就隐藏) if (!legend.value.includes('点')) { mapRef.value.massMarksAllList.forEach((line: any) => { line.hide() }) } } // 阀门,调压站等点标记点击 const massMarksClick = (data: any) => { console.log(data, '阀门,调压站等点标记点击') // 定义弹窗 detail.value = new mapRef.value.AMap.InfoWindow({ closeWhenClickMap: true, // 是否在鼠标点击地图后关闭信息窗体 autoMove: true, // 是否自动调整窗体到视野内 isCustom: true, // 自定义信息窗体 content: detailRef.value.$el, // 窗体内容(vue组件) offset: new mapRef.value.AMap.Pixel(9, -5), // 偏移 }) console.log(detail.value, 'detail.value 点') // 打开信息窗口 console.log(data.event.data.lnglat, 'data.event.data.lnglat') detail.value.open(data.map, data.event.data.lnglat) // 初始化信息窗口 detailRef.value.initDialog({ overlay: data.event.target, infoWindow: detail.value, info: data.event.data, // flag: 'valve', // 阀门 flag: 'district', // 阀门 }) } // 监听地图缩放 watch(() => mapRef.value?.zoom, (newVal) => { if (!newVal) { return } // 10.5作为临界点 隐藏行政区hover 显示设备以及管线 if (newVal >= 10.5) { if (zoomStatus.value === 'hidden') { return } // 隐藏行政区hover mapRef.value.polygonAllList.forEach((polygon: any) => { polygon.setOptions({ fillOpacity: 0.3, fillColor: 'transparent', }) polygon.on('mouseover', () => { polygon.setOptions({ fillOpacity: 0.3, fillColor: 'transparent', }) }) }) // // 绘制管线 // drawLine() // 绘制阀门,调压站等点标记 // drawMarker() zoomStatus.value = 'hidden' } else { if (zoomStatus.value === 'show') { return } // 显示行政区hover mapRef.value.polygonAllList.forEach((polygon: any) => { polygon.on('mouseover', () => { polygon.setOptions({ fillOpacity: 0.5, fillColor: '#3CA4D2', }) }) }) // 移除管线 mapRef.value.removePolyline() // 移除标记点 mapRef.value.removePolyline() zoomStatus.value = 'show' } }) // 点击图例,显示隐藏对应的点或线 const clickLegend = (data: { name: string; type: string }) => { if (legend.value.includes(data.name)) { // 隐藏 legend.value = legend.value.filter((citem: string) => citem !== data.name) if (data.type === 'line') { mapRef.value.lineAllList.forEach((line: any) => { line.hide() }) } else { mapRef.value.massMarksAllList.forEach((marker: any) => { marker.hide() }) } } else { // 显示 legend.value.push(data.name) if (data.type === 'line') { mapRef.value.lineAllList.forEach((line: any) => { console.log(line, 'line') line.show() }) } else { mapRef.value.massMarksAllList.forEach((marker: any) => { marker.show() }) } } } </script> <template> <div class="full-container"> <!-- 左侧 --> <div class="left-container"> <!-- 基本概况 --> <base-over-view /> <!-- 官网类型统计 --> <pipe-network-type style="margin-top: 20px;" /> <!-- 监测设备统计 --> <monitor-device-count style="margin-top: 20px;" /> </div> <!-- 右侧 --> <div class="right-container"> <!-- 总体报警情况 --> <all-alarm-status /> <!-- 各分公司报警统计 --> <dept-alarm-count style="margin-top: 20px;" /> <!-- 设备运行态势 --> <device-run-status style="margin-top: 20px;" /> </div> <!-- 设备信息窗体 --> <detail-info ref="detailRef" /> <!-- 地图 --> <a-map ref="mapRef" layer="dark" :zoom="9.2" :center="[116.372535, 40.213715]" @complete="drawBj" @polygonClick="polygonClick" @lineClick="lineClick" @massMarksClick="massMarksClick" /> <!-- 图例 --> <!-- <div class="amap-legend"> <div class="legend-item"> <div class="icon" :class="legend.includes('点') ? '' : 'none'"> 图标 </div> <div class="value" @click="clickLegend({ name: '点', type: 'marker' })"> 点 </div> </div> <div class="legend-item"> <div class="icon" :class="legend.includes('线') ? '' : 'none'"> 图标 </div> <div class="value" @click="clickLegend({ name: '线', type: 'line' })"> 线 </div> </div> </div> --> </div> </template> <styele lang="scss" scoped> .left-container { position: absolute; z-index: 9; top: 100px; left: 15px; background-color: rgba($color: #0B0B0F, $alpha: 0.8); } .right-container { position: absolute; z-index: 9; top: 100px; right: 15px; // background-color: #0b0b0f; background-color: rgba($color: #0B0B0F, $alpha: 0.8); } </styele> <style> .full-container { width: 100%; height: 100vh; } .none { opacity: 0; } .amap-legend { position: fixed; bottom: 10px; left: 10px; background: rgb(68 66 66 / 60%); color: #fff; padding: 10px; .legend-item { display: flex; .value { &:hover { cursor: pointer; } } } } .close { width: 150px; height: 70px; position: fixed; top: 0; right: 0; /* background-color: antiquewhite; */ &:hover { .icon { display: block; } } .icon { display: none; width: 50px; height: 50px; background: rgb(145 144 144 / 60%); border-radius: 50%; line-height: 50px; text-align: center; font-size: 18px; font-weight: 700; color: #ccc; margin: 10px auto; &:hover { cursor: pointer; } } } </style>