guanqb
2023-04-12 3d0eb36471cfc8f6e3e72d10600be4e255e3db13
视频巡逻路线分割、新增路线、一分钟播放路线
3 files modified
301 ■■■■ changed files
src/views/activity/components/publicIndex.vue 1 ●●●● patch | view | raw | blame | history
src/views/activity/components/videoControlBox.vue 7 ●●●● patch | view | raw | blame | history
src/views/video/region.vue 293 ●●●● patch | view | raw | blame | history
src/views/activity/components/publicIndex.vue
@@ -18,7 +18,6 @@
        <polyline-plot ref="PolylinePlotPage" :showingSecurityId="showingSecurityId"></polyline-plot>
        <police-car-change ref="PoliceCarChange" :policeOption="policeOption"
            :showingSecurityId="showingSecurityId"></police-car-change>
src/views/activity/components/videoControlBox.vue
@@ -179,6 +179,8 @@
    mounted () {
        this.$nextTick(() => {
            tc = new global.DC.TrackController(global.viewer)
        })
    },
@@ -188,18 +190,19 @@
         * @return {*}
         */
        watchVideo (linePosition, polygonPosition) {
            const that = this
            const line = this.$turf.lineString(linePosition.split(';').filter(item => item != '').map(item => item.split(',').map(i => Number(i))))
            // const lineLength = this.$turf.length(line) * 1000
            const chunkLine = this.$turf.lineChunk(line, 0.1)
            console.log('chunkLine', chunkLine)
            let arr = chunkLine.features.reduce((pre, cur) =>
                pre.concat(cur.geometry.coordinates)
                , []).map(item => item.join(','))
            const time = arr.filter(item => arr.indexOf(item) == arr.lastIndexOf(item)).length * 16
            const newPostion = arr.filter((item, index) => index == arr.lastIndexOf(item)).join(';')
            console.log('arr', arr, 'time', time, 'newPostion', newPostion)
            this.getRegionList(polygonPosition)
            this.videoShow = true
src/views/video/region.vue
@@ -18,6 +18,11 @@
                    <input v-model="searchValue" @input="searchChange" type="text" placeholder="请输入搜索条件" />
                    <button @click="searchClick" class="el-icon-search"></button>
                </div>
                <div class="draw-btn">
                    新增路线:
                    <el-button type="primary" size="mini" @click="draw('polyline')">新增路线</el-button>
                    <el-button type="primary" size="mini" @click="removeDrawLayer">清除</el-button>
                </div>
                <div v-show="true" class="search-val-box">
                    <div @click="searchVlaClick(item)" v-for="(item, index) in searchArray" :key="index">{{ item.name }}
@@ -35,9 +40,9 @@
                                <el-table-column prop="name" label="范围名称" min-width="50%"></el-table-column>
                                <el-table-column prop="extent" label="长度km/面积㎡" min-width="50%">
                                    <!-- <template slot-scope="scope">
                                                                                                <span>{{ scope.row.extent }}</span>
                                                                                                <span>千米</span>
                                                                                            </template>-->
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <span>{{ scope.row.extent }}</span>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <span>千米</span>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </template>-->
                                </el-table-column>
                                <el-table-column prop="id" label="操作" min-width="50%">
                                    <template slot-scope="scope">
@@ -260,19 +265,46 @@
                <el-button @click="editRangeVisible = false">取消</el-button>
            </div>
        </el-dialog>
        <el-dialog title="新增路线" :modal="false" :visible.sync="drawDialogVisible" :before-close="drawDialogBeforeClose"
            :close-on-click-modal="true" class="video-draw-box">
            <div>
                <div>名称:</div>
                <input type="text" v-model="drawName" placeholder="请输入绘制线的名称" />
            </div>
            <div>
                <div>范围:</div>
                <input type="text" v-model="range" placeholder="请输入绘制线的范围" />
            </div>
            <div class="line">
                <div class="value-name-box">颜色:</div>
                <div class="pick-color-box">
                    <el-color-picker v-model="chooseAddRangeColor" :predefine="predefineColors" size="small">
                    </el-color-picker>
                </div>
            </div>
            <div>
                <button @click="saveDrawInfo">保存</button>
                <button @click="cancelSaveDrawInfo">取消</button>
            </div>
        </el-dialog>
    </div>
</template>
<script>
import EntityDraw from "@/utils/EntityDraw.js"
import { listQuery, accurateSearch } from "@/utils/search.js"
import { getVideoList, getDevices, getRegionSaveList, deleteRegionSaveList, getRegionList, updataRegionSaveList } from '@/api/video/index.js'
import { getVideoList, getDevices, getRegionSaveList, deleteRegionSaveList, getRegionList, updataRegionSaveList, insertRegionSaveList, getRegionListAll } from '@/api/video/index.js'
import flvjs from 'flv.js'
// let graphicLayer = null
let rangeLayer = null
let rangeLineLayer = null
let drawPlotLayers = null
let plot = undefined
let drwaPlot = undefined
let videoTimer = null
let videoLineIndex = -1
import { initMapPosition } from '@/utils/mapPositionInit'
@@ -281,6 +313,7 @@
    data () {
        return {
            drawDialogVisible: false,
            currentPage: 1,
            pagesize: 13,
            pagesCount: 1,
@@ -358,6 +391,7 @@
                video8: false,
            },
            chooseRangeColor: '#FF0000',
            chooseAddRangeColor: '#FF0000',
            editRangeVisible: false,
            lineWidth: '',
            rangeOverlayData: {},
@@ -379,6 +413,7 @@
                'hsla(209, 100%, 56%)',
                '#c7158577'
            ],
            drawType: 1,
        }
    },
@@ -405,6 +440,13 @@
            if (rangeLineLayer == null) {
                rangeLineLayer = new global.DC.VectorLayer('rangeLineLayer')
                global.viewer.addLayer(rangeLineLayer)
            }
            if (drawPlotLayers == null) {
                drawPlotLayers = new global.DC.VectorLayer('drawPlotLayers')
                global.viewer.addLayer(drawPlotLayers)
                drwaPlot = new global.DC.Plot(global.viewer, {
                    clampToModel: true
                })
            }
        })
@@ -549,14 +591,13 @@
            }
            this.saveRangeList.forEach(item => {
                console.log(item, 656565656)
                let positionStr = ''
                if (item.type == 1) {
                    let linePositionStr = ''
                    linePositionStr = item.positions.replace(/,/g, ';')
                    linePositionStr = linePositionStr.replace(/ /g, ',')
                    linePositionStr += ';'
                    let coords = global.DC.GeoTools.polylineBuffer(linePositionStr, 100)
                    let coords = global.DC.GeoTools.polylineBuffer(linePositionStr, item.width)
                    let polygon = new global.DC.Polygon(coords)
                    let position = ''
                    polygon._positions.forEach(item => {
@@ -707,6 +748,7 @@
        initMonitoringIcon () {
            this.monitoringList.forEach((item, index) => {
                let iconUrl = item.status == 0 ? '/img/icon/video-off.png' : '/img/icon/video.png'
                this.$EventBus.$emit('layerPointAdd', {
                    layerName: 'monitoringLayers',
                    type: "billboard",
@@ -715,7 +757,7 @@
                        lng: item.longitude,
                        lat: item.latitude,
                        alt: 1,
                        url: '/img/icon/video.png',
                        url: iconUrl,
                        // deviceId: item.deviceId
                    },
                    // incident: this.siteClick
@@ -754,6 +796,8 @@
                    type: 'VectorLayer'
                })
            } else {
                clearInterval(videoTimer)
                this.isShowVideo = {
                    video1: false,
                    video2: false,
@@ -781,7 +825,6 @@
                        id: row.id
                    }).then(res => {
                        let monitorData = res.data.data.list
                        this.monitoringList = res.data.data.list
                        this.$EventBus.$emit('mapRemoveLayer', {
                            layerName: 'monitoringLayers',
@@ -815,46 +858,20 @@
                    let positionStr = row.positions.replace(/,/g, ';')
                    positionStr = positionStr.replace(/ /g, ',')
                    positionStr += ';'
                    let coords = global.DC.GeoTools.polylineBuffer(positionStr, row.width)
                    let polygon = new global.DC.Polygon(coords)
                    let position = ''
                    polygon._positions.forEach(item => {
                        position += item._lng + ',' + item._lat + ';'
                    let positionArr = positionStr.slice(0, positionStr.length - 1).split(';')
                    let positionNewArr = []
                    positionArr.forEach(item => {
                        positionNewArr.push([Number(item.split(',')[0]), Number(item.split(',')[1])])
                    })
                    getRegionList({
                        page: 1,
                        count: 20,
                        range: position
                    }).then(res => {
                        let monitorData = res.data.data.list
                    // 按距离获取路线划分块
                    let videoLine = this.$turf.lineString(positionNewArr)
                    let videoChunk = this.$turf.lineChunk(videoLine, 0.1, { units: 'kilometers' })
                    videoLineIndex = -1
                    this.initVideoLineFrag(videoChunk, row)
                    videoTimer = setInterval(() => {
                        this.initVideoLineFrag(videoChunk, row)
                    }, 60000)
                        this.monitoringList = res.data.data.list
                        this.$EventBus.$emit('mapRemoveLayer', {
                            layerName: 'monitoringLayers',
                            type: 'VectorLayer'
                        })
                        this.initMonitoringIcon()
                        this.monitorOption = []
                        monitorData.forEach((item, index) => {
                            this.monitorOption.push({ value: index, label: item.name, item })
                            if (index < 8) {
                                const ind = index + 1
                                this.isShowVideo[`video${ind}`] = true
                                this.monitor[`type${ind}`] = item.name
                                if (item.status == 0) {
                                    this.isShowOutline[`video${ind}`] = true
                                }
                                this.getDevices(item.channelId).then(res => {
                                    this.playVideoList(`flvPlayer${ind}`, `${res}`, `videoElement${ind}`, `${ind}`)
                                })
                            }
                        })
                    })
                }
            }
@@ -889,6 +906,62 @@
        //         this.flvPlayer.play()
        //     }
        // },
        initVideoLineFrag (videoChunk, row) {
            videoLineIndex++
            if (videoLineIndex == videoChunk.features.length) {
                clearInterval(videoTimer)
            }
            let positionStr = ''
            let positionArr = videoChunk.features[videoLineIndex].geometry.coordinates
            positionArr.forEach(item => {
                positionStr += item[0] + ',' + item[1] + ';'
            })
            let point1 = this.$turf.point(positionArr[0])
            let point2 = this.$turf.point(positionArr[1])
            let midpoint = this.$turf.midpoint(point1, point2).geometry.coordinates
            console.log('midpoint', midpoint)
            this.$EventBus.$emit('toPosition', {
                siteJd: midpoint[0],
                siteWd: midpoint[1],
                siteGd: 5000,
            })
            let coords = global.DC.GeoTools.polylineBuffer(positionStr, row.width)
            let polygon = new global.DC.Polygon(coords)
            let position = ''
            polygon._positions.forEach(item => {
                position += item._lng + ',' + item._lat + ';'
            })
            getRegionListAll({
                range: position
            }).then(res => {
                let monitorData = res.data.data.filter(item => { return item.status == 1 })
                this.monitoringList = res.data.data
                this.$EventBus.$emit('mapRemoveLayer', {
                    layerName: 'monitoringLayers',
                    type: 'VectorLayer'
                })
                this.initMonitoringIcon()
                this.monitorOption = []
                monitorData.forEach((item, index) => {
                    this.monitorOption.push({ value: index, label: item.name, item })
                    if (index < 8) {
                        const ind = index + 1
                        this.isShowVideo[`video${ind}`] = true
                        this.monitor[`type${ind}`] = item.name
                        if (item.status == 0) {
                            this.isShowOutline[`video${ind}`] = true
                        }
                        this.getDevices(item.channelId).then(res => {
                            this.playVideoList(`flvPlayer${ind}`, `${res}`, `videoElement${ind}`, `${ind}`)
                        })
                    }
                })
            })
        },
        dialogBeforeClose () {
            this.dialogVisible = false
@@ -976,6 +1049,112 @@
            }
        },
        // 绘制新增路线
        draw (type) {
            this.drawType = 1
            drwaPlot && drwaPlot.draw(type, overlay => {
                if (overlay) {
                    drawPlotLayers.addOverlay(overlay)
                    drwaPlot.edit(overlay)
                    if (overlay) {
                        drawPlotLayers.addOverlay(overlay)
                        drwaPlot.edit(overlay, (e) => {
                            this.drawDialogVisible = true
                            this.range = 100
                            this.drawPlotData = overlay
                            document.oncontextmenu = function () {
                                return false
                            }
                            // this.getRegionList(type, overlay)
                        })
                    }
                }
            }, { material: global.DC.Color.RED })
        },
        // 清楚绘制图层
        removeDrawLayer () {
            if (drawPlotLayers != null) {
                drawPlotLayers.clear()
            }
        },
        // 保存绘制的线面
        saveDrawInfo () {
            if (this.drawName == '') {
                this.$message({
                    message: '请输入名称',
                    type: 'error'
                })
            } else {
                let drawPositionStr = ''
                let extent = 0
                if (this.drawType == 1) {
                    // 获取线坐标
                    this.drawPlotData._positions.forEach(item => {
                        drawPositionStr += item._lng + ' ' + item._lat + ','
                    })
                    drawPositionStr = drawPositionStr.slice(0, drawPositionStr.length - 1)
                    // 求线长度
                    let linePosition = []
                    this.drawPlotData._positions.forEach(item => {
                        linePosition.push([item._lng, item._lat])
                    })
                    let line = this.$turf.lineString(linePosition)
                    let length = this.$turf.length(line, { units: 'kilometers' })
                    extent = length.toFixed(3)
                }
                this.insertRegionSaveList({ type: this.drawType, positions: drawPositionStr, name: this.drawName, extent: extent, width: this.range, color: this.chooseAddRangeColor })
                this.drawDialogVisible = false
                this.drawName = ''
                if (drawPlotLayers != null) {
                    drawPlotLayers.clear()
                }
                // this.$EventBus.$emit('mapRemoveLayer', {
                //     layerName: 'monitoringLayers',
                //     type: 'VectorLayer'
                // })
            }
        },
        // 关闭新增路线弹窗
        drawDialogBeforeClose () {
            this.drawName = ''
            if (drawPlotLayers != null) {
                drawPlotLayers.clear()
            }
            this.$EventBus.$emit('mapRemoveLayer', {
                layerName: 'monitoringLayers',
                type: 'VectorLayer'
            })
            this.drawDialogVisible = false
        },
        // 取消绘制线面
        cancelSaveDrawInfo () {
            this.drawDialogBeforeClose()
        },
        // type线面类型, positions坐标, name名称, width线宽度, extent线长度或面面积
        insertRegionSaveList (parmas) {
            insertRegionSaveList(parmas).then(res => {
                if (res.data.success) {
                    this.$message({
                        message: '保存成功',
                        type: 'warning'
                    })
                    this.getRegionSaveList(this.currentPage, this.pagesize, this.userInfo.dept_id)
                } else {
                    this.$message({
                        message: '保存失败'
                    })
                }
            })
        },
        //#region
        // enterVideoBox (num) {
@@ -1056,6 +1235,10 @@
            this.flvPlayer.destroy()
            this.flvPlayer = null
        }
        this.removeDrawLayer()
        clearInterval(videoTimer)
    }
}
@@ -1148,6 +1331,24 @@
                }
            }
            .draw-btn {
                margin: 8px;
                margin-top: 0;
                display: flex;
                align-items: center;
                justify-content: space-around;
                height: 26px;
                .el-button {
                    flex: 1;
                }
                :deep(.el-button--primary) {
                    background-color: #1d5ce4;
                    border-color: #1d5ce4;
                }
            }
            .list-show {
                flex: 1;