import * as MapStyle from './map-style' // import { // createStorageAndGoodsPopup, // createGeneralPopup, // createGudEvnPopupInfoWf, // } from './createMarkerPopup' import { ElNotification } from 'element-plus' import { iconConfig } from '@/supermap/config/iconConfig' import { resourceConfig } from '@/supermap/config/layerConfig' // import { getTopicResourceDetailInformation } from '@/api/forestFireThreeScreens/index.js' import mybus from '@/myplugins/mybus' // 引入空间计算文件 import * as turf from '@turf/turf' // import { // createDispatchResourcePopup, // createDistanceAndAreaPopup, // createGeneralPopup, // createGudEvnPopup, // createStorageAndGoodsPopup, // } from './createMarkerPopup'; // import { layerConfig } from '@/supermap/config/layerConfig'; const L = window.L || {} const SuperMap = window.SuperMap || {} const echarts = require('echarts') // const test = new dom({ // template: '', // data() { // return { // mapData: hello // }; // }, // components: { // GeneralPopup // } // }); // console.log( // '%c 👩‍❤️‍💋‍👨: test ', // 'font-size:16px;background-color:#d7d724;color:black;', // test.initDom() // ); // console.log( // '%c 🥩: test ', // 'font-size:16px;background-color:#0b1e8e;color:white;', // test.initDom().toString() // ); /** * @description: 添加html动态图层 * @param {type} point property * @return {String} html */ const blinkMarker = function (property) { // 使用js标签,便于操作,这个temDivEle的作用是将divEle通过innerHTML的方式获取为字符串 var tempDivEle = document.createElement('div') var divEle = document.createElement('div') var spanEl = document.createElement('span') var aEl = document.createElement('a') tempDivEle.append(divEle) divEle.append(spanEl) spanEl.append(aEl) // 设置上基础的样式 spanEl.classList.add('pulse-icon') aEl.classList.add('dive-icon') // 操作样式 var style = document.createElement('style') style.type = 'text/css' document.head.appendChild(style) // sheet = style.sheet; // 主体颜色 if (property) { if (property.color) { aEl.style.backgroundColor = property.color if (!property.diveColor) { aEl.style.boxShadow = '0 0 6px 2px ' + property.color } } // 标记大小 if (property.iconSize) { spanEl.style.width = property.iconSize[0] + 'px' spanEl.style.height = property.iconSize[1] + 'px' } // 发散的color if (property.diveColor) { // 发散的重度 if (property.level) { aEl.style.boxShadow = '0 0 ' + property.level * 3 + 'px ' + property.level + 'px ' + property.diveColor } else { aEl.style.boxShadow = '0 0 6px 2px ' + property.diveColor } } // 发散的重度 if (property.level) { if (property.diveColor) { aEl.style.boxShadow = '0 0 ' + property.level * 3 + 'px ' + property.level + 'px ' + property.diveColor } else if (property.color) { aEl.style.boxShadow = '0 0 ' + property.level * 3 + 'px ' + property.level + 'px ' + property.color } else { aEl.style.boxShadow = '0 0 ' + property.level * 3 + 'px ' + property.level + 'px rgba(0,0,0,0.3)' } } // 闪烁的速度 if (property.speedTime) { aEl.style.setProperty( 'animation', 'pulsate ' + property.speedTime + 's infinite' ) } } return tempDivEle.innerHTML } /** * * 多屏联动功能接口 * @param mapObj 设置全局参数对象 * @param hiMapFun 地图通用方法对象 * @constructor */ const MultiScreenFun = function (mapObj, hiMapFun) { // 初始化全局变量 const degreeToMeter = mapObj.DEGGER_TO_METER // degreeToMeter 度与米的换算单位 const layerGroup = mapObj.layerGroup // 全局图层记录数组 const featureGroup = mapObj.featureGroup // 全局图层数组 const map = mapObj.map // 全局地图对象 const drawFill = mapObj.drawFill /** * 根据传入的几何多边形,查询给定的多边形内的资源 * @param GeometryLayer { Ploygon } 面图层 * @param layerConfigList { Array} 要查询的图层数组 * @param researchFilterCallback {Function} 要执行的与后台数据库过滤的回调函数 * @param getCameraPopupInfo {Function} 获取视频弹窗信息的方法 * @param resourceStoragePopupInfo {Function} 获取仓库加物资弹窗的方法 * @param getLayerPopupInfo {Function} 获取普通弹窗的方法 * @param callBackFun {Function} 要执行的回调函数,可选 */ function _geometricQuery( geometryLayer, layerConfigList, researchFilterCallback, { getCameraPopupInfo = null, getStoragePopupInfo = null, getLayerPopupInfo = null, callBackFun = null, } = {} ) { // 定义图层配置对象 const layerConfigObjects = {} // 查询参数数据 const queryParams = [] // 构造查询数组 debugger layerConfigList.forEach((layerConfig) => { // 当前图层配置对象 const layerConfigObject = {} const layerConfigInfo = JSON.parse(layerConfig.configInfo) const layerName = layerConfig.layerCode layerConfigObject['layerName'] = layerName layerConfigObject['layerConfigInfo'] = layerConfigInfo layerConfigObject['layerConfig'] = layerConfig layerConfigObjects[layerConfigInfo.layerName] = layerConfigObject // 查看图层组里面是否存在该图层,存在删除。防止重复渲染 if (layerGroup.get(layerName)) { hiMapFun.removeLayerByLayerName(layerName) } // 构造范围查询的数据集数组 const queryObject = {} queryObject.name = layerConfigInfo.layerName queryParams.push(queryObject) }) const queryUrl = _mapConfig.config.QUERY_URL // 几何查询 const param = new SuperMap.QueryByGeometryParameters({ queryParams: queryParams, geometry: geometryLayer, }) L.supermap .queryService(queryUrl) .queryByGeometry(param, (serviceResult) => { console.log('serviceResult234324', serviceResult) // 判断查询是否成功 if (serviceResult.type === 'processCompleted') { // 遍历查询的数据集集合 debugger serviceResult.result.recordsets.forEach((recordset) => { console.log('资源进入多次', recordset) // 获取数据集名称 const datasetName = recordset.datasetName // 获取属性名称 const features = recordset.features.features if (features.length > 0) { const uuidObjects = {} const featureObjects = {} // 判断查询的是否为视频点数据 if (datasetName === 'YJPT_VideoPoints@HISENSE_himap') { features.forEach((feature) => { if ( feature.properties[ hiMapFun.convertCaseOfAttributes('CAMERA_INDEX_CODE') ] !== '' ) { // 去除无用数据 const cameraData = {} // cameraData['UUID'] = feature.properties.CAMERA_INDEX_CODE; // cameraData['SMX'] = feature.properties.SMX; // cameraData['SMY'] = feature.properties.SMY; cameraData['UUID'] = feature.properties[ hiMapFun.convertCaseOfAttributes('CAMERA_INDEX_CODE') ] cameraData['SMX'] = feature.geometry.coordinates[0] cameraData['SMY'] = feature.geometry.coordinates[1] uuidObjects[ feature.properties[ hiMapFun.convertCaseOfAttributes('CAMERA_INDEX_CODE') ] ] = cameraData featureObjects[ feature.properties[ hiMapFun.convertCaseOfAttributes('CAMERA_INDEX_CODE') ] ] = feature } }) } else { features.forEach((feature) => { if ( feature.properties[ hiMapFun.convertCaseOfAttributes('UUID') ] !== '' ) { // 去除无用数据 const resourceData = {} // resourceData['UUID'] = feature.properties.UUID; // resourceData['SMX'] = feature.properties.SMX; // resourceData['SMY'] = feature.properties.SMY; resourceData['UUID'] = feature.properties[ hiMapFun.convertCaseOfAttributes('UUID') ] resourceData['SMX'] = feature.geometry.coordinates[0] resourceData['SMY'] = feature.geometry.coordinates[1] uuidObjects[ feature.properties[ hiMapFun.convertCaseOfAttributes('UUID') ] ] = resourceData featureObjects[ feature.properties[ hiMapFun.convertCaseOfAttributes('UUID') ] ] = feature } }) } // 获取当前图层的配置文件 const layerConfigObject = layerConfigObjects[datasetName] // 获取当前地图数据点的UUID,加上关键字进行过滤,得到过滤后的集合 // researchFilterCallback(uuidObjects, layerConfigObject.layerConfig).then((response) => { // const queryResults = response.data; // if (queryResults.length > 0) { // 根据返回的数据过滤超图库查询的点位数据 // const filterFeatures = []; // 遍历找出过滤后的超图库数据 // queryResults.forEach(queryResult => { // if (datasetName === 'YJPT_VideoPoints@HISENSE_himap') { // filterFeatures.push(featureObjects[queryResult.indexCode]); // } else { // filterFeatures.push(featureObjects[queryResult.uuid]); // } // }); // // 构造传给callBackFun方法参数对象 // 将符合要求的点位信息转成GeoJson,存入地图对象上图 console.log('上图features应该是个数组', features) const affectResource = L.geoJSON(features, { onEachFeature: (feature, layer) => { layer.setIcon( MapStyle.featureIcon(layerConfigObject.layerConfigInfo) ) layer.configInfo = layerConfigObject.layerConfigInfo // 给查询出的每一个点添加点击弹窗事件 if ( layerConfigObject.layerName === 'multi_screen_camera' && getCameraPopupInfo != null ) { // 当查询的为视频监控点时(单独处理) layer.on('click', function (e) { // const indexCode = e.sourceTarget.feature.properties.CAMERA_INDEX_CODE; const indexCode = e.sourceTarget.feature.properties[ hiMapFun.convertCaseOfAttributes('CAMERA_INDEX_CODE') ] const layerConfigInfo = e.sourceTarget.configInfo const location = [e.latlng.lat, e.latlng.lng] const latlng = L.latLng(location) getCameraPopupInfo(indexCode, layerConfigInfo).then( (response) => { response.allMapObject = { mapObj: mapObj, hiMapFun: hiMapFun, } const elementHtml = // hiMapFun.createGeneralPopupInfo(response) L.popup({ className: 'multi-general-popup-style' }) .setLatLng(latlng) // .setContent(elementHtml) .openOn(map) } ) }) } else { // 当查询的不是视频监控点时 layer.on('click', function (e) { // const uuid = e.sourceTarget.feature.properties.UUID; const uuid = e.sourceTarget.feature.properties[ hiMapFun.convertCaseOfAttributes('UUID') ] const layerConfigInfo = e.sourceTarget.configInfo const location = [e.latlng.lat, e.latlng.lng] const latlng = L.latLng(location) if ( layerConfigObject.layerName === 'multi_screen_storage' && getStoragePopupInfo != null ) { // 仓库+物资信息的弹窗展示方式 getStoragePopupInfo(uuid, layerConfigInfo).then( (response) => { response.entityData.goodsDetail.push( { GOODSNAME: '哈哈哈哈', TOTALQUANTITY: 2, UNIT: '个', }, { GOODSNAME: '哈哈哈哈', TOTALQUANTITY: 2, UNIT: '个', }, { GOODSNAME: '哈哈哈哈', TOTALQUANTITY: 2, UNIT: '个', }, { GOODSNAME: '哈哈哈哈', TOTALQUANTITY: 2, UNIT: '个', } ) response.allMapObject = { mapObj: mapObj, hiMapFun: hiMapFun, } const elementHtml = hiMapFun.createStorageAndGoodsPopupInfo(response) L.popup({ className: 'multi-general-popup-style' }) .setLatLng(latlng) .setContent(elementHtml) .openOn(map) } ) } else if (getLayerPopupInfo) { // 通用资源弹窗展示方式 debugger getLayerPopupInfo( uuid, layerConfigInfo.resourceType, layerConfigInfo ).then((response) => { if (response.data) { response.allMapObject = { mapObj: mapObj, hiMapFun: hiMapFun, } const elementHtml = // hiMapFun.createGeneralPopup(response) L.popup({ className: 'multi-general-popup-style' }) .setLatLng(latlng) // .setContent(elementHtml) .openOn(map) } else { ElNotification.warning({ title: '提示', message: '暂未查询到相关资源详情', position: 'bottom-right', type: 'error', duration: 1000, }) } }) } }) } }, }) hiMapFun.removeLayerByLayerName(layerConfigObject.layerName) featureGroup.addLayer(affectResource) layerGroup.set(layerConfigObject.layerName, affectResource) // 构造输出函数 if (callBackFun) { // 构造传给callBackFun方法参数对象 const paramObject = {} paramObject['professionalData'] = queryResults paramObject['featurePoints'] = filterFeatures paramObject['layerConfigObject'] = layerConfigObject paramObject['layers'] = affectResource callBackFun(paramObject) } // } // }); } }) } else { ElNotification.warning({ title: '提示', message: '几何查询错误,请重试', position: 'bottom-right', type: 'error', duration: 1000, }) } }) } /** * 根据传入的几何多边形,查询给定的多边形内的资源 * @param GeometryLayer { Ploygon } 面图层 * @param layerConfigList { Array} 要查询的图层数组 * @param researchFilterCallback {Function} 要执行的与后台数据库过滤的回调函数 * @param getCameraPopupInfo {Function} 获取视频弹窗信息的方法 * @param resourceStoragePopupInfo {Function} 获取仓库加物资弹窗的方法 * @param getLayerPopupInfo {Function} 获取普通弹窗的方法 * @param callBackFun {Function} 要执行的回调函数,可选 */ function _newGeometricQuery( geometryLayer, layerConfigList, researchFilterCallback, { getCameraPopupInfo = null, getStoragePopupInfo = null, getLayerPopupInfo = null, callBackFun = null, } = {} ) { // 定义图层配置对象 const layerConfigObjects = {} // 查询参数数据 const queryParams = [] // 构造查询数组 debugger layerConfigList.forEach((layer) => { const layerName = layer.layerName const queryObj = {} queryObj.name = layerName queryParams.push(queryObj) layerConfigObjects[layerName] = layer }) // 清除圈选结果图层 if (layerGroup.get('circleResult')) { hiMapFun.removeLayerByLayerName('circleResult') } console.log('查看构建是否正确', queryParams, layerConfigObjects) const queryUrl = _mapConfig.config.QUERY_URL // 几何查询 const param = new SuperMap.QueryByGeometryParameters({ queryParams: queryParams, geometry: geometryLayer, }) L.supermap .queryService(queryUrl) .queryByGeometry(param, (serviceResult) => { console.log('serviceResult234324', serviceResult) // 判断查询是否成功 if (serviceResult.type === 'processCompleted') { debugger // 构建查询出来的总的集合 const result = serviceResult.result.recordsets let allFeatures = [] const uuidList = [] const resourceList = [] result.map((item) => { const feature = item.features.features feature.map((f) => { f.layerName = item.datasetName f.iconType = item.datasetName + f.properties.resource_type return f }) console.log(feature) allFeatures = allFeatures.concat(feature) }) console.log('构造完毕的集合', allFeatures) // 资源上图 const layers = [] allFeatures.map((fe) => { const iconUrl = iconConfig[fe.iconType] const icon = MapStyle.featureIconByURL(iconUrl) const point = { lat: fe.geometry.coordinates[1], lng: fe.geometry.coordinates[0], } const param = { resourceType: resourceConfig[fe.layerName], uuid: fe.properties.uuid, layerName: fe.layerName, } uuidList.push(fe.properties.uuid) resourceList.push({ // 用于森火三屏圈选 layerName: fe.layerName, uuid: fe.properties.uuid, }) const marker = L.marker(point, { icon, param }) // 资源点击事件 marker.on('click', function (e) { console.log('eeeeeeeeeeee', e) // const uuid = e.sourceTarget.feature.properties.UUID; const uuid = e.sourceTarget.options.param.uuid const resourceType = e.sourceTarget.options.param.resourceType const location = [e.latlng.lat, e.latlng.lng] const latlng = L.latLng(location) debugger mybus.$emit('trsSupermapData', { uuid, resType: resourceType }) // // 获取资源详情, 调用外部函数 // getTopicResourceDetailInformation({uuid, resType: resourceType}).then((response) => { // if (response.data) { // // 弹窗信息 // } else { // ElNotification.warning({ // title: '提示', // message: '暂未查询到相关资源详情', // position: 'bottom-right', // type: 'error', // duration: 1000 // }); // } // }); }) layers.push(marker) }) console.log('添加资源有错误', layers) // 数据传递 if (callBackFun) { callBackFun(layers, uuidList, resourceList).then((res) => { debugger console.log('收到过滤的图层', res) hiMapFun.removeLayerByLayerName('circleResult') const markerGroup = L.layerGroup(res) featureGroup.addLayer(markerGroup) layerGroup.set('circleResult', markerGroup) return }) } const markerGroup = L.layerGroup(layers) featureGroup.addLayer(markerGroup) layerGroup.set('circleResult', markerGroup) } }) } /** * 根据Circle插件画一个Ploygen圆用于范围查询 * @param circleLayer {Object} * @private */ function _createCircleLayer(circleLayer) { // 画圆 // 1度=100407米,圆的半径为度 const radius = circleLayer._mRadius / degreeToMeter // 点集 const parts = [] // 计算圆的边缘所有点 for (let i = 0; i < 360; i++) { const radians = ((i + 1) * Math.PI) / 180 parts[i] = [ Math.cos(radians) * radius + parseFloat(circleLayer._latlng.lat), Math.sin(radians) * radius + parseFloat(circleLayer._latlng.lng), ] } return L.polygon(parts, drawFill) } /** * 根据自定义事件的icon,加载图层 * @param layerName * @param features * @param layerConfigInfo * @param handelFlag * @param getGudEvnPopupinfo * @private */ function _addEventFeaturesByDivIcon( layerName, features, layerConfigInfo, { handelFlag = true, getGudEvnPopupinfo = null } = {} ) { const layers = [] features.forEach((feature, index) => { const contentHTML = `
0${index + 1}
` let myIcon = '' if (handelFlag) { myIcon = L.divIcon({ iconSize: [100, 70], html: contentHTML, className: 'event-handle-div-icon', }) } else { myIcon = L.divIcon({ iconSize: [122, 99], html: contentHTML, className: 'event-unhandle-div-icon', }) } // 创建marker图层,绑定要素 const markerLayer = L.marker([feature.coordinateX, feature.coordinateY], { icon: myIcon, attribution: feature, }) markerLayer.layerConfigInfo = layerConfigInfo markerLayer.handelType = 'handel' markerLayer.on('click', function (e) { if (getGudEvnPopupinfo) { const layerConfigInfo = e.sourceTarget.layerConfigInfo const location = [e.latlng.lat, e.latlng.lng] const latlng = L.latLng(location) const data = e.sourceTarget.options.attribution getGudEvnPopupinfo(data.gudEvnInfoId, layerConfigInfo).then( (response) => { response.allMapObject = { mapObj: mapObj, hiMapFun: hiMapFun, } // const elementHtml = hiMapFun.createGudEvnPopupInfo(response); L.popup({ className: 'multi-event-popup-style' }) .setLatLng(latlng) .openOn(map) } ) } }) layers.push(markerLayer) }) const markerGroup = L.layerGroup(layers) featureGroup.addLayer(markerGroup) layerGroup.set(layerName, markerGroup) } /** * 单屏事件扎点 * @param layerName * @param features * @param layerConfigInfo * @param handelFlag * @param getGudEvnPopupinfo * @private */ function _addSingleEvent( layerName, features, layerConfigInfo, { handelFlag = false, getGudEvnPopupinfo = null } = {} ) { const layers = [] features.forEach((feature, index) => { const html = blinkMarker({ iconSize: [25, 15], level: '6', speedTime: 1, color: 'rgba(255,85,0,0.3)', diveColor: '#ffc2c5', }) const pointIcon = '/src/supermap/image/multi_handel_event_orange.png' const contentHTML = `
0${ index + 1 }
${html}
` let myIcon = '' if (handelFlag) { myIcon = L.divIcon({ iconSize: [100, 70], html: contentHTML, className: 'event-handle-div-icon', }) } else { myIcon = L.divIcon({ iconSize: [122, 99], html: contentHTML, className: 'event-unhandle-div-icon', }) } // 创建marker图层,绑定要素 const markerLayer = L.marker([feature.coordinateX, feature.coordinateY], { icon: myIcon, attribution: feature, }) markerLayer.layerConfigInfo = layerConfigInfo markerLayer.handelType = 'singleEvent' markerLayer.on('click', function (e) { if (getGudEvnPopupinfo) { const layerConfigInfo = e.sourceTarget.layerConfigInfo const location = [e.latlng.lat, e.latlng.lng] const latlng = L.latLng(location) const data = e.sourceTarget.options.attribution getGudEvnPopupinfo(data.gudEvnInfoId, layerConfigInfo).then( (response) => { response.allMapObject = { mapObj: mapObj, hiMapFun: hiMapFun, } // const elementHtml = hiMapFun.createGudEvnPopupInfo(response); L.popup({ className: 'multi-event-popup-style' }) .setLatLng(latlng) .openOn(map) } ) } }) layers.push(markerLayer) }) const markerGroup = L.layerGroup(layers) featureGroup.addLayer(markerGroup) layerGroup.set(layerName, markerGroup) } /** * 根据自定义事件的icon,加载未处置事件图层 * @param layerName * @param features * @param layerConfigInfo * @param handelFlag * @param getGudEvnPopupinfo * @private */ function _addUnHandleEventFeaturesByDivIcon( layerName, features, layerConfigInfo, { numMarker = 0, getGudEvnPopupinfo = null } = {} ) { const layers = [] features.forEach((feature, index) => { // 根据不同的事件等级,添加不同的图标 console.log('feature.eventGrade', feature) let html = blinkMarker({ iconSize: [25, 15], level: '6', speedTime: 1 }) let pointIcon = '/src/supermap/image/multi_handel_event_blue.png' if (feature.redGrade) { html = blinkMarker({ iconSize: [25, 15], level: '6', speedTime: 1, color: 'rgba(198,1,0,0.3)', diveColor: '#ffc2c5', }) pointIcon = '/src/supermap/image/multi_handel_event_red.png' } if (feature.orangeGrade) { html = blinkMarker({ iconSize: [25, 15], level: '6', speedTime: 1, color: 'rgba(255,85,0,0.3)', diveColor: '#ffc2c5', }) pointIcon = '/src/supermap/image/multi_handel_event_orange.png' } if (feature.yellowGrade) { html = blinkMarker({ iconSize: [25, 15], level: '6', speedTime: 1, color: 'rgba(198,170,20,0.3)', diveColor: '#fdffc2', }) pointIcon = '/src/supermap/image/multi_handel_event_yellow.png' } if (feature.blueGrade) { html = blinkMarker({ iconSize: [25, 15], level: '6', speedTime: 1, color: 'rgba(40,146,198,0.3)', diveColor: '#c2eaff', }) pointIcon = '/src/supermap/image/multi_handel_event_blue.png' } // 因为进入非常态化很多属性都丢了,所以加这个判断 if (feature.eventGrade) { switch (feature.eventGrade) { case '3': html = blinkMarker({ iconSize: [25, 15], level: '6', speedTime: 1, color: 'rgba(198,1,0,0.3)', diveColor: '#ffc2c5', }) pointIcon = '/src/supermap/image/multi_handel_event_red.png' break case '2': html = blinkMarker({ iconSize: [25, 15], level: '6', speedTime: 1, color: 'rgba(255,85,0,0.3)', diveColor: '#ffc2c5', }) pointIcon = '/src/supermap/image/multi_handel_event_orange.png' break case '1': html = blinkMarker({ iconSize: [25, 15], level: '6', speedTime: 1, color: 'rgba(198,170,20,0.3)', diveColor: '#fdffc2', }) pointIcon = '/src/supermap/image/multi_handel_event_yellow.png' break case '0': html = blinkMarker({ iconSize: [25, 15], level: '6', speedTime: 1, color: 'rgba(40,146,198,0.3)', diveColor: '#c2eaff', }) pointIcon = '/src/supermap/image/multi_handel_event_blue.png' break default: html = blinkMarker({ iconSize: [25, 15], level: '6', speedTime: 1, color: 'rgba(40,146,198,0.3)', diveColor: '#c2eaff', }) pointIcon = '/src/supermap/image/multi_handel_event_blue.png' break } } const contentHTML = `
${html}
` const myIcon = L.divIcon({ iconSize: [122, 99], html: contentHTML, className: 'event-handle-div-icon', }) // 创建marker图层,绑定要素 const markerLayer = L.marker([feature.coordinateX, feature.coordinateY], { icon: myIcon, attribution: feature, }) markerLayer.layerConfigInfo = layerConfigInfo markerLayer.handelType = 'unHandel' markerLayer.on('click', function (e) { if (getGudEvnPopupinfo) { const layerConfigInfo = e.sourceTarget.layerConfigInfo const location = [e.latlng.lat, e.latlng.lng] const latlng = L.latLng(location) const data = e.sourceTarget.options.attribution getGudEvnPopupinfo(data.gudEvnInfoId, layerConfigInfo).then( (response) => { response.allMapObject = { mapObj: mapObj, hiMapFun: hiMapFun, } // const elementHtml = hiMapFun.createGudEvnPopupInfo(response); // 防火专题事件点报错修改 L.popup({ className: 'multi-event-popup-style' }) .setLatLng(latlng) .openOn(map) } ) } }) layers.push(markerLayer) }) const markerGroup = L.layerGroup(layers) featureGroup.addLayer(markerGroup) layerGroup.set(layerName, markerGroup) } /** * 多屏指挥调度中添加事件上图 * @param layerName * @param features * @param layerConfigInfo * @private */ function _addEventFeaturesOnMap( layerName, features, layerConfigInfo, { getGudEvnPopupinfo = null } = {} ) { const layers = [] features.forEach((feature) => { // 创建marker图层,绑定要素 静态图层 const markerLayer = L.marker([feature.coordinateX, feature.coordinateY], { icon: MapStyle.featureIcon(layerConfigInfo), attribution: feature, }) markerLayer.layerConfigInfo = layerConfigInfo // 图标点击弹窗事件 markerLayer.on('click', (e) => { const layerConfigInfo = e.sourceTarget.layerConfigInfo const enity = e.sourceTarget.options.attribution const location = [e.latlng.lat, e.latlng.lng] const latlng = L.latLng(location) getGudEvnPopupinfo(enity.gudEvnInfoId, layerConfigInfo).then( (response) => { response.allMapObject = { mapObj: mapObj, hiMapFun: hiMapFun, } // const elementHtml = hiMapFun.createGudEvnPopupInfo(response); L.popup({ className: 'multi-event-popup-style' }) .setLatLng(latlng) .openOn(map) } ) }) }) const markerGroup = L.layerGroup(layers) featureGroup.addLayer(markerGroup) layerGroup.set(layerName, markerGroup) } /** * 显示单兵轨迹 * @param layerName * @param data * @private */ function _showSoliderTrackOnMap(layerName, data) { const trackPointArray = [] data.forEach((item) => { // let point = [item.longitude,item.latitude]; const point = [item.latitude, item.longitude] trackPointArray.push(point) }) const soliderTrackLine = L.polyline(trackPointArray, { color: 'red' }) featureGroup.addLayer(soliderTrackLine) layerGroup.set(layerName, soliderTrackLine) } /** * @param markerLayerName 单兵点图层名字 * @param trackLayerName 点兵点的历史轨迹图层名 * @param data 单兵点的数据 * @param layerConfigInfo 单兵点的图层配置信息 */ function _addSoliderMarkerOnMap( markerLayerName, trackLayerName, data, layerConfigInfo ) { if (data.length !== 0) { const lastPoint = data[data.length - 1] const markerLayer = L.marker([lastPoint.latitude, lastPoint.longitude], { icon: MapStyle.featureIcon(layerConfigInfo), }) markerLayer.data = data markerLayer.layerConfigInfo = layerConfigInfo markerLayer.on('click', function (e) { const layerConfigInfo = e.sourceTarget.layerConfigInfo const layerData = e.sourceTarget.data _showSoliderTrackOnMap(trackLayerName, data) }) featureGroup.addLayer(markerLayer) layerGroup.set(markerLayerName, markerLayer) } else { console.log('单兵没有经纬度信息!') } } /** * 实时路况数据展示 * @param layerName {String} 配置图层名 * @param configInfo {Object} 图层配置对象 * @param data {Array} 后台返回的路况数组对象 * @param getLayerPopupInfo {Function} 获取弹窗数据的方法 * todo 后期根据具体数据进行修改 * @param className {String} className字符串 * */ function _showTrafficStatusInfo( layerName, configInfo, data, { getLayerPopupInfo = null, className = '' } = {} ) { // 拿到坐标绘制路网 const featureArray = [] for (let rs = 0; rs < data.length; rs++) { let styleLine = {} // let roadStatus = ''; // 记录道路拥堵状态描述 switch (data[rs].grade) { case '3': styleLine = { strokeColor: 'red', strokeWidth: 4, strokeLinecap: 'round', strokeDashstyle: 'solid', } // roadStatus = '拥堵'; break case '1': styleLine = { strokeColor: 'green', strokeWidth: 3, strokeLinecap: 'round', strokeDashstyle: 'solid', } // roadStatus = '畅行'; break case '2': styleLine = { strokeColor: 'yellow', strokeWidth: 3, strokeLinecap: 'round', strokeDashstyle: 'solid', } // roadStatus = '缓行'; break } // const roadLine = {}; const roadPoints = [] // const pointNum = 0; if (data[rs].mCoord !== '' && data[rs].mCoord != null) { const nodeArr = data[rs].mCoord.split(',') const arrLength = nodeArr.length / 2 for (var i = 0; i < arrLength; i++) { var coord_x = nodeArr[2 * i] var coord_y = nodeArr[2 * i + 1] // 描绘所有点 const point = [coord_y, coord_x] roadPoints[i] = point } } // todo const sourceGeometry = L.polyline(roadPoints, { color: styleLine.strokeColor, }) if (getLayerPopupInfo) { sourceGeometry.title = layerName sourceGeometry.roadId = data[rs].roadId sourceGeometry.roadName = data[rs].roadName sourceGeometry.configInfo = configInfo sourceGeometry.on('click', function (e) { const location = [e.latlng.lat, e.latlng.lng] const latlng = L.latLng(location) const roadId = e.sourceTarget.roadId const configInfo = e.sourceTarget.configInfo // const contentHtml = trafficStatusCallback(roadId, configInfo); getLayerPopupInfo(roadId, configInfo).then((response) => { response.allMapObject = { mapObj: mapObj, hiMapFun: hiMapFun, } // const elementHtml = hiMapFun.createGeneralPopupInfo(response) L.popup({ className: className }) .setLatLng(latlng) // .setContent(elementHtml) .openOn(map) }) }) } featureArray.push(sourceGeometry) } const markerGroupArray = L.layerGroup(featureArray) featureGroup.addLayer(markerGroupArray) layerGroup.set(layerName, markerGroupArray) } /** * 水文水务中加载水库专用方法 * @param layerName {String} 图层名字 * @param features {Array} 地图要素数组 * @param layerConfigInfo {Object} 图层配置对象 * @param callBackInClick {function} 点击图标时执行的函数 * @param selectWaterAffairsSmallReservoirsInfoByName * @param waterConditionBureau */ function _addReservoirStationOnMap( layerName, features, layerConfigInfo, callBackInClick, { selectWaterAffairsSmallReservoirsInfoByName = null, waterConditionBureau = 'water_affairs_bureau', getReservoirInfoByReservoirInfoId = null, getWaterAffairsReservoirInfoByReservoirInfoId = null, } = {} ) { const layers = [] features.forEach((feature) => { if (feature.data.label === '1') { // 小水库 layerConfigInfo.img = 'reservoir_small.png' } else if (feature.data.label === '3') { // 中型水库 layerConfigInfo.img = 'reservoir_middle.png' } else if (feature.data.label === '4') { layerConfigInfo.img = 'reservoir_big.png' } const icon = MapStyle.featureIcon(layerConfigInfo) // 创建marker图层,绑定要素 const markerLayer = L.marker([feature.data.lat, feature.data.lon], { icon: icon, attribution: feature.data, }) markerLayer.layerConfigInfo = layerConfigInfo markerLayer.on('click', function (e) { const layerConfigInfo = e.sourceTarget.layerConfigInfo const location = [e.latlng.lat, e.latlng.lng] const latlng = L.latLng(location) const data = e.sourceTarget.options.attribution // 当为水务数据且为小型水库时,点击查看的是数据详细信息 if ( layerConfigInfo.img === 'reservoir_small.png' && waterConditionBureau === 'water_affairs_bureau' ) { selectWaterAffairsSmallReservoirsInfoByName( e.sourceTarget.options.attribution.reservoirInfoName.trim(), layerConfigInfo ).then((response) => { response.allMapObject = { mapObj: mapObj, hiMapFun: hiMapFun, } const elementHtml = hiMapFun.createSmallReservoirPopup(response) L.popup({ className: 'multi-small-reservoir-popup-style' }) .setLatLng(latlng) .setContent(elementHtml) .openOn(map) }) } else { // 自定函数,调用的是获取echars callBackInClick(layerConfigInfo, latlng, data, e, { getReservoirInfoByReservoirInfoId: getReservoirInfoByReservoirInfoId, getWaterAffairsReservoirInfoByReservoirInfoId: getWaterAffairsReservoirInfoByReservoirInfoId, }) } }) layers.push(markerLayer) }) const markerGroup = L.layerGroup(layers) featureGroup.addLayer(markerGroup) layerGroup.set(layerName, markerGroup) } /** * 加载水库监测点对应的Echars * **/ function _loadReservoirStationEcharsByReservoirInfoId( layerConfigInfo, latlng, data, e, { getReservoirInfoByReservoirInfoId = null } = {} ) { if (getReservoirInfoByReservoirInfoId) { getReservoirInfoByReservoirInfoId(data.reservoirInfoId).then( (response) => { const reservoirList = response.data if ( typeof reservoirList === 'undefined' || reservoirList.length === 0 ) { alert('未查询到该水库的详细信息!') } else { const maxWaterLevel = reservoirList.reduce((item1, item2) => { return item1 > item2.waterLevel ? item1 : item2.waterLevel }, 0) // 设置Echars图标信息 const location = [latlng.lat, latlng.lng] const option = { grid: { right: '15%', bottom: '8%', top: '20%', }, color: ['#fff21f', '00b4ff'], legend: { right: '1%', top: '1.5%', data: [ { name: '水位', }, { name: '库容', }, ], textStyle: { color: '#00fcff', fontSize: 16, }, }, tooltip: { trigger: 'axis', backgroundColor: 'rgba(6, 25, 69, 0.8)', borderColor: 'rgba(0, 180, 255, 0.8);', borderWidth: 1, axisPointer: { type: 'cross', }, }, dataset: { // 这里指定了维度名的顺序,从而可以利用默认的维度到坐标轴的映射。 // 如果不指定 dimensions,也可以通过指定 series.encode 完成映射。 dimensions: ['updatedDate', 'waterLevel', 'waterStorage'], source: reservoirList, }, xAxis: { type: 'category', axisLabel: { color: '#00fcff', fontSize: 16, }, axisLine: { lineStyle: { color: '#117ce0', }, }, axisTick: { show: false, }, splitArea: { show: true, areaStyle: { color: ['rgba(0,0,0,0.2)', 'rgba(0,0,0,0)'], }, }, }, // yAxis: {}, yAxis: [ { type: 'value', name: '水位', nameTextStyle: { color: '#00fcff', fontSize: 16, }, min: 0, max: Math.floor(maxWaterLevel + 20), // interval: 20, splitLine: { lineStyle: { type: 'dotted', color: '#117ce0', }, }, axisLabel: { formatter: '{value} 米', color: '#00fcff', fontSize: 16, }, axisLine: { lineStyle: { color: '#117ce0', }, }, axisTick: { show: false, }, }, { type: 'value', name: '库容', nameTextStyle: { color: '#00fcff', fontSize: 16, }, min: function (value) { return value.min - 10 }, max: function (value) { return value.max + 10 }, // interval: 200, splitLine: { lineStyle: { type: 'dotted', color: '#117ce0', }, }, axisLabel: { formatter: '{value} 万方', color: '#00fcff', fontSize: 16, }, axisLine: { lineStyle: { color: '#117ce0', }, }, axisTick: { show: false, }, scale: true, }, ], series: [ { name: '水位', type: 'line', symbol: 'image://../mode/static/img/yellow-spot.png', symbolSize: 22, lineStyle: { color: '#fff21f', }, }, { name: '库容', type: 'bar', barWidth: '20', yAxisIndex: 1, itemStyle: { color: '#00b4ff', }, }, ], } const div = L.DomUtil.create('div') const chart = echarts.init(div, '', { width: 720, height: 400, }) chart.setOption(option) L.popup({ maxWidth: 800 }) .setLatLng(location) .setContent(function () { const titleDiv = document.createElement('div') const spanDiv = document.createElement('div') spanDiv.style.cssText = 'width: 100%;height: 30px;background: linear-gradient(left, rgba(0, 156, 255, 0.8), rgba(0, 0, 0, 0));' + 'background: -ms-linear-gradient(left, rgba(0, 156, 255, 0.8), rgba(0, 0, 0, 0));' + 'background: -webkit-linear-gradient(left, rgba(0, 156, 255, 0.8), rgba(0, 0, 0, 0));' + 'background: -moz-linear-gradient(left, rgba(0, 156, 255, 0.8), rgba(0, 0, 0, 0));' + 'padding-top: 7px;padding-left: 10px;' const titleContent = document.createTextNode( e.sourceTarget.options.attribution.reservoirInfoName ) spanDiv.appendChild(titleContent) titleDiv.appendChild(spanDiv) chart.setOption({ title: [ // { // text: e.sourceTarget.options.attribution.name, // }, { text: '当前水位:' + reservoirList[reservoirList.length - 1].waterLevel + '米', x: '1%', y: '1.5%', textStyle: { color: '#fff', fontSize: 16, fontWeight: 'normal', }, }, { text: '当前来水量:' + reservoirList[reservoirList.length - 1].waterInflow + '万方', x: '25%', y: '1.5%', textStyle: { color: '#fff', fontSize: 16, fontWeight: 'normal', }, }, ], }) titleDiv.appendChild(chart.getDom()) // return chart.getDom(); return titleDiv }) .openOn(map) } } ) } } /** * 加载水务局水库监测点对应的Echars * **/ function _loadWaterAffairsReservoirStationEcharsByReservoirInfoId( layerConfigInfo, latlng, data, e, { getWaterAffairsReservoirInfoByReservoirInfoId = null } = {} ) { getWaterAffairsReservoirInfoByReservoirInfoId(data.reservoirInfoId).then( (response) => { const reservoirList = response.data if ( typeof reservoirList === 'undefined' || reservoirList.length === 0 ) { alert('未查询到该水库的详细信息!') } else { // 设置Echars图标信息 const location = [latlng.lat, latlng.lng] const option = { grid: { right: '15%', bottom: '8%', top: '20%', }, color: ['#fff21f', '00b4ff'], legend: { right: '1%', top: '1.5%', data: [ { name: '水位', }, { name: '库容', }, ], textStyle: { color: '#00fcff', fontSize: 16, }, }, tooltip: { trigger: 'axis', backgroundColor: 'rgba(6, 25, 69, 0.8)', borderColor: 'rgba(0, 180, 255, 0.8);', borderWidth: 1, axisPointer: { type: 'cross', }, }, dataset: { // 这里指定了维度名的顺序,从而可以利用默认的维度到坐标轴的映射。 // 如果不指定 dimensions,也可以通过指定 series.encode 完成映射。 dimensions: ['updatedDate', 'waterLevel', 'waterStorage'], source: reservoirList, }, xAxis: { type: 'category', axisLabel: { color: '#00fcff', fontSize: 16, }, axisLine: { lineStyle: { color: '#117ce0', }, }, axisTick: { show: false, }, splitArea: { show: true, areaStyle: { color: ['rgba(0,0,0,0.2)', 'rgba(0,0,0,0)'], }, }, }, // yAxis: {}, yAxis: [ { type: 'value', name: '水位', nameTextStyle: { color: '#00fcff', fontSize: 16, }, min: 0, max: 100, interval: 20, splitLine: { lineStyle: { type: 'dotted', color: '#117ce0', }, }, axisLabel: { formatter: '{value} 米', color: '#00fcff', fontSize: 16, }, axisLine: { lineStyle: { color: '#117ce0', }, }, axisTick: { show: false, }, }, { type: 'value', name: '库容', nameTextStyle: { color: '#00fcff', fontSize: 16, }, min: function (value) { return value.min - 10 }, max: function (value) { return value.max + 10 }, // interval: 200, splitLine: { lineStyle: { type: 'dotted', color: '#117ce0', }, }, axisLabel: { formatter: '{value} 万方', color: '#00fcff', fontSize: 16, }, axisLine: { lineStyle: { color: '#117ce0', }, }, axisTick: { show: false, }, scale: true, }, ], series: [ { name: '水位', type: 'line', symbol: 'image://../mode/static/img/yellow-spot.png', symbolSize: 22, lineStyle: { color: '#fff21f', }, }, { name: '库容', type: 'bar', barWidth: '20', yAxisIndex: 1, itemStyle: { color: '#00b4ff', }, }, ], } const div = L.DomUtil.create('div') const chart = echarts.init(div, '', { width: 720, height: 400, }) chart.setOption(option) L.popup({ maxWidth: 800 }) .setLatLng(location) .setContent(function () { const titleDiv = document.createElement('div') const spanDiv = document.createElement('div') spanDiv.style.cssText = 'width: 100%;height: 30px;background: linear-gradient(left, rgba(0, 156, 255, 0.8), rgba(0, 0, 0, 0));' + 'background: -ms-linear-gradient(left, rgba(0, 156, 255, 0.8), rgba(0, 0, 0, 0));' + 'background: -webkit-linear-gradient(left, rgba(0, 156, 255, 0.8), rgba(0, 0, 0, 0));' + 'background: -moz-linear-gradient(left, rgba(0, 156, 255, 0.8), rgba(0, 0, 0, 0));' + 'padding-top: 7px;padding-left: 10px;' const titleContent = document.createTextNode( e.sourceTarget.options.attribution.reservoirInfoName ) spanDiv.appendChild(titleContent) titleDiv.appendChild(spanDiv) chart.setOption({ title: [ // { // text: e.sourceTarget.options.attribution.name, // }, { text: '当前水位:' + reservoirList[reservoirList.length - 1].waterLevel + '米', x: '1%', y: '1.5%', textStyle: { color: '#fff', fontSize: 16, fontWeight: 'normal', }, }, { text: '当前来水量:' + reservoirList[reservoirList.length - 1].waterInflow + '万方', x: '25%', y: '1.5%', textStyle: { color: '#fff', fontSize: 16, fontWeight: 'normal', }, }, ], }) titleDiv.appendChild(chart.getDom()) // return chart.getDom(); return titleDiv }) .openOn(map) } } ) } /** * 森火三屏版本周边分析 * @param geometry {obj} 地理信息 包含lng(经度),lat(纬度),radius(范围) * @param dataList {Array} 需要筛选的所有业务库资源列表 */ function _circleQuery( geometry = { lng: '', lat: '', radius: 12, units: 'kilometers' }, dataList = [] ) { // 清除圈 hiMapFun.removeLayerByLayerName('circleMarker') // 圈一直居中 const latLng = { lat: geometry.lat, lng: geometry.lng, } let zoom = 14 // 根据半径 自动缩放地图 if (geometry.radius <= 1) { zoom = 14 } else if (geometry.radius <= 2) { zoom = 13 } else if (geometry.radius <= 5) { zoom = 12 } else if (geometry.radius <= 10) { zoom = 11 } else if (geometry.radius <= 20) { zoom = 10 } else if (geometry.radius <= 25) { zoom = 9 } else if (geometry.radius <= 50) { zoom = 8 } else { zoom = 7 } const duration = 0.15 map.flyTo(latLng, zoom || 15, { duration: duration || 0.15 }) // 三等分画圈、添加半径标识 let circleMarker = '' let newPoint = '' let popup = '' const color = ['#ff6724', '#ffef21', '#41fafc'] const className = ['orange-rect', 'yellow-rect', 'blue-rect'] for (let index = 1; index < 4; index++) { // const element = array[index]; const radius = ((geometry.radius * 1000) / 3) * index circleMarker = L.circle([geometry.lat, geometry.lng], { radius: radius, color: color[index - 1], fill: index === 3, fillColor: '#1D4076', weight: 1.4, }) mapObj.featureGroup.addLayer(circleMarker) mapObj.layerGroup.set('circleMarker', circleMarker) // 设置图层名称 console.log(index) // 计算正下方的经纬度 const point = turf.point([geometry.lng, geometry.lat]) const bearing = 180 const options = { units: 'kilometers' } console.log('radius', radius) const destination = turf.destination( point, radius / 1000, bearing, options ) newPoint = { lat: destination.geometry.coordinates[1], lng: destination.geometry.coordinates[0], } const number = (radius / 1000).toFixed(2) popup = L.popup({ offset: L.point(0, 50) }) .setLatLng(newPoint) .setContent( '

' + number + 'km

' ) mapObj.featureGroup.addLayer(popup) mapObj.layerGroup.set('circleMarker', popup) // 设置图层名称 console.log('destination', destination) } // 创建100边形近似圆 const circle = turf.circle([geometry.lng, geometry.lat], geometry.radius, { steps: 100, units: geometry.units, }) console.log('turfCircle', circle) // 包含圆周点位信息 // 筛选出在圆中的所有资源 const result = dataList.filter((item) => { return turf.booleanPointInPolygon( turf.point([item.longitude, item.latitude]), circle ) }) return result } return { geometricQuery: _geometricQuery, newGeometricQuery: _newGeometricQuery, createCircleLayer: _createCircleLayer, addEventFeaturesByDivIcon: _addEventFeaturesByDivIcon, addEventFeaturesOnMap: _addEventFeaturesOnMap, showTrafficStatusInfo: _showTrafficStatusInfo, addUnHandleEventFeaturesByDivIcon: _addUnHandleEventFeaturesByDivIcon, showSoliderTrackOnMap: _showSoliderTrackOnMap, addReservoirStationOnMap: _addReservoirStationOnMap, loadReservoirStationEcharsByReservoirInfoId: _loadReservoirStationEcharsByReservoirInfoId, loadWaterAffairsReservoirStationEcharsByReservoirInfoId: _loadWaterAffairsReservoirStationEcharsByReservoirInfoId, addSoliderMarkerOnMap: _addSoliderMarkerOnMap, addSingleEvent: _addSingleEvent, circleQuery: _circleQuery, } } export { MultiScreenFun }