|
@@ -0,0 +1,395 @@
|
|
|
+<template>
|
|
|
+ <div ref="pipeSectionPicture" style="width: 99%; height: 99%"></div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import * as echarts from 'echarts'
|
|
|
+import PipeQueryHelper from '@/utils/mapCommon/PipeQueryHelper'
|
|
|
+import Config from './config.json'
|
|
|
+export default {
|
|
|
+ name: 'crossSectionChart', //断面图
|
|
|
+ props: {
|
|
|
+ drawSectionInfo: null
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ config: Config,
|
|
|
+ _echart: null,
|
|
|
+ crossResult: null,
|
|
|
+ SelectPipe: null,
|
|
|
+ crossLinePoints: null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ //绘制断面图
|
|
|
+ drawSectionPicture() {
|
|
|
+ if (this._echart) {
|
|
|
+ this._echart.dispose()
|
|
|
+ this._echart = null
|
|
|
+ }
|
|
|
+ if (this.crossResult == undefined && this.SelectPipe == undefined && this.crossLinePoints == undefined) return
|
|
|
+ const minDiameter = 10
|
|
|
+ const minScatter = 10
|
|
|
+ const maxScatter = 30
|
|
|
+ const maxDiameter = 1000
|
|
|
+ this.crossResult.sort((a, b) => {
|
|
|
+ return a.distance - b.distance
|
|
|
+ })
|
|
|
+ const s3mlayername = this.SelectPipe.s3mlayername
|
|
|
+ const currentSceneLayer = this.$_.find(PipeQueryHelper.pipe, (item) => {
|
|
|
+ return item.origindataset === s3mlayername
|
|
|
+ })
|
|
|
+
|
|
|
+ //选中管线信息
|
|
|
+ const selectPipeColor = 'rgb(' + currentSceneLayer.lineColor.join(',') + ')'
|
|
|
+ const selectPipe = this.crossLinePoints
|
|
|
+ const fromPoint = Cesium.Cartographic.fromCartesian(selectPipe[0])
|
|
|
+ const toPoint = Cesium.Cartographic.fromCartesian(selectPipe[1])
|
|
|
+ const selectPipeDiameter = isNaN(this.SelectPipe[this.config.sjFields.diameter])
|
|
|
+ ? 10
|
|
|
+ : parseFloat(this.SelectPipe[this.config.sjFields.diameter])
|
|
|
+
|
|
|
+ const selepipeLineSymbol =
|
|
|
+ selectPipeDiameter < 10
|
|
|
+ ? minDiameter
|
|
|
+ : ((selectPipeDiameter - minDiameter) / (maxDiameter - minDiameter)) * (maxScatter - minScatter) + minScatter
|
|
|
+ //起始点地面高程
|
|
|
+ const inRoadHeight = parseFloat(this.SelectPipe[this.config.sjFields.inSurfaceH])
|
|
|
+ const outRoadHeight = parseFloat(this.SelectPipe[this.config.sjFields.outSurfaceH])
|
|
|
+
|
|
|
+ const demHeight = []
|
|
|
+ const roadHeight = []
|
|
|
+ const data = this.crossResult.map((item) => {
|
|
|
+ const carto = Cesium.Cartographic.fromCartesian(item.position).height
|
|
|
+ demHeight.push(carto)
|
|
|
+ roadHeight.push(item.height)
|
|
|
+ return {
|
|
|
+ value: [item.distance, carto],
|
|
|
+ symbol: item.diameterType === 'circle' ? 'circle' : 'emptyRectangle',
|
|
|
+ symbolSize:
|
|
|
+ item.diameter < 10
|
|
|
+ ? minDiameter
|
|
|
+ : ((item.diameter - minDiameter) / (maxDiameter - minDiameter)) * (maxScatter - minScatter) + minScatter,
|
|
|
+ itemStyle: {
|
|
|
+ color: 'rgba(255,255,255,0)',
|
|
|
+ borderColor: 'rgb(' + item.lineColor.join(',') + ')',
|
|
|
+ borderWidth: 3
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ demHeight.push(fromPoint.height)
|
|
|
+ demHeight.push(toPoint.height)
|
|
|
+ demHeight.push(inRoadHeight)
|
|
|
+ demHeight.push(outRoadHeight)
|
|
|
+ //点积求投影长度
|
|
|
+ const fcross = Cesium.Cartographic.fromCartesian(this.crossLinePoints[0])
|
|
|
+ const lcross = Cesium.Cartographic.fromCartesian(this.crossLinePoints[1])
|
|
|
+ const newLcross = Cesium.Cartographic.fromRadians(lcross.longitude, lcross.latitude, fcross.height)
|
|
|
+ const vectora = Cesium.Cartesian3.subtract(
|
|
|
+ Cesium.Cartographic.toCartesian(newLcross),
|
|
|
+ Cesium.Cartographic.toCartesian(fcross),
|
|
|
+ new Cesium.Cartesian3()
|
|
|
+ )
|
|
|
+ const vectorb = Cesium.Cartesian3.subtract(
|
|
|
+ this.crossLinePoints[1],
|
|
|
+ this.crossLinePoints[0],
|
|
|
+ new Cesium.Cartesian3()
|
|
|
+ )
|
|
|
+ const projectDistance = Cesium.Cartesian3.dot(vectora, vectorb) / Cesium.Cartesian3.magnitude(vectora)
|
|
|
+
|
|
|
+ const maxHeight = Math.max.apply(null, roadHeight)
|
|
|
+ const lineLength = Math.abs(projectDistance)
|
|
|
+ let minYAxis = Math.floor(Math.min.apply(null, demHeight)) - 1
|
|
|
+ const maxYAxis = Math.ceil(Math.max.apply(null, demHeight))
|
|
|
+
|
|
|
+ const maxXAxis = Math.ceil(lineLength)
|
|
|
+ const minXAxis = -(maxXAxis / 10)
|
|
|
+ const splitTick = (maxYAxis - minYAxis) / 8
|
|
|
+ //const splitTick = 1;
|
|
|
+ minYAxis = minYAxis - splitTick * 4
|
|
|
+ // minYAxis=minYAxis-splitTick*;
|
|
|
+ let pipeInfoArea = []
|
|
|
+ this.crossResult.forEach((item, index) => {
|
|
|
+ const height = parseFloat(item.height).toFixed(2)
|
|
|
+ const diameter = item.diameterStr
|
|
|
+ const depth = parseFloat(item.depth).toFixed(2)
|
|
|
+ if (index === 0) {
|
|
|
+ const value = parseFloat(item.distance).toFixed(2)
|
|
|
+ pipeInfoArea.push([
|
|
|
+ { name: value, label: { show: true, position: 'inside' }, coord: [0, splitTick + minYAxis] },
|
|
|
+ { coord: [item.distance, minYAxis] }
|
|
|
+ ])
|
|
|
+ pipeInfoArea.push([
|
|
|
+ { name: depth, label: { show: true, position: 'insideRight' }, coord: [0, splitTick * 2 + minYAxis] },
|
|
|
+ { coord: [item.distance, splitTick + minYAxis] }
|
|
|
+ ])
|
|
|
+ pipeInfoArea.push([
|
|
|
+ { name: diameter, label: { show: true, position: 'insideRight' }, coord: [0, splitTick * 3 + minYAxis] },
|
|
|
+ { coord: [item.distance, splitTick * 2 + minYAxis] }
|
|
|
+ ])
|
|
|
+ pipeInfoArea.push([
|
|
|
+ { name: height, label: { show: true, position: 'insideRight' }, coord: [0, splitTick * 4 + minYAxis] },
|
|
|
+ { coord: [item.distance, splitTick * 3 + minYAxis] }
|
|
|
+ ])
|
|
|
+ } else {
|
|
|
+ const value = (parseFloat(item.distance) - parseFloat(this.crossResult[index - 1].distance)).toFixed(2)
|
|
|
+ const preDistance = parseFloat(this.crossResult[index - 1].distance)
|
|
|
+ const distance = parseFloat(item.distance)
|
|
|
+ if (parseFloat(value) > 0) {
|
|
|
+ pipeInfoArea.push([
|
|
|
+ { name: value, label: { show: true, position: 'inside' }, coord: [preDistance, splitTick + minYAxis] },
|
|
|
+ { coord: [distance, minYAxis] }
|
|
|
+ ])
|
|
|
+ pipeInfoArea.push([
|
|
|
+ { name: depth, label: { show: true, position: 'insideRight' }, coord: [0, splitTick * 2 + minYAxis] },
|
|
|
+ { coord: [item.distance, splitTick + minYAxis] }
|
|
|
+ ])
|
|
|
+ pipeInfoArea.push([
|
|
|
+ {
|
|
|
+ name: diameter,
|
|
|
+ label: { show: true, position: 'insideRight' },
|
|
|
+ coord: [preDistance, splitTick * 3 + minYAxis]
|
|
|
+ },
|
|
|
+ { coord: [distance, splitTick * 2 + minYAxis] }
|
|
|
+ ])
|
|
|
+ pipeInfoArea.push([
|
|
|
+ {
|
|
|
+ name: height,
|
|
|
+ label: { show: true, position: 'insideRight' },
|
|
|
+ coord: [preDistance, splitTick * 4 + minYAxis]
|
|
|
+ },
|
|
|
+ { coord: [distance, splitTick * 3 + minYAxis] }
|
|
|
+ ])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ const image = new Image()
|
|
|
+ image.src = require('@/views/groupPage/images/sectionbg.png')
|
|
|
+ image.onload = () => {
|
|
|
+ const backData = [
|
|
|
+ [0, splitTick * 4 + minYAxis],
|
|
|
+ [maxXAxis, splitTick * 4 + minYAxis],
|
|
|
+ [maxXAxis, outRoadHeight],
|
|
|
+ [0, inRoadHeight]
|
|
|
+ ]
|
|
|
+
|
|
|
+ this._echart = echarts.init(this.$refs['pipeSectionPicture'])
|
|
|
+
|
|
|
+ const options = {
|
|
|
+ title: {
|
|
|
+ text: '地下管线横断面图',
|
|
|
+ left: 'center',
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ tooltip: { show: true },
|
|
|
+ toolbox: {
|
|
|
+ show: false,
|
|
|
+ feature: {
|
|
|
+ saveAsImage: {}
|
|
|
+ }
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ left: '15%',
|
|
|
+ bottom: 10,
|
|
|
+ right: '6%',
|
|
|
+ top: 30
|
|
|
+ },
|
|
|
+ backgroundcolor: 'transparent',
|
|
|
+ xAxis: {
|
|
|
+ name: '(m)',
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: maxXAxis,
|
|
|
+ splitLine: { show: false },
|
|
|
+ axisLabel: { show: false },
|
|
|
+ axisTick: { show: false }
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {
|
|
|
+ name: '高程(m)',
|
|
|
+ type: 'value',
|
|
|
+ min: minYAxis,
|
|
|
+ max: maxYAxis,
|
|
|
+ splitLine: { show: false },
|
|
|
+ axisLabel: {
|
|
|
+ inside: false,
|
|
|
+ //margin: -(-minXAxis / (maxXAxis - minXAxis)) * 862 + 8,
|
|
|
+ formatter: (value, index) => {
|
|
|
+ if (value >= splitTick * 4 + minYAxis) {
|
|
|
+ return value
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ dataZoom: [
|
|
|
+ {
|
|
|
+ type: 'inside',
|
|
|
+ filterMode: 'filter',
|
|
|
+ xAxisIndex: 0,
|
|
|
+ start: 0,
|
|
|
+ end: 100
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'custom',
|
|
|
+ silent: true,
|
|
|
+ animation: false,
|
|
|
+ zlevel: 0,
|
|
|
+ renderItem: (params, api) => {
|
|
|
+ if (params.context.rendered) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ params.context.rendered = true
|
|
|
+
|
|
|
+ var points = []
|
|
|
+ for (var i = 0; i < backData.length; i++) {
|
|
|
+ points.push(api.coord(backData[i]))
|
|
|
+ }
|
|
|
+ var color = api.visual('color')
|
|
|
+
|
|
|
+ return {
|
|
|
+ type: 'polygon',
|
|
|
+ transition: ['shape'],
|
|
|
+ shape: {
|
|
|
+ points: points
|
|
|
+ },
|
|
|
+ style: api.style({
|
|
|
+ fill: color,
|
|
|
+ stroke: echarts.color.lift(color)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ itemStyle: {
|
|
|
+ color: {
|
|
|
+ image: image,
|
|
|
+ repeat: 'no-repeat'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ clip: true,
|
|
|
+ data: backData
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '管点',
|
|
|
+ type: 'scatter',
|
|
|
+ zlevel: 4,
|
|
|
+ tooltip: {
|
|
|
+ formatter: (params) => {
|
|
|
+ return this.crossResult[params.dataIndex].title
|
|
|
+ }
|
|
|
+ },
|
|
|
+ markLine: {
|
|
|
+ symbol: ['none', 'none'],
|
|
|
+ silent: true,
|
|
|
+ animation: false,
|
|
|
+ lineStyle: {
|
|
|
+ type: 'solid',
|
|
|
+ color: '#696969',
|
|
|
+ width: 2
|
|
|
+ },
|
|
|
+ data: data.map((item) => {
|
|
|
+ return [
|
|
|
+ { name: '', coord: [item.value[0], minYAxis] },
|
|
|
+ { name: '', coord: [item.value[0], minYAxis + splitTick * 4] }
|
|
|
+ ]
|
|
|
+ })
|
|
|
+ },
|
|
|
+ data: data,
|
|
|
+ animation: false
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '距离标注',
|
|
|
+ type: 'scatter',
|
|
|
+ symbol: 'emptyCircle',
|
|
|
+ symbolSize: 1,
|
|
|
+ silent: true,
|
|
|
+ animation: false,
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'left',
|
|
|
+ formatter: '{b}',
|
|
|
+ fontWeight: 'bold',
|
|
|
+ fontSize: 14
|
|
|
+ },
|
|
|
+ markLine: {
|
|
|
+ symbol: ['none', 'none'],
|
|
|
+ label: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ lineStyle: {
|
|
|
+ normal: {
|
|
|
+ type: 'solid',
|
|
|
+ width: 2
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data: [
|
|
|
+ { yAxis: minYAxis },
|
|
|
+ { yAxis: splitTick + minYAxis },
|
|
|
+ { yAxis: splitTick * 2 + minYAxis },
|
|
|
+ { yAxis: splitTick * 3 + minYAxis },
|
|
|
+ { yAxis: splitTick * 4 + minYAxis }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ markArea: {
|
|
|
+ silent: true,
|
|
|
+ label: {
|
|
|
+ color: '#333'
|
|
|
+ },
|
|
|
+ itemStyle: {
|
|
|
+ color: 'transparent',
|
|
|
+ borderColor: '#ff0000',
|
|
|
+ borderWidth: 0
|
|
|
+ },
|
|
|
+ data: pipeInfoArea
|
|
|
+ },
|
|
|
+ data: [
|
|
|
+ { name: '间距(m)', value: [0, splitTick / 2 + minYAxis] },
|
|
|
+ { name: '埋深(m)', value: [0, splitTick * 1.5 + minYAxis] },
|
|
|
+ { name: '管径(mm)', value: [0, splitTick * 2.5 + minYAxis] },
|
|
|
+ { name: '地面高程(m)', value: [0, splitTick * 3.5 + minYAxis] }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '选中管线',
|
|
|
+ type: 'scatter',
|
|
|
+ zlevel: 3,
|
|
|
+ symbol: 'circle',
|
|
|
+ symbolSize: 1,
|
|
|
+ slient: true,
|
|
|
+ animation: false,
|
|
|
+ markLine: {
|
|
|
+ silent: true,
|
|
|
+ animation: false,
|
|
|
+ symbol: ['none', 'none'],
|
|
|
+ lineStyle: {
|
|
|
+ color: selectPipeColor,
|
|
|
+ type: 'solid',
|
|
|
+ width: selepipeLineSymbol
|
|
|
+ },
|
|
|
+ data: [[{ coord: [0, fromPoint.height] }, { coord: [maxXAxis, toPoint.height] }]]
|
|
|
+ },
|
|
|
+ data: [{ value: [0, maxHeight] }]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ this._echart.setOption(options)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ drawSectionInfo: {
|
|
|
+ handler(n, o) {
|
|
|
+ this.crossResult = n.crossResult
|
|
|
+ this.SelectPipe = n.SelectPipe
|
|
|
+ this.crossLinePoints = n.crossLinePoints
|
|
|
+ this.drawSectionPicture()
|
|
|
+ }
|
|
|
+ // deep:true
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style>
|
|
|
+</style>
|