<template> <MapBox :initJson="props.initJson" :loadCallback="getModalData" @map-click="mapClickEvt" v-show="MapShow"> </MapBox> <!-- <div id="trajectory-popup" ref="trajectory">1111</div> --> <!-- <div style="width: 700px; height: 350px" ref="streetSpace1" id="streetSpace1"> <streetSpace :location="datas.location"></streetSpace> </div> --> </template> <script setup name="Map"> import bus from '@/bus'; import request from '@/utils/request'; import MapBox from '@/components/Map/Map'; import { getBaseListPoint } from '@/api/MonitorAssetsOnMap'; import { supervisionRealinformationList } from '@/api/internetVehicles'; import useUserStore from '@/store/modules/user'; import { reactive, onMounted, onBeforeUnmount, nextTick, defineProps, watch } from 'vue'; import streetSpace from '@/components/Map/streetSpace'; import gq_line from '../../../public/static/libs/mapbox/json/gq_line.json'; import ys_flow from '../../../public/static/libs/mapbox/json/ys_flow.json'; import line from '../../../public/static/libs/mapbox/json/line.json'; import point from '../../../public/static/libs/mapbox/json/point.json'; import { MapboxOverlay } from '@deck.gl/mapbox'; import { LineLayer, GeoJsonLayer } from '@deck.gl/layers'; import { TripsLayer, Tile3DLayer } from '@deck.gl/geo-layers'; import { Tiles3DLoader } from '@loaders.gl/3d-tiles'; const appStore = useUserStore(); const MapShow = ref(true); const props = defineProps({ // 数据id initJson: { type: String, default: () => '/static/libs/mapbox/style/wh_dhgx.json', }, loadCallback: { type: Function, default: () => function () {}, }, }); const datas = reactive({ location: [], isOpenPanorama: false, }); const { proxy } = getCurrentInstance(); const refreshTimer = ref(null); const default_params = { point: { key: 'point', prevId: null, }, sx_wn_hm_monitoring: { key: 'sx_wn_hm_monitoring', prevId: null, }, town: { key: '乡镇', c_key: '村', prevId: null, }, hupo: { key: '湖泊', prevId: null, }, gangqu: { key: '港渠', prevId: null, }, hb_wh_dhgx_merge: { key: 'hb_wh_dhgx_merge', children: { psfq: { key: '排水分区' }, }, prevId: null, }, 海绵型水系: { color: 'rgba(35,184,153,1)' }, 海绵建筑与社区: { color: 'rgba(255,119,125,1)' }, 海绵型道路广场: { color: 'rgba(255,152,4,1)' }, 管网及泵站: { color: 'rgba(0,153,68,1)' }, 海绵型公园绿地: { color: 'rgba(223,214,20,1)' }, flow: { color: 'rgba(255,255,255,1)' }, rain: { color: 'rgba(255,255,255,1)' }, water_level: { color: 'rgba(255,255,255,1)' }, waterlogging: { color: 'rgba(255,255,255,1)' }, rain_bz: { color: 'rgba(255,255,255,1)' }, sxt: { color: 'rgba(255,255,255,1)' }, WSCLC: { color: 'rgba(255,255,255,1)' }, overflow_outfall: { color: 'rgba(255,255,255,1)' }, rainfall: { color: 'rgba(223,214,20,1)' }, pipeline: { color: 'rgba(223,214,20,1)' }, drain_outlet: { color: 'rgba(223,214,20,1)' }, }; window.mapInitBusName = 'mapInitBusName'; const mapClickEvt = (lngLat, properties, layerId) => { datas.isOpenPanorama && (() => { setPopupDom('proxy.$refs.streetSpace1', 2); newfiberMap.popup1.setLngLat(lngLat).addTo(newfiberMap.map); datas.location = lngLat; })(); console.log('properties', properties, layerId); // 图层点击事件 if (properties) bus.emit('FenQuClick', properties); clearTrajectory(); clearTemporaryData(); proxy.$emit('map-click1', lngLat, properties, layerId); const { town, hupo, gangqu, hb_wh_dhgx_merge } = default_params; const { setLayerVisible, setHighlight, setGeoJSON, removeMapDatas } = events_params; const _keys = ['rain_water_pump_station_info', 'sewage_pump_station_info']; (() => { setHighlight_(properties); newfiberMap .getLayers() .filter(i => i.newfiberId == '村域边界')[0] .setData(turf.featureCollection([])); if (town.prevId) { busEmit(setLayerVisible.key, { layername: town.key, isCheck: true }); busEmit(setLayerVisible.key, { layername: town.prevId, isCheck: false }); town.prevId = null; } busEmit( removeMapDatas.key, _keys.map(k => k + 1) ); })(); ( ({ [town.key]: () => { newfiberMap .getLayers() .filter(i => i.newfiberId == '村域边界')[0] .setData( turf.featureCollection( newfiberMap.map.getSource('hb_wh_gxq_cun2')._data.features.filter(i => i.properties.type == properties.name) ) ); busEmit(setLayerVisible.key, { layername: town.key, isCheck: false }); busEmit(setLayerVisible.key, { layername: properties.name, isCheck: true }); town.prevId = properties.name; }, [hupo.key]: () => { if (hupo.prevId) { busEmit(setLayerVisible.key, { layername: hupo.prevId, isCheck: false, values: [hupo.prevId, ['严东湖', '严西湖'].join(',')], }); hupo.prevId = null; bus.emit('removeMapDatas', ['outlet_info1']); } const keys = ['outlet_info', '村域边界', 'lake']; const specialKeys = ['严东湖', '严西湖']; newfiberMap .getLayers() .filter(i => i.newfiberId == keys[1])[0] .setData(turf.featureCollection(gq_line.features.filter(i => i.properties.w_id == properties.name))); let features = newfiberMap.map .getSource('point') ._data.features.filter( i => i.properties.type == keys[0] && i.properties.waterBodyType == keys[2] && i.properties.waterBodyId == properties.pid ) .map(i => _.cloneDeep(i)); features.forEach(i => (i.properties.type = i.properties.type + '1')); busEmit(events_params.setGeoJSON.key, { json: turf.featureCollection(features), key: keys[0] + 1, }); const values = [specialKeys.includes(properties.name) ? specialKeys.join(',') : properties.name]; busEmit(setLayerVisible.key, { layername: properties.name, isCheck: true, values, }); hupo.prevId = properties.name; }, [gangqu.key]: () => { if (gangqu.prevId) { gangqu.prevId = null; bus.emit('removeMapDatas', ['outlet_info1']); } const keys = ['outlet_info', '村域边界', 'channel']; newfiberMap .getLayers() .filter(i => i.newfiberId == keys[1])[0] .setData(turf.featureCollection(gq_line.features.filter(i => i.properties.name == properties.name))); let features = newfiberMap.map .getSource('point') ._data.features.filter( i => i.properties.type == keys[0] && i.properties.waterBodyType == keys[2] && i.properties.waterBodyId == properties.pid ) .map(i => _.cloneDeep(i)); features.forEach(i => (i.properties.type = i.properties.type + '1')); busEmit(events_params.setGeoJSON.key, { json: turf.featureCollection(features), key: keys[0] + 1, }); gangqu.prevId = properties.name; }, [hb_wh_dhgx_merge.key]: () => { if (properties.layer == hb_wh_dhgx_merge.children.psfq.key) { const layerSplit = properties.c_layer.split('_'); let geometry = Terraformer.WKT.parse(properties.geometry); busEmit(setHighlight.key, []); const type = _.chunk(layerSplit[1], 2)[0].join(''); let pType = type == '雨水' ? 'YS' : 'WS'; pType == 'YS' ? ys_flow(properties, true) : ws_flow(properties); if (layerSplit[2] != 3) return mapCenterByData(turf.bbox(geometry)); let features = newfiberMap.map .getSource('hb_wh_dhgx_pipe_line_n_y_w') ._data.features.filter(i => i.properties[type + '系统'] == properties.name && i.properties['管段类型'] == pType); let pFeatures = newfiberMap.map .getSource('point') ._data.features.filter(i => _keys.includes(i.properties.type) && (i.properties.pointTypeName || '').includes(type)); let p_features = turf.pointsWithinPolygon(turf.featureCollection(pFeatures), geometry); p_features.features.forEach(i => (i.properties.type = i.properties.type + 1)); busEmit(setGeoJSON.key, { json: p_features }); console.log('features', p_features, pFeatures); busEmit(setHighlight.key, turf.flatten(turf.featureCollection(features)).features); } }, })[layerId] || function () { //newfiberMap.map.easeTo(newfiberMap.config_.params.init); } )(); function ys_flow(properties, visible) { const keys = ['雨水系统流向', '雨水系统流向1']; keys.forEach(key => busEmit(setLayerVisible.key, { layername: key, isCheck: visible })); setHighlight_(properties); } function ws_flow(properties) { const keys_ = ['雨水', '污水']; const keys = ['1_泵站', '1_污水处理厂', '分区流向', '分区流向1']; bus.emit('removeMapDatas', keys); newfiberMap .getLayers() .filter(i => i.newfiberId == keys[3])[0] .getSource() .setData(turf.featureCollection([])); let key = (properties.c_layer || '').includes(keys_[0]) ? keys_[0] : keys_[1]; if (properties.pointTypeName) key = keys_[1]; const nameKey = '龙王咀' || properties.name.substring(0, 2); let features = line.features.filter(i => i.properties.area.includes(key)); // let features1 = point.features.filter(i => i.properties.type.includes(key) ); let points = _.groupBy(point.features, a => a.properties.type); features.forEach(i => { i.properties.type = keys[2]; i.properties.color = key == keys_[0] ? 'rgba(21,127,176,1)' : 'rgba(255,0,0,1)'; }); /* Object.keys(points).map((key) => bus.emit("setGeoJSON", { json: turf.featureCollection( points[key].map((i) => ({ type: i.type, geometry: i.geometry, properties: { ...i.properties, type: "1_" + key }, })) ), key: "1_" + key, }) );*/ // bus.emit("setGeoJSON", { json: turf.featureCollection(features), key: keys[2] }); /* newfiberMap .getLayers() .filter((i) => i.newfiberId == keys[3])[0] .getSource() .setData(turf.featureCollection(features));*/ setHighlight_(properties); } }; function setHighlight_(properties = {}) { const temporary = 'temporary'; bus.emit('removeMapDatas', [temporary]); if (!properties.geometry) return; let geojson = turf.polygonToLine(Terraformer.WKT.parse(properties.geometry)); geojson = geojson.features ? geojson : turf.featureCollection([geojson]); geojson.features.forEach(i => (i.properties = { color: 'rgba(255,255,0,1)', type: temporary })); bus.emit('setGeoJSON', { json: geojson, key: temporary }); newfiberMap .getLayers() .filter(i => i.newfiberId == '村域边界')[0] .setData(geojson); } const getModalData = () => { isClockInRange(); const { setLayerVisible, setHighlight } = events_params; Object.keys(events_params) .filter(key => events_params[key].method) .forEach(key => busOn(events_params[key].key, events_params[key].method)); // 获取地图项目数据 dataToMap({}); //5分钟刷新一次实时数据1000 * 60 * 5) /* refreshTimer.value = setInterval(() => { dataToMap({ params: { rainfall: {}, pipeline: {}, drainUutlet: {} } }); }, 1000 * 60 * 5);*/ createPopup(); busEmit(events_params.closeAllLayer.key); proxy.$emit('loadCallback'); ww(); ysFlow(); }; const ysFlow = () => { const key = '雨水系统流向'; // let features = line.features.filter(i => key.includes(i.properties.area)); // ys_flow.features = ys_flow.features.concat(features).map(i => ({ ...i, properties: { ...i.properties, color: 'rgba(49,254,223,1)', name: undefined } })); newfiberMap .getLayers() .filter(i => i.newfiberId == key)[0] .setData(ys_flow); busEmit(events_params.setGeoJSON.key, { json: ys_flow, key: key + 1 }); }; const ww = () => { const keys = ['尾水路径']; let features = newfiberMap.map .getSource('hb_wh_dhgx_merge') ._data.features.filter(i => i.properties.c_layer.includes(keys[0]) && i.properties.geometry_type == 2); busEmit(events_params.setGeoJSON.key, { json: turf.featureCollection(features), key: keys[0], }); }; let prevObj = null; const panelDataToMap = obj => { // debugger const { setLayerVisible, setHighlight } = events_params; // if (prevObj != null) busEmit(setLayerVisible.key, { layername: prevObj.type, isCheck: false }); busEmit(setHighlight.key, []); // busEmit(setLayerVisible.key, { layername: obj.type, isCheck: true }); // debugger; let features = ['point', 'linestring', 'polygon', 'hb_wh_dhgx_merge'] .map(key => newfiberMap.map .getSource(key) ._options.data.features.filter( i => (i.properties.name || '').includes(obj.name) && (obj.id ? obj.id == i.properties.pid : true) ) ) .flat(); let feature = features.filter(i => i.properties.name == obj.name)[0] || features[_.random(0, features.length - 1)]; if (!feature) return; busEmit(setHighlight.key, [feature]); mapCenterByData(turf.bbox(feature)); }; const mapCenterByData = bbox => { newfiberMap.map.fitBounds( [ [bbox[0], bbox[1]], [bbox[2], bbox[3]], ], { padding: 50, offset: [100, 10], maxZoom: 18, pitch: 0, duration: 500 } ); }; const trajectoryToMap = data => { clearTrajectory(); const fields = { lng: 'l', lat: 'a' }; mapCenterByData([data[0]['l'], data[0]['a'], data[1]['l'], data[1]['a']].map(Number)); newfiberMap.map.trackLayer = new mapboxgl1.TrackLayer(newfiberMap.map, data, fields, (properties, index) => { const lng = properties[fields.lng]; const lat = properties[fields.lat]; if (!(index % 50)) { newfiberMap.map.flyTo({ center: [lng, lat], bearing: newfiberMap.map.getBearing(), pitch: newfiberMap.map.getPitch(), zoom: newfiberMap.map.getZoom(), }); } /* setPopupDom('proxy.$refs.trajectory', 1); newfiberMap.popup.setLngLat([lng,lat]).addTo(newfiberMap.map);*/ }); }; const clearTrajectory = () => { if (newfiberMap.map.trackLayer) newfiberMap.map.trackLayer.destory(); if (newfiberMap.popup) newfiberMap.popup.remove(); }; const dataToMap = async ({ params, callback }) => { const { setLayerVisible, beansToMap } = events_params; const data_default_params = { sites: { method: getBaseListPoint, fields: { geometry: 'geometry', name: 'name' }, groupMethod: data => _.groupBy( data .map(i => i.data) .flat() .filter(i => i.geometry) .map(item => ({ ...item })), v => v.pointType + (v.connectType ? '_' + v.connectType : '') ), }, //车辆 cheliang: { method: supervisionRealinformationList, fields: { lng: 'longitude', lat: 'latitude', name: 'plateNumber' }, groupMethod: data => _.groupBy( data.supervisionRealinformationList .filter(i => i.longitude && i.latitude) .map(item => ({ ...item, type: item.vehicleCategory + item.status })), v => v.type ), }, }; let keys = Object.keys(params || data_default_params); const results = await Promise.all( keys.map((k, idx) => data_default_params[k].method((params || {})[k] || data_default_params[k].mPrams)) ); results.forEach((result, idx) => { const data = result.data; const k = keys[idx]; if (!data) return; const filteredData = filterGeometryNotEmpty(data); appStore.SET_MapData(filteredData); bus.emit('changeData'); const groups = data_default_params[k].groupMethod(data); const g_keys = Object.keys(groups); bus.emit('removeMapDatas', g_keys); g_keys.forEach(key => busEmit(beansToMap.key, { beans: groups[key].map(i => ({ ...i, color: (default_params[key] || {}).color, })), fields: data_default_params[k].fields, type: key, }) ); }); callback && callback(); }; const createPopup = () => { newfiberMap.popup = new mapboxgl1.Popup({ closeButton: false, closeOnClick: false, }); newfiberMap.popup1 = new mapboxgl1.Popup({ closeButton: false, closeOnClick: false, }); }; const setPopupDom = (dom, offset) => { f(); nextTick(f); function f() { console.log('eval(dom)', eval(dom)); newfiberMap.popup1.setDOMContent(eval(dom)); newfiberMap.popup1.setOffset(offset); } }; function filterGeometryNotEmpty(inputData) { return inputData.map(item => { // 过滤掉每个对象中的 data 数组里 geometry 为空的元素 const filteredData = item.data.filter(dataPoint => dataPoint.geometry !== ''); return { ...item, data: filteredData, }; }); } //路径规划 const pathPlanning = async (origin = '116.481028,39.989643', destination = '116.465302,40.004717', callback) => { const origin_ = origin.split(',').map(Number); const destination_ = destination.split(',').map(Number); if (origin_.length != 2 || destination_.length != 2) return console.log('输入参数错误:', origin, destination); const results = await request( `/amap/v3/direction/driving?origin=${origin}&destination=${destination}&extensions=all&output=json&key=74f1b47f7fea1971354edb2dfacb3982` ); if (!results.route.paths[0]) return console.log('暂无路径!'); callback && callback( turf.featureCollection( results.route.paths[0].steps.map(i => turf.feature( Terraformer.WKT.parse( `LINESTRING(${i.polyline .split(';') .map(i => i.split(',').join(' ')) .join(',')})` ), i ) ) ) ); }; //判断是否在打卡点内 const isClockInRange = ( currentLocation = 'POINT(109.41360117253636 34.49038724464877)', ranges = [ 'POINT(109.43167853335872 34.51345940211415)', 'POINT(109.46797592891363 34.51145239795833)', 'POINT(109.44903576574815 34.50165755773118)', ], rVal = 500 ) => { const feature = { ...Terraformer.WKT.parse(currentLocation) }; return ( ranges .map(i => turf.buffer({ ...Terraformer.WKT.parse(i) }, rVal / 1000)) .map(i => turf.booleanContains(i, feature)) .filter(Boolean)[0] || false ); }; const clearTemporaryData = () => { const { setLayerVisible, removeMapDatas } = events_params; const keys_ = [ '问题管线', '1_泵站', '1_污水处理厂', '1_调蓄池', '分区流向', '分区流向1', 'rainwater_pipeline_water_level', 'rainwater_pipeline_water_level_GWGSWYX', 'outlet_info1', 'temporary', 'highlight_linestring', 'highlight_polygon', 'highlight_point', ]; const hideKeys = ['雨水系统流向', '雨水系统流向1']; bus.emit(removeMapDatas.key, keys_); const keys = newfiberMap.config_.l7.filter(i => i.temporary).map(i => i.key); newfiberMap .getLayers() .filter(i => keys.includes(i.newfiberId)) .forEach(i => i.setData({ type: 'FeatureCollection', features: [] })); hideKeys.forEach(i => busEmit(setLayerVisible.key, { layername: i, isCheck: false })); setHighlight_(); }; const remove3Dtiles = () => { newfiberMap.map._controls.filter(i => i._deck).forEach(i => i.setProps({ layers: [] })); }; const load3DTiles = ({ id, url }) => { remove3Dtiles(); let deckOverlay = null; deckOverlay = newfiberMap.map._controls.filter(i => i._deck)[0]; if (!deckOverlay) { deckOverlay = new MapboxOverlay({ interleaved: true, layers: [], }); newfiberMap.map.addControl(deckOverlay); } const layers = deckOverlay._props.layers; deckOverlay.setProps({ layers: [ ...layers, new Tile3DLayer({ id: id, name: id, data: url, loader: Tiles3DLoader, extruded: true, // 设置3D功能 opacity: 1, // 设置透明度 loadOptions: { '3d-tiles': { loadGLTF: true, decodeQuantizedPositions: false, isTileset: 'auto', assetGltfUpAxis: null, }, }, pickable: true, // 设置可选取 onTilesetLoad: tileset => { const { cartographicCenter, zoom } = tileset; deckOverlay.setProps({ initialViewState: { longitude: cartographicCenter[0], latitude: cartographicCenter[1], zoom, }, }); }, pointSize: 2, }), ], }); }; const busEmit = (event, params) => bus.emit(event, params); const busOn = (event, func) => bus.on(event, func); const busOff = event => bus.off(event); //添加临时动态线 const addDynamicLine = (c_layer, c_layer1) => { if (newfiberMap.getLayerByName('dynamicLine')) { newfiberMap.removeLayer(newfiberMap.getLayerByName('dynamicLine')); } let dynamicLineJson = turf.featureCollection( newfiberMap.map .getSource('sx_wn_hm_merge') ._data.features.filter( feature => feature.properties.c_layer.includes(c_layer) && feature.properties.c_layer.includes(c_layer1) ) ); console.log(c_layer, dynamicLineJson); let layer = new mapboxL7.LineLayer({ name: 'dynamicLine', }) .source(dynamicLineJson) .size(3) .shape('line') .color('color') .animate({ interval: 1, duration: 2, trailLength: 0.8, }); newfiberMap.addLayer(layer); }; const events_params = { removeMapDatas: { key: 'removeMapDatas' }, setGeoJSON: { key: 'setGeoJSON' }, setLayerVisible: { key: 'setLayerVisible' }, beansToMap: { key: 'beansToMap' }, closeAllLayer: { key: 'closeAllLayer' }, setHighlight: { key: 'setHighlight' }, dataToMap: { key: 'dataToMap', method: dataToMap }, pathPlanning: { key: 'pathPlanning', method: pathPlanning }, panelDataToMap: { key: 'panelDataToMap', method: panelDataToMap }, trajectoryToMap: { key: 'trajectoryToMap', method: trajectoryToMap }, clearTrajectory: { key: 'clearTrajectory', method: clearTrajectory }, clearTemporaryData: { key: 'clearTemporaryData', method: clearTemporaryData }, load3DTiles: { key: 'load3DTiles', method: load3DTiles }, remove3Dtiles: { key: 'remove3Dtiles', method: remove3Dtiles }, isOpenPanorama: { key: 'isOpenPanorama', method: flag => (datas.isOpenPanorama = flag), }, }; onMounted(() => { bus.on('YQ_head', val => { if (val == false) { MapShow.value = false; } else { MapShow.value = true; } }); }); onBeforeUnmount(() => { bus.off('YQ_head'); Object.keys(events_params) .filter(key => events_params[key].method) .forEach(key => busOff(events_params[key].key)); clearInterval(refreshTimer.value); // 清除定时器 refreshTimer.value = null; }); </script> <style lang="scss"> #Map { width: 100%; height: 100%; } </style>