| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673 |
- <template>
- <transition
- appear
- name="animate__animated animate__move"
- enter-active-class="animate__zoomIn"
- leave-active-class="animate__zoomOut"
- >
- <div class="widget-ProjectPipeSpeedInfoCheck" v-drag>
- <div class="header">
- <span class="close">
- <i class="el-icon-close" @click="close()" />
- </span>
- <el-select
- v-model="selectPrj"
- placeholder="请选择"
- :popper-append-to-body="false"
- size="small"
- filterable
- clearable
- @change="prjChange"
- >
- <el-option
- v-for="item in prjOptions"
- :key="item.name + item.code"
- :label="item.name + item.code"
- :value="item.name"
- >
- </el-option>
- </el-select>
- <div class="title">日期选择:</div>
- <el-date-picker
- style="width: 220px"
- :picker-options="pickerOptions"
- v-model="dateValue"
- type="datetimerange"
- range-separator="-"
- start-placeholder="开始日期"
- end-placeholder="结束日期"
- value-format="yyyy-MM-dd HH:mm:ss"
- :default-time="['00:00:00', '23:59:59']"
- size="mini"
- @change="dateChange"
- >
- </el-date-picker>
- </div>
- <div class="content" v-show="dateValue">
- <div class="left">
- <img class="operationBtn" :src="buttonImg" @click="play()" />
- </div>
- <div class="right">
- <el-steps :active="active" finish-status="success">
- <el-step :title="item[0].split(' ')[0]" v-for="(item, index) in timeSteps" :key="index"></el-step>
- </el-steps>
- </div>
- </div>
- </div>
- </transition>
- </template>
- <script lang="ts">
- import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
- import { pbsTreeList_api, GetProgress, PipeAndNodeProcess } from '@/api/APIs'
- import { queryMapByAttribute } from '@/views/groupPage/util'
- import _ from 'lodash'
- import config from '@/views/groupPage/districtPageModules/customTools/config.json'
- import pipeInfo from '@/views/groupPage/districtPageModules/customTools/infoComponents/pipeInfo.vue'
- const gPipe = config.gPipe
- const SuperMap = (window as any).SuperMap
- const Cesium = (window as any).Cesium
- let gCustomDataSource = null
- let gPrimitiveCollection = null
- let gPpostUpdate = undefined
- let gHandler = null
- //进度查看模块
- @Component({ name: 'ProjectPipeSpeedInfoCheck' })
- export default class ProjectPipeSpeedInfoCheck extends Vue {
- viewer
- apiurls = {
- sjfw: '',
- smiddtfw: ''
- }
- pipeInfo = null
- prjOptions = []
- selectPrj: string = ''
- //时间戳值
- active: number = 0
- //播放变量
- buttonImg = ''
- playButtonImg = require('@/views/groupPage/images/工具栏/play.png')
- pauseButtonImg = require('@/views/groupPage/images/工具栏/stop.png')
- isPlaying = false
- isShowCompletion = false
- //日期控件
- dateValue = ''
- pickerOptions = {
- shortcuts: [
- {
- text: '最近一周',
- onClick(picker) {
- const end = new Date()
- const start = new Date()
- start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
- picker.$emit('pick', [start, end])
- }
- },
- {
- text: '最近一个月',
- onClick(picker) {
- const end = new Date()
- const start = new Date()
- start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
- picker.$emit('pick', [start, end])
- }
- },
- {
- text: '最近三个月',
- onClick(picker) {
- const end = new Date()
- const start = new Date()
- start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
- picker.$emit('pick', [start, end])
- }
- }
- ]
- }
- //
- timeSteps: Array<string> = []
- //播放监听
- @Watch('isPlaying', { immediate: true })
- activeChangeMethod(val) {
- this.buttonImg = val ? this.pauseButtonImg : this.playButtonImg
- }
- get mapConfig() {
- return this.$store.state.bigScreen.mapConfig
- }
- mounted() {
- this.viewer = (window as any).viewer
- this.init()
- this.initPrjInfo()
- }
- //初始化数据服务地址
- init() {
- this.apiurls.sjfw = this.mapConfig.gisResource.tiplayers.config['sjfw'].url
- this.apiurls.smiddtfw = this.mapConfig.gisResource.tiplayers.config['bjsmidfw'].url
- gCustomDataSource = new Cesium.CustomDataSource('displaycontrol')
- this.viewer.dataSources.add(gCustomDataSource)
- }
- // 获取树状结构列表
- async initPrjInfo() {
- let res = await pbsTreeList_api({ prjId: 45 })
- let { result } = res
- this.prjOptions = result[0].structures.filter(
- (item) => item.levelname !== '分部工程(专业)' && item.levelname !== '部件类型'
- )
- }
- //开始播放
- play() {
- this.isPlaying = !this.isPlaying
- if (this.isPlaying) {
- this.loopPlayback()
- } else {
- }
- }
- @Watch('isShowCompletion')
- onchangeMethod(n, o) {
- if (n && this.isPlaying) {
- this.loopPlayback()
- }
- }
- loopPlayback() {
- //长度减一是因为timeSteps存储的是时间间隔
- if (this.active > this.timeSteps.length - 1) {
- this.active = 0
- }
- this.isShowCompletion = false
- const start = this.timeSteps[this.active][0]
- const end = this.timeSteps[this.active][1]
- const data2 = {
- beginDate: start.replaceAll('-', ''),
- endDate: end.replaceAll('-', '')
- }
- this.clearSpeedInfos()
- setTimeout(() => {
- this.initScanTimes(data2)
- this.active += 1
- }, 500)
- }
- prjChange() {
- this.clearSpeedInfos()
- this.initScanTimes({ queryText: this.selectPrj })
- }
- //时间改变
- dateChange() {
- if (!this.dateValue) {
- this.active = 0
- this.isPlaying = false
- this.clearSpeedInfos()
- return
- } else {
- this.splitTime()
- const start = this.dateValue[0]
- const end = this.dateValue[1]
- const data2 = {
- queryText: this.selectPrj,
- beginDate: start.replaceAll('-', ''),
- endDate: end.replaceAll('-', '')
- }
- this.clearSpeedInfos()
- this.initScanTimes(data2)
- // this.showSpeedInfos(start, end)
- }
- }
- //时间分割函数
- splitTime() {
- let start = this.dateValue[0]
- let end = this.dateValue[1]
- const startTime = start.split(' ')[0]
- const endTime = end.split(' ')[0]
- const intervalDay = (getDate(endTime).getTime() - getDate(startTime).getTime()) / (1000 * 60 * 60 * 24)
- if (intervalDay >= 1) {
- let timeArr = formatEveryDay(startTime, endTime)
- this.timeSteps = group(timeArr, 2)
- }
- function formatEveryDay(s, e) {
- let dateList = []
- let startTimeC = getDate(s)
- let endTimeC = getDate(e)
- while (endTimeC.getTime() - startTimeC.getTime() >= 0) {
- let year = startTimeC.getFullYear()
- let month = startTimeC.getMonth() + 1 < 10 ? '0' + (startTimeC.getMonth() + 1) : startTimeC.getMonth() + 1
- let day = startTimeC.getDate().toString().length == 1 ? '0' + startTimeC.getDate() : startTimeC.getDate()
- dateList.push(year + '-' + month + '-' + day + ' ' + start.split(' ')[1])
- startTimeC.setDate(startTimeC.getDate() + 1)
- }
- dateList[dateList.length - 1] = endTime + ' ' + end.split(' ')[1]
- return dateList
- }
- function getDate(datestr) {
- let temp = datestr.split('-')
- let date = new Date(temp[0], temp[1] - 1, temp[2])
- return date
- }
- function group(array, subGroupLength) {
- let index = 0
- let newArray = []
- while (index < array.length - 1) {
- newArray.push(array.slice(index, index + subGroupLength))
- index += 1
- }
- return newArray
- }
- }
- //进度信息查询
- initScanTimes(dateRange) {
- const pipe = gPipe
- const that = this
- const fieldName = 'CODE'
- const geourl = this.apiurls.smiddtfw
- PipeAndNodeProcess(dateRange)
- .then((result) => {
- console.log(result)
- if (result.code !== 1 || result.result.length === 0) {
- that.isShowCompletion = true
- return
- }
- const filters = []
- const cwpInfos = []
- const len = result.result.length
- for (let i = 0; i < len; i++) {
- const item = result.result[i]
- const pipename = item.firstLayerName.split(',')[0]
- const layer = _.find(pipe, function (pipeItem) {
- return pipeItem.origindataset === pipename
- })
- if (!layer) {
- continue
- }
- //组装
- let cwpInfo = {
- name: '',
- roadName: '',
- code: '',
- dateRange: '',
- design: {
- name: '',
- total: 0,
- pipe: 0,
- node: 0
- },
- spv: {
- name: '',
- pipeLen: 0,
- times: 0,
- part: 0,
- pictures: 0
- },
- con: {
- name: '',
- pipeLen: 0,
- times: 0,
- part: 0,
- pictures: 0,
- totalLen: 0
- }
- }
- cwpInfo.dateRange = dateRange.beginDate + '~' + dateRange.endDate
- cwpInfo.code = item.firstPbs
- cwpInfo.name = item.zdwName
- cwpInfo.roadName = item.roadName
- //设计
- const design = _.find(item.tjData, (djData) => {
- return djData.dataType === 'DESIGN'
- })
- if (design) {
- cwpInfo.design.name = design.designUnit
- cwpInfo.design.total = design.tfPipeLength
- cwpInfo.design.pipe = design.tfPipeCount
- cwpInfo.design.node = design.tfNodeCount
- }
- //施工
- const con = _.find(item.tjData, (djData) => {
- return djData.dataType === 'CON'
- })
- if (con) {
- cwpInfo.con.name = con.buildUnit
- cwpInfo.con.pipeLen = con.smLength
- cwpInfo.con.times = con.scanTimes
- cwpInfo.con.part = con.partsTotal
- cwpInfo.con.pictures = con.pictures
- cwpInfo.con.totalLen = con.builtLength
- }
- //监理
- const spv = _.find(item.tjData, (djData) => {
- return djData.dataType === 'SPV'
- })
- if (spv) {
- cwpInfo.spv.name = spv.supervisionUnit
- cwpInfo.spv.pipeLen = spv.smLength
- cwpInfo.spv.times = spv.scanTimes
- cwpInfo.spv.part = spv.partsTotal
- cwpInfo.spv.pictures = spv.pictures
- }
- cwpInfos.push(cwpInfo)
- //多图层搜索
- const queryname = layer.smidmapnameNT ? layer.smidmapnameNT : layer.smidmapname
- const JGFilter = new SuperMap.REST.FilterParameter({
- name: queryname,
- attributeFilter: fieldName + " = '" + item['firstPbs'] + "'",
- fields: [fieldName]
- })
- filters.push(JGFilter)
- }
- const onComplete = function (geoResult) {
- console.log('地图查询结果', geoResult)
- //交互事件
- that.getCurrentInfo()
- geoResult.originResult.recordsets.forEach((record) => {
- const features = record.features
- if (features.length > 1) {
- console.log('pbs重复')
- return true
- }
- if (features.length == 0) {
- return true
- }
- const scanProj = _.find(cwpInfos, function (scanItem) {
- return scanItem.code === features[0]['fieldValues'][0]
- })
- let labelText = dateRange.beginDate + '~' + dateRange.endDate
- let position = features[0].geometry.points[0]
- position = Cesium.Cartesian3.fromDegrees(position.x, position.y, position.z)
- that.addUnitBillboard({
- id: scanProj.code,
- name: scanProj.code,
- text: labelText,
- position: position,
- scanProj: scanProj
- })
- })
- that.isShowCompletion = true
- }
- queryMapByAttribute({
- url: geourl,
- filterParameters: filters,
- completed: onComplete.bind(this),
- failed: function (err) {
- console.log(err)
- }
- })
- })
- .catch((err) => {
- console.log(err)
- })
- }
- /**
- * 该方法用于生成部件定位指示牌
- * @param options entity信息
- * @param options.id entity ID
- * @param options.text 站点信息
- * @param options.name 站点信息
- * @param options.position 位置
- */
- addUnitBillboard(options) {
- var bottomPosition = Cesium.Cartographic.fromCartesian(options.position)
- var topPosition = Cesium.Cartographic.fromRadians(
- bottomPosition.longitude,
- bottomPosition.latitude,
- bottomPosition.height + 40
- )
- var bPosition = Cesium.Cartographic.toCartesian(bottomPosition)
- var tPosition = Cesium.Cartographic.toCartesian(topPosition)
- options.text =
- options.scanProj.roadName + '(' + options.scanProj.con.pipeLen + 'm,' + options.scanProj.con.part + '个)'
- var color = 'rgb(56, 136, 205)'
- var canvas = document.createElement('canvas')
- const ratio = 2.0
- let height = 50
- const realHeight = 48
- //临时数值
- let width = 100
- canvas.width = width * ratio
- canvas.height = height * ratio
- const fonttxt = '50px Arial'
- var ctx = canvas.getContext('2d')
- //ctx.scale(ratio, ratio)
- var img = new Image()
- img.src = require('@/views/groupPage/images/back.png')
- img.onload = function () {
- ctx.lineWidth = 10
- ctx.strokeStyle = color
- ctx.font = '24px Arial'
- const realWidth = ctx.measureText(options.text).width
- ctx.font = fonttxt
- width = ctx.measureText(options.text).width + 100
- canvas.width = width
- ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
- ctx.font = fonttxt
- ctx.fillStyle = 'rgb(255,255,255)'
- ctx.textBaseline = 'middle'
- ctx.fillText(options.text, 50, height)
- //ctx.fillText(options.text, (canvas.width - width) / 2, (canvas.height + 15) / 2);
- var entity = new Cesium.Entity({
- id: options.id,
- name: options.name,
- show: true,
- position: Cesium.Cartographic.toCartesian(topPosition),
- polyline: {
- positions: [bPosition, tPosition],
- material: Cesium.Color.fromBytes(56, 136, 205, 255),
- width: 3
- },
- billboard: {
- sizeInMeters: false,
- image: canvas,
- //scale:0.2,
- width: realWidth,
- height: realHeight,
- scaleByDistance: new Cesium.NearFarScalar(10000, 1.0, 10100, 0.5),
- verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
- horizontalOrigin: Cesium.HorizontalOrigin.CENTER
- }
- })
- entity.displayData = options.scanProj
- if (!gCustomDataSource.entities.getById(options.id)) {
- gCustomDataSource.entities.add(entity)
- }
- }
- }
- /**
- * 获取当前情况
- */
- getCurrentInfo() {
- const pipeInfoConstructor = Vue.extend(pipeInfo)
- const that = this
- if (!this.pipeInfo) {
- this.pipeInfo = new pipeInfoConstructor({
- store: this.$store
- }).$mount()
- }
- this.removeLabels()
- gHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas)
- gHandler.setInputAction(
- function (movement) {
- var pickedObject = this.viewer.scene.pick(movement.endPosition)
- // 使用时,最好利用pickPositionSupported判断一下浏览器是否支持模型高度拾取
- if (this.viewer.scene.pickPositionSupported && Cesium.defined(pickedObject)) {
- let info = pickedObject.id
- if (info && info.displayData) {
- this.pipeInfo.$set(this.pipeInfo, 'displayData', info.displayData)
- this.pipeInfo.$set(this.pipeInfo, 'isShow', true)
- this.pipeInfo.$refs['widget-pipeInfo'].style.setProperty('--left', `${movement.endPosition.x}px`)
- this.pipeInfo.$refs['widget-pipeInfo'].style.setProperty('--top', `${movement.endPosition.y}px`)
- }
- } else {
- this.pipeInfo.$set(this.pipeInfo, 'isShow', false)
- }
- }.bind(this),
- Cesium.ScreenSpaceEventType.MOUSE_MOVE
- )
- }
- //清除进度信息
- clearSpeedInfos() {
- this.viewer.scene.layers.releaseSelection()
- this.removeLabels()
- this.clearPrimitives()
- // if (gPpostUpdate) {
- // gPpostUpdate()
- // gPpostUpdate = undefined
- // }
- }
- //该方法用于清除entity label
- removeLabels() {
- if (Cesium.defined(gCustomDataSource)) {
- gCustomDataSource.entities.removeAll()
- }
- this.otherDestroy()
- }
- otherDestroy() {
- if (gHandler != null && !gHandler.isDestroyed()) {
- gHandler.destroy()
- }
- }
- //该方法用于清除primitivecollection
- clearPrimitives() {
- if (gPrimitiveCollection) {
- gPrimitiveCollection.removeAll()
- const isDel = this.viewer.scene.primitives.remove(gPrimitiveCollection)
- if (isDel) gPrimitiveCollection = null
- }
- }
- close() {
- this.$store.state.bigScreen.isShowPipeSpeedInfoCheck = false
- if (this.pipeInfo) {
- this.pipeInfo.remove()
- }
- this.clearSpeedInfos()
- }
- }
- </script>
- <style lang='scss' scoped>
- .animate__zoomIn,
- .animate__zoomOut {
- animation-duration: 1s; //动画持续时间
- animation-delay: 0s; //动画延迟时间
- }
- .widget-ProjectPipeSpeedInfoCheck {
- bottom: 0.520833rem /* 100/192 */;
- left: calc(50% - 1.5625rem);
- // margin-left: -1.5625rem /* 300/192 */;
- width: 3.125rem /* 600/192 */;
- height: 0.833333rem /* 160/192 */;
- position: absolute;
- font-family: Source Han Sans CN;
- z-index: 999;
- //
- background: rgba(0, 60, 98, 0.7);
- border-radius: 4px;
- .header {
- width: 100%;
- height: 0.208333rem /* 40/192 */;
- border-bottom: 1px solid rgba(41, 177, 255, 0.3);
- display: flex;
- align-items: center;
- /deep/ .el-select {
- width: 100px;
- .el-input__inner {
- background-color: transparent;
- border: none;
- font-size: 0.072917rem /* 14/192 */;
- font-family: Source Han Sans CN;
- font-weight: 500;
- color: #2ba7ff;
- position: relative;
- }
- .el-icon-arrow-up:before {
- content: '';
- display: block;
- // 定义元素宽高
- margin-top: 0.041667rem /* 8/192 */;
- width: 0.130208rem /* 25/192 */;
- height: 0.078125rem /* 15/192 */;
- background: url('~@/views/groupPage/images/三角下.png') no-repeat center center;
- background-size: 100% 100%;
- transform: rotate(180deg);
- }
- }
- .close {
- position: absolute;
- right: 0.052083rem /* 10/192 */;
- color: #a3d3ff;
- font-size: 0.083333rem /* 16/192 */;
- z-index: 10;
- cursor: pointer;
- }
- .title {
- font-family: Source Han Sans CN;
- font-size: 0.072917rem /* 14/192 */;
- color: #2ba7ff;
- }
- }
- .content {
- width: 100%;
- height: calc(100% - 0.208333rem /* 40/192 */);
- display: flex;
- .left {
- width: 0.572917rem /* 110/192 */;
- height: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- .operationBtn {
- cursor: pointer;
- width: 0.255208rem /* 49/192 */;
- height: 0.255208rem /* 49/192 */;
- }
- }
- .right {
- width: calc(100% - 0.572917rem /* 110/192 */);
- height: 100%;
- padding: 0.052083rem /* 10/192 */;
- display: flex;
- align-items: flex-end;
- overflow-y: auto;
- /deep/ .el-steps {
- width: 100%;
- .el-step__icon-inner {
- color: transparent;
- }
- .el-step__line {
- top: 0.03125rem /* 6/192 */;
- height: 0.020833rem /* 4/192 */;
- background: #0ea7ff;
- }
- .el-step__head.is-success {
- .el-step__icon.is-text {
- width: 0.083333rem /* 16/192 */;
- height: 0.083333rem /* 16/192 */;
- border: 3px solid #04eaff;
- box-shadow: 0 0 5px #04eaff;
- }
- }
- .el-step__title.is-success {
- font-family: Source Han Sans CN;
- font-size: 0.0625rem /* 12/192 */;
- font-weight: 500;
- color: #04eaff;
- padding: 0 0.026042rem /* 5/192 */;
- white-space: nowrap;
- }
- .el-step__head.is-wait .el-step__icon.is-text,
- .el-step__head.is-process .el-step__icon.is-text {
- width: 0.083333rem /* 16/192 */;
- height: 0.083333rem /* 16/192 */;
- border: 3px solid #0ea7ff;
- }
- .el-step__title.is-process,
- .el-step__title.is-wait {
- font-size: 0.0625rem /* 12/192 */;
- font-family: Source Han Sans CN;
- font-weight: 500;
- color: #ffffff;
- padding: 0 0.026042rem /* 5/192 */;
- white-space: nowrap;
- }
- }
- }
- }
- }
- </style>
|