<template> <div id="poumianPage"> <div id="map" ref="rootmap"> <!--属性面板--> <div class="page-panel mapPanel" id="popuppoumian" v-if="poumianPopVis"> <!-- <a-icon type="close" class="close-icon" @click="closepopup()"/> --> <div class="panel-head"> <div class="title">{{ bianhaoName }}</div> </div> <div class="panel-body"> <div class="panel-list-item" v-for="item in realTimeData" :key="item.key"> <div class="label">{{ item.key }}</div> <div class="value">{{ item.value }}m</div> </div> </div> </div> </div> <!-- 暂无数据 --> <!-- <div class="noData" v-if="noData">暂无剖面数据 </div> --> </div> </template> <script> import 'ol/ol.css'; import { Point, Polygon, LineString } from 'ol/geom'; import { Map, View, Feature } from 'ol'; import Overlay from 'ol/Overlay.js'; import SourceVector from 'ol/source/Vector'; import LayerVector from 'ol/layer/Vector'; import Style from 'ol/style/Style'; import Fill from 'ol/style/Fill'; import Text from 'ol/style/Text'; import Stroke from 'ol/style/Stroke'; import dragzoom from 'ol/interaction/DragZoom'; import DragPan from 'ol/interaction/DragPan'; import MouseWheelZoom from 'ol/interaction/MouseWheelZoom'; import DoubleClickZoom from 'ol/interaction/DoubleClickZoom'; import Icon from 'ol/style/Icon'; import { defaults } from 'ol/control'; import bus from '@/bus'; import { nextTick } from 'vue'; export default { props: { reflashData: { type: Object, default: () => ({}), }, cutNumber: { type: Number, default: () => 0.17, }, }, data() { return { map: null, pointMin: [0.01, 0.37, 0.41, 0.17], pointMax: [4.6, 4.7, 4.8, 4.9], lineMin: [0.3, 0.5, 0.7, 0.8], lineMax: [1.4, 1.6, 1.8, 2.0], lineLeng: [30, 10, 28], pointCoordX: [], editSource: null, editVectorLayer: null, menu_overlay: null, poumianPopVis: false, noData: false, bianhaoName: '', realTimeData: [], featurehighlight: null, Pointfeaturehighlight: null, mouseCurrentFeature: null, }; }, mounted() { let self = this; bus.off('reflashData'); bus.on('reflashData', self.reflashData); }, methods: { reflashDataMethod({ pointMin, pointMax, lineMin, lineMax, lineLeng, pointName, lineName, linegeom1, lineFlows }) { // 没有值时显示暂无数据 if (pointMin.length == 0) { this.noData = true; } ///开始赋值 this.pointMin = pointMin; this.pointMax = pointMax; this.lineMin = lineMin; this.lineMax = lineMax; this.lineLeng = lineLeng; this.pointName = pointName; this.lineName = lineName; this.linegeom1 = linegeom1; this.lineFlows = lineFlows; if (!!!this.map) this.createMap(); let timeout = setTimeout(() => { //开始计算 this.computeData(); clearTimeout(timeout); }, 1000); }, //创建地图 createMap() { // 时间未改变且因子也没变化,只需要重新绘制 this.$nextTick(function () { setTimeout(() => { this.map.updateSize(); }, 500); }); //加载地图自定义图标 var view = new View({ projection: 'EPSG:3857', //使用这个坐标系 center: [50, 30], zoom: 22, maxZoom: 22, }); this.map = new Map({ controls: defaults({ attribution: false, zoom: false, rotate: false, }), target: 'map', view: view, }); let pan = null; this.map.getInteractions().forEach(element => { if (element instanceof DragPan) { pan = element; pan.setActive(false); } if (element instanceof dragzoom) { pan = element; pan.setActive(false); } if (element instanceof MouseWheelZoom) { pan = element; pan.setActive(false); } if (element instanceof DoubleClickZoom) { pan = element; pan.setActive(false); } }); //添加属性面板 this.menu_overlay = new Overlay({ element: document.getElementById('popuppoumian'), positioning: 'bottom-center', offset: [0, -20], }); this.menu_overlay.setVisible(false); this.map.addOverlay(this.menu_overlay); //鼠标事件 //鼠标移动事件 this.map.on('pointermove', e => { if (e.map.hasFeatureAtPixel(e.pixel)) { e.map.getTargetElement().style.cursor = 'pointer'; } else { e.map.getTargetElement().style.cursor = ''; } // if (this.menu_overlay) { // this.menu_overlay.setPosition(undefined); // } e.preventDefault(); var pixel = this.map.getEventPixel(e.originalEvent); var feature = this.map.forEachFeatureAtPixel(pixel, function (feature, layer) { return feature; }); //设置高亮feature为null if (this.featurehighlight) this.featurehighlight.setStyle(this.getLineStyle()); if (this.Pointfeaturehighlight) this.Pointfeaturehighlight.setStyle(this.getDownWhitePipeLineStyle()); //站点 if (feature) { if (feature.name) { this.bianhaoName = feature.name; if (feature.hasOwnProperty('rimElev')) { this.featurehighlight = feature; feature.setStyle(this.getHighLightStyle()); this.realTimeData = [ { key: '底高程', value: Number(feature.invertElev).toFixed(2), }, { key: '地面高程', value: Number(feature.rimElev).toFixed(2), }, ]; } else { this.Pointfeaturehighlight = feature; feature.setStyle(this.getHighLightPointStyle()); this.realTimeData = [ { key: '管径', value: feature.linegeom1, }, { key: '管长', value: feature.lineLeng, }, ]; } this.poumianPopVis = true; nextTick(() => { document.getElementById('popuppoumian').style.left = Number(e.pixel[0]) - 20 + 'px'; }); } } }); //map点击地图图标事件 //鼠标点击事件 this.map.on('click', e => { this.poumianPopVis = true; e.preventDefault(); var pixel = this.map.getEventPixel(e.originalEvent); var feature = this.map.forEachFeatureAtPixel(pixel, function (feature, layer) { return feature; }); if (feature.name) { nextTick(() => { document.getElementById('popuppoumian').style.left = Number(e.pixel[0]) - 20 + 'px'; }); if (!feature.name.includes('-')) { console.log(feature.name); bus.emit('selectWallFromPouM', feature.name); } } // //站点 // if (feature) { // if (feature.name) { // if (feature.hasOwnProperty('rimElev')) { // this.HighLightLinecoor(feature.values_.geometry.flatCoordinates); // } else { // this.HighLightPointcoor(feature.values_.geometry.flatCoordinates); // } // } // } }); }, computeData() { if (this.editSource) this.editSource.clear(); if (this.editVectorLayer) this.map.removeLayer(this.editVectorLayer); //新建矢量图层 this.editSource = new SourceVector({ wrapX: false, }); this.editVectorLayer = new LayerVector({ source: this.editSource, Declutter: true, }); this.map.addLayer(this.editVectorLayer); let dualSum = 0.0; this.pointCoordX = []; this.pointCoordX.push(0); this.pointCoordX.push(...this.lineLeng.map(length => (dualSum += length))); this.drawJCJpoint(this.pointCoordX); }, //检查井、管线渲染 drawJCJpoint(pointCoordX) { //获取Y值最大扩展比例系数 console.log(this.pointMax); console.log(this.lineMin); console.log(this.pointMin); var jcjmax = Math.max(...this.pointMax); var linezhemin = Math.min(...this.lineMin); var pointzhemin = Math.min(...this.pointMin); console.log(jcjmax); console.log(linezhemin); console.log(pointzhemin); var linemax = this.pointCoordX[this.pointCoordX.length - 1]; var cutNum = (jcjmax - pointzhemin) / (linemax * this.cutNumber); console.log(pointCoordX); console.log(this.pointName); for (var i = 0; i < pointCoordX.length; i++) { var start = [pointCoordX[i], this.pointMin[i] / cutNum]; var end = [pointCoordX[i], this.pointMax[i] / cutNum]; var jcjLine = new LineString([start, end]); var feature = new Feature(jcjLine); feature.name = this.pointName[i]; //编号 feature.invertElev = this.pointMin[i]; //节点底高程 feature.rimElev = this.pointMax[i]; //地面高程 feature.setStyle(this.getLineStyle()); this.editSource.addFeature(feature); } //绘制管线深色块下面的图层 var downArea = []; downArea.push([pointCoordX[0], pointzhemin / cutNum]); for (var k = 0; k < this.lineMin.length; k++) { console.log([pointCoordX[k], this.lineMin[k]]); downArea.push([pointCoordX[k], this.lineMin[k] / cutNum]); } downArea.push([pointCoordX[pointCoordX.length - 1], pointzhemin / cutNum]); downArea.push([pointCoordX[0], pointzhemin / cutNum]); var polygondown = new Polygon([downArea]); var featuredown = new Feature(polygondown); featuredown.setStyle(this.getDownPolygonStyle()); this.editSource.addFeature(featuredown); //绘制管线深色块上面的图层 var upArea = []; let lineFlow = []; for (var j = 0; j < this.lineMax.length; j++) { if (j > 0) { var cor1 = [pointCoordX[j - 1], this.lineMin[j - 1] / cutNum]; var cor2 = [pointCoordX[j - 1], this.lineMax[j - 1] / cutNum]; var cor3 = [pointCoordX[j], this.lineMax[j] / cutNum]; var cor4 = [pointCoordX[j], this.lineMin[j] / cutNum]; if (cor3[1] > cor2[1]) { lineFlow.push(1); } else { lineFlow.push(0); } } } let maxLineFlow = this.getArrMostFrequency(lineFlow)[0]; console.log('maxLineFlowmaxLineFlowmaxLineFlowmaxLineFlow', maxLineFlow); for (var j = 0; j < this.lineMax.length; j++) { upArea.push([pointCoordX[j], this.lineMax[j] / cutNum]); if (j > 0) { var cor1 = [pointCoordX[j - 1], this.lineMin[j - 1] / cutNum]; var cor2 = [pointCoordX[j - 1], this.lineMax[j - 1] / cutNum]; var cor3 = [pointCoordX[j], this.lineMax[j] / cutNum]; var cor4 = [pointCoordX[j], this.lineMin[j] / cutNum]; this.lineFlows[j - 1] = maxLineFlow; var polygonpipeline = new Polygon([[cor1, cor2, cor3, cor4, cor1]]); var featurepipeline = new Feature(polygonpipeline); var center = polygonpipeline.getInteriorPoint(); var featuremark = new Feature(center); featuremark.setStyle(this.getFlowIcon(this.lineFlows[j - 1] == 0 ? 0 : 110)); this.editSource.addFeature(featuremark); featurepipeline.name = this.lineName[j - 1]; //编号 featurepipeline.linegeom1 = this.linegeom1[j - 1]; //管径 featurepipeline.lineLeng = this.lineLeng[j - 1]; //管长 featurepipeline.name = this.lineName[j - 1]; //编号 featurepipeline.setStyle(this.getDownWhitePipeLineStyle()); this.editSource.addFeature(featurepipeline); } } for (var m = pointCoordX.length - 1; m > -1; m--) { var point; if (this.pointMax[m] > this.lineMax[m]) point = [pointCoordX[m], this.pointMax[m] / cutNum]; else point = [pointCoordX[m], this.lineMax[m] / cutNum]; upArea.push(point); } var polygonup = new Polygon([upArea]); var featureup = new Feature(polygonup); featureup.setStyle(this.getUpPolygonStyle()); this.editSource.addFeature(featureup); //加载边框 var xmin = 0.0; var ymin = pointzhemin / cutNum; var xmax = pointCoordX[pointCoordX.length - 1]; //var ymax=pointCoordX[pointCoordX.length-1]*0.6; var ymax = jcjmax / cutNum; for (var i = 0; i < pointCoordX.length; i++) { console.log(pointCoordX); console.log(this.lineName); //检查井编号 console.log('标注位置:' + this.pointName[i]); console.log([pointCoordX[i], pointzhemin / cutNum]); if (i > 0 && this.lineLeng[i - 1] < 30 && this.lineLeng[i] < 30) continue; var pointmark = new Point([pointCoordX[i], ymin]); var featuremark = new Feature(pointmark); featuremark.setStyle(this.getpointMarkStyle(this.pointName[i])); this.editSource.addFeature(featuremark); /* var featuremark2 = new Feature(pointmark); featuremark2.setStyle(this.getpointMarkStyle2(this.pointMin[i]+"")) this.editSource.addFeature(featuremark2) */ if (i > 0) { //管线编号 console.log('管线标注位置:' + this.lineName[i - 1]); var linemark = new Point([(pointCoordX[i - 1] + pointCoordX[i]) / 2, ymax]); var featurelinemark = new Feature(linemark); featurelinemark.setStyle(this.getlineMarkStyle(this.lineName[i - 1])); //this.editSource.addFeature(featurelinemark); } } //绘制边框 var box = new Polygon([ [ [0, ymin], [xmax, ymin], [xmax, ymax], [0, ymax], [0, ymin], ], ]); var feature = new Feature(box); feature.setStyle(this.getboxStyle()); this.editSource.addFeature(feature); //绘制网格线 //0-xmax pointzhemin-jcjmax //第一个y=0网上的横条 if (jcjmax > 0 && jcjmax <= 0.5) { var start1 = [0, jcjmax / cutNum]; var end1 = [pointCoordX[pointCoordX.length - 1], jcjmax / cutNum]; var wgLine1 = new LineString([start1, end1]); var feature1 = new Feature(wgLine1); feature1.setStyle(this.getWangeLineStyle()); this.editSource.addFeature(feature1); var linemark1 = new Point(end1); var featurelinemark1 = new Feature(linemark1); featurelinemark1.setStyle(this.getwanggeRightMarkStyle(jcjmax + '')); this.editSource.addFeature(featurelinemark1); } else if (jcjmax > 0.5) { var Num = Math.ceil(jcjmax / 0.5); var startnum; if (pointzhemin <= 0) startnum = 0; else startnum = Math.ceil(pointzhemin / 0.5); for (var n = startnum; n < Num; n++) { var start = [0, (n * 0.5) / cutNum]; var end = [pointCoordX[pointCoordX.length - 1], (n * 0.5) / cutNum]; var wgLine = new LineString([start, end]); var feature = new Feature(wgLine); feature.setStyle(this.getWangeLineStyle()); this.editSource.addFeature(feature); var linemark = new Point(end); var featurelinemark = new Feature(linemark); featurelinemark.setStyle(this.getwanggeRightMarkStyle(n * 0.5 + '')); this.editSource.addFeature(featurelinemark); } } //绘制网格线 //0-xmax pointzhemin-jcjmax //第一个y=0网下的横条 pointzhemin if (pointzhemin < 0 && pointzhemin >= -0.5) { var start2 = [0, pointzhemin / cutNum]; var end2 = [pointCoordX[pointCoordX.length - 1], pointzhemin / cutNum]; var wgLine2 = new LineString([start2, end2]); var feature2 = new Feature(wgLine2); feature2.setStyle(this.getWangeLineStyle()); this.editSource.addFeature(feature2); var linemark2 = new Point(end2); var featurelinemark2 = new Feature(linemark2); featurelinemark2.setStyle(this.getwanggeRightMarkStyle(pointzhemin + '')); this.editSource.addFeature(featurelinemark2); } else if (pointzhemin < -0.5) { var fushu = -pointzhemin; var Num = Math.ceil(fushu / 0.5); for (var n = 0; n < Num; n++) { var start3 = [0, (-n * 0.5) / cutNum]; var end3 = [pointCoordX[pointCoordX.length - 1], (-n * 0.5) / cutNum]; var wgLine3 = new LineString([start3, end3]); var feature3 = new Feature(wgLine3); feature3.setStyle(this.getWangeLineStyle()); this.editSource.addFeature(feature3); var linemark3 = new Point(end3); var featurelinemark3 = new Feature(linemark3); featurelinemark3.setStyle(this.getwanggeRightMarkStyle(-n * 0.5 + '')); this.editSource.addFeature(featurelinemark3); } } //绘制网格线 //0-xmax pointzhemin-jcjmax //第一个x=0网右的竖条 pointzhemin var maxLen = this.pointCoordX[this.pointCoordX.length - 1]; if (maxLen > 0 && maxLen <= 50) { var start4 = [maxLen, pointzhemin / cutNum]; var end4 = [maxLen, ymax]; var wgLine4 = new LineString([start4, end4]); var feature4 = new Feature(wgLine4); feature4.setStyle(this.getWangeLineStyle()); this.editSource.addFeature(feature4); var linemark4 = new Point(start4); var featurelinemark4 = new Feature(linemark4); featurelinemark4.setStyle(this.getwanggeTopMarkStyle(maxLen.toFixed(1) + '')); this.editSource.addFeature(featurelinemark4); } else if (maxLen > 50) { var Num = Math.ceil(maxLen / 50); for (var n = 0; n < Num; n++) { var start5 = [n * 50, pointzhemin / cutNum]; var end5 = [n * 50, ymax]; var wgLine5 = new LineString([start5, end5]); var feature5 = new Feature(wgLine5); feature5.setStyle(this.getWangeLineStyle()); this.editSource.addFeature(feature5); var linemark5 = new Point(start5); var featurelinemark5 = new Feature(linemark5); featurelinemark5.setStyle(this.getwanggeTopMarkStyle(n * 50 + '')); this.editSource.addFeature(featurelinemark5); } var start6 = [maxLen, pointzhemin / cutNum]; var linemark6 = new Point(start6); var featurelinemark6 = new Feature(linemark6); featurelinemark6.setStyle(this.getwanggeTopMarkStyle(maxLen.toFixed(1) + '')); this.editSource.addFeature(featurelinemark6); } //加载定位范围的隐藏边框,用于固定视图 /* var xminView=-xmax*0.1; var yminView=ymin*0.6; var xmaxView=xmax*1.2 var ymaxView=ymax*1.05 var boxView=new Polygon([[[xminView,ymin+yminView],[xmaxView,ymin+yminView],[xmaxView,ymaxView],[xminView,ymaxView],[xminView,ymin+yminView]]]); */ var leftright = xmax * 0.01; var upbuttom = (ymax - ymin) * 0.2; /* var xminView=-xmax*0.1; var xmaxView=xmax*1.2 var yminView=(ymax-ymin)*0.2; var ymaxView=ymax*1.05 */ var boxView = new Polygon([ [ [-leftright, ymin - upbuttom], [xmax + leftright, ymin - upbuttom], [xmax + leftright, ymax + upbuttom], [-leftright, ymax + upbuttom], [-leftright, ymin - upbuttom], ], ]); var featureView = new Feature(boxView); featureView.setStyle(this.getViewboxStyle()); this.editSource.addFeature(featureView); //定位地图 var center = featureView.getGeometry().getExtent(); console.log(center); this.map.getView().fit(center, this.map.getSize()); /* var zoomtag=this.map.getView().getZoom() this.map.getView().setMaxZoom(zoomtag) this.map.getView().setMinZoom(zoomtag) */ setTimeout(() => { this.map.updateSize(); }, 100); }, getArrMostFrequency(arr) { let maxElement, maxNum = 1; let obj = arr.reduce((p, n) => { p[n] ? p[n]++ : (p[n] = 1); if (p[n] > maxNum) { maxElement = n; maxNum++; } return p; }, {}); return [maxElement, maxNum]; }, getpointMarkStyle2(pointMin) { console.log(pointMin); return new Style({ text: new Text({ text: pointMin, font: 'normal 10px 微软雅黑', fill: new Fill({ color: 'aqua', }), offsetY: 50, textAlign: 'center', textBaseline: 'bottom', }), zIndex: 999999, }); }, getpointMarkStyle(text) { return new Style({ text: new Text({ text: text, font: 'normal 10px 微软雅黑', fill: new Fill({ color: 'aqua', }), offsetY: 40, textAlign: 'center', textBaseline: 'bottom', }), zIndex: 999999, }); }, getwanggeTopMarkStyle(text) { return new Style({ text: new Text({ text: text, font: 'normal 10px 微软雅黑', fill: new Fill({ color: 'aqua', }), offsetY: 20, textAlign: 'center', textBaseline: 'bottom', }), zIndex: 999999, }); }, getwanggeRightMarkStyle(text) { return new Style({ text: new Text({ text: text, font: 'normal 10px 微软雅黑', fill: new Fill({ color: 'aqua', }), offsetX: 20, offsetY: 5, textAlign: 'center', textBaseline: 'bottom', }), zIndex: 999999, }); }, getlineMarkStyle(text) { return new Style({ text: new Text({ text: text, font: 'normal 10px 微软雅黑', fill: new Fill({ color: 'aqua', }), offsetY: -20, textAlign: 'center', textBaseline: 'bottom', }), zIndex: 999999, }); }, getFlowIcon(rotation = 0) { return new Style({ image: new Icon({ src: '/images/flow.png', size: [24, 24], rotation, }), }); }, getUpPolygonStyle() { return new Style({ stroke: new Stroke({ color: 'rgb(33,49,81)', lineCap: 'butt', width: 3, }), fill: new Fill({ color: 'rgb(33,49,81)', }), zIndex: 999997, }); }, getDownWhitePipeLineStyle() { return new Style({ stroke: new Stroke({ color: 'black', lineCap: 'butt', width: 1, }), fill: new Fill({ color: 'rgb(158,183,235)', }), }); }, getDownPolygonStyle() { return new Style({ stroke: new Stroke({ color: 'rgb(33,49,81)', lineCap: 'butt', width: 3, }), fill: new Fill({ color: 'rgb(33,49,81)', }), zIndex: 999997, }); }, getboxStyle() { return new Style({ stroke: new Stroke({ color: 'gray', lineCap: 'butt', width: 2, }), }); }, //隐藏样式的边框视角 getViewboxStyle() { return new Style({}); }, //设置点线面style getPointStyle() { return new Style({ image: new Icon({}), }); }, //网格线 getWangeLineStyle() { return new Style({ stroke: new Stroke({ color: '#666', lineCap: 'butt', width: 0.2, }), zIndex: 999999999997, }); }, //检查井线条 getLineStyle() { return new Style({ stroke: new Stroke({ color: '#0088ff', lineCap: 'butt', width: 3, }), zIndex: 999999999999, }); }, //高亮面样式 getHighLightPointStyle(feature) { return new Style({ fill: new Fill({ //矢量图层填充颜色,以及透明度 color: 'rgb(0,170,100)', }), /* stroke: new Stroke({ color: "#33ffff", lineCap: "butt", width: 0.0001, }), */ zIndex: 9, }); }, //高亮线样式 getHighLightStyle(feature) { return new Style({ //填充色 fill: new Fill({ color: 'rgb(0,170,100)', }), //边线颜色 stroke: new Stroke({ color: 'rgb(0,170,100)', width: 2, }), zIndex: 9999999999999, }); }, }, watch: { reflashData: { handler(newValue, oldValue) { if (Object.keys(newValue).length) this.$nextTick(() => this.reflashDataMethod(newValue)); }, deep: true, immediate: true, }, }, }; </script> <style lang="scss" scoped> #poumianPage { position: relative; width: 100%; height: calc(100% - 50px); top: 40px; } #map { height: 100%; width: 100%; overflow: auto; position: absolute; right: 0; background-color: rgba(255, 255, 255, 0); } .page-modal-no-footer { :deep(.ant-modal-body) { height: 450px; } } .mapPanel { position: absolute; top: 10px; left: 10px; width: 100%; height: 150px; overflow: auto; z-index: 99; .panel-head { margin-top: 10px; font-weight: bold; color: #00eeff; } .panel-body { .label { color: rgb(164, 226, 93); } } } .noData { text-align: center; font-size: 16px; color: #fdfdfd; position: absolute; top: 40%; width: 100%; z-index: 100; } .page-panel { position: absolute; width: 200px; padding: 0 15px; background: rgba(69, 92, 126, 0.7); color: white; border: 1px solid #3b5082; border-top: 2px solid #9c9c9c; bottom: 30px; } .ol-viewport { background: #07264c !important; } </style>