<!-- * @Description: 双创地图 * @Author: 王晓颖 * @Date: 2020-09-09 10:18:08 --> <template> <div style="width: 100%; height:100%"> <div style="width:100%; height:100%;position:relative"> <f-map :type="type" :plugins="plugins" :layers="layers" @ready="mapReady"> <f-map-features :data="boundaryData" type="ArcgisPolygon" geoField="geo" layer="boundary"/> <f-map-features :data="roads" type="Polygon" geoField="geo" layer="roads" :visible="layersShow.roadShow"/> <!--人员--> <!--<f-map-features :data="peopleData" x="longitude" y="latitude" :visible="peopleShow" layer="volunteers"/>--> <f-map-features :data="peopleData" x="longitude" y="latitude" :visible="layersShow.peopleShow" layer="volunteer"/> <!--三种类型的案件--> <f-map-features :data="caseWaitData" x="longitude" y="latitude" :visible="layersShow.caseShow" layer="caseWait"/> <f-map-features :data="caseHandleData" x="longitude" y="latitude" :visible="layersShow.caseShow" layer="caseHandle"/> <f-map-features :data="caseOvertimeData" x="longitude" y="latitude" :visible="layersShow.caseShow" layer="caseOvertime"/> <!--摄像头--> <!--<f-map-features :data="cameraData" x="X" y="Y" :visible="layersShow.cameraShow" layer="boxCamera"/>--> <!--<f-map-features :data="cameraData" x="X" y="Y" :visible="layersShow.cameraShow" layer="boxCamera"/>--> <f-map-features :data="videoChannels" x="gpsX" y="gpsY" :visible="layersShow.cameraShow" layer="boxCamera"/> </f-map> <!--切换图层按钮区域--> <div style="position:absolute;top:20px;right:20px;z-index:100"> <button1 v-model="layersShow.roadShow" @click.native="layersShow.roadShow=!layersShow.roadShow">网格</button1> <button1 v-model="layersShow.cameraShow" @click.native="showCameras">摄像头</button1> <button1 v-model="layersShow.peopleShow" @click.native="showShuangChuang">人员</button1> <button1 v-model="layersShow.caseShow" @click.native="showCase">事件</button1> </div> <!-- 统计面板--> <camera :raw-data="cameraStaticData" v-if="layersShow.cameraShow"/> <people v-if="layersShow.peopleShow"/> <case v-if="layersShow.caseShow"/> <!-- 视频播放器 --> <div v-show="videosShow" class="videoBox"> <div class="videoBox-subBox" v-show="videoShow1"> <span class="videoClose" @click="videoShow1 = false;videoUrl = '';">关闭</span> <div class="prism-player" id="player-con"></div> </div> <div class="videoBox-subBox" v-show="videoShow2"> <span class="videoClose" @click="videoShow2 = false;videoUrl2 = '';">关闭</span> <div class="prism-player" id="player-con2"></div> </div> <div class="videoBox-subBox" v-show="videoShow3"> <span class="videoClose" @click="videoShow3 = false;videoUrl3 = '';">关闭</span> <div class="prism-player" id="player-con3"></div> </div> <div class="videoBox-subBox" v-show="videoShow4"> <span class="videoClose" @click="videoShow4 = false;videoUrl4 = '';">关闭</span> <div class="prism-player" id="player-con4"></div> </div> </div> </div> </div> </template> <script> import FMap from '@/components/fMap/components/fMap' import FMapFeatures from '@/components/fMap/components/fMapFeatures' import Button1 from '@/components/button/button1' import People from './panelBoard/people' import Case from './panelBoard/case' import Camera from './panelBoard/camera' import {fetchShuangchuang, fetchCase} from '@/api/cityManage' import {fetchVideoToken, fetchFlushVideoToken, fetchChannels, fetchVideo} from '@/api/camera' import {fetchBoundary, fetchRoadResponse, fetchGeojson} from '@/api/geojson' export default { name: 'ScMap2D', components: {Camera, People, Case, FMapFeatures, FMap, Button1}, data () { var that = this return { type: 'blackVector', // 地图类型 plugins: ['mapswitch', 'mouseposition'], // 插件 zoom: 12, // 缩放等级 layers: { boundary: {name: 'boundary', title: '边界图层', selectable: false, style: 'fill:rgba(255, 255, 0, 0.0);stroke-color:#59baf2;stroke-width:4;'}, roads: {name: 'roads', title: '道路及负责人', selectable: true, bubbleable: true, bubble: 'roadBB', style: 'fill:rgba(255, 255, 0, 0.5);stroke-color:#ffff33;stroke-width:2;', hoverStyle: 'fill:rgba(255, 0, 0, 0.6);stroke-color:#0000ff;stroke-width:2;', selectedStyle: 'fill:rgba(255, 0, 0, 0.6);stroke-color:#0000ff;stroke-width:2;'}, boxCamera: {name: 'boxCamera', title: '摄像头', bubble: 'cameraBB', textable: true, text: '11111', onmousein: function (data) { that.fmap.singleSelectedFeature(data.feature) }, onmouseout: function (data) { that.fmap.closeSingleBubble() }, onclick: function (event) { that.getVideo(event.feature.values_.clients.channelId) }, symbol: 'camera2'}, volunteers: {name: 'volunteers', type: 'Clust', animation: true, bubble: 'myclustBB', title: '志愿者', symbol: 'volunteers'}, volunteer: {name: 'volunteer', bubbleable: true, bubble: 'volunteerBB', title: '志愿者1', symbol: 'volunteer'}, caseHandle: {name: 'caseHandle', bubbleable: true, bubble: 'caseBB', title: '已处理事件', symbol: 'case-handle'}, caseOvertime: {name: 'caseOvertime', bubbleable: true, bubble: 'caseBB', title: '超期事件', symbol: 'case-over'}, caseWait: {name: 'caseWait', bubbleable: true, bubble: 'caseBB', title: '待处理事件', symbol: 'case-wait'} }, // 往fmap注入的图层 boundaryData: [], // 边界数据 roads: [], // 道路和责任人信息 cameraStaticData: {}, // 摄像头统计数据 cameraData: [], // 摄像头位置数据 peopleData: [], // 双创志愿者数据 caseHandleData: [], // 案件数据 caseOvertimeData: [], // 案件数据 caseWaitData: [], // 案件数据, videoToken: '', // 视频云token videoTimer: null, // 视频定时器 videoCount: 60, // 倒计时 videoChannels: [], // 视频通道 onlineVideoChannels: [], // 在线视频通道列表 offlineVideoChannels: [], // 离线视频通道列表 videoUrl: '', // 视频地址 videoUrl2: '', // 视频地址2 videoUrl3: '', // 视频地址3 videoUrl4: '', // 视频地址4 videoShow: false, // videoShow1: false, // 第一个视频的显示 videoShow2: false, // 第二个视频的显示 videoShow3: false, // 第三个视频的显示 videoShow4: false, // 第四个视频的显示 player: null, // 播放器1 player2: null, // 播放器2 player3: null, // 播放器3 player4: null, // 播放器4 currentPlayer: 'player', // 当前切换palyer layersShow: { roadShow: true, // 道路是否显示 cameraShow: false, // 摄像头图层显示 peopleShow: false, // 双创志愿者图层显示 caseShow: false // 案件图层显示 } } }, mounted () { this.getBoundary() // 获取边界数据 }, computed: { videosShow () { const result = this.videoShow1 || this.videoShow2 || this.videoShow3 || this.videoShow4 return result } }, methods: { // 地图准备好后的操作,返回fmap对象 mapReady ({fmap}) { this.fmap = fmap this.showCase() setTimeout(() => { this.getRoadResponse() // 获取地块和责任人信息 }, 500) }, // 获取行政区划 getBoundary () { // 精一接口 fetchBoundary().then(response => { if (response.code === '1') { const data = response.data.data[0].data this.boundaryData = data } }) }, // 获取道路地块和责任人信息 getRoadResponse () { // fetchGeojson('rjxq').then(res => { // console.log('获取本地json成功') // const coordinatesArray = [] // let data = res // for (const feature of data.features) { // var coordinates = feature.geometry.coordinates[0] // coordinatesArray.push({geo: coordinates[0]}) // } // this.roads = coordinatesArray // }) fetchRoadResponse().then(response => { // var geoJson = new ol.format.GeoJSON() // var features = geoJson.readFeatures(response) // this.fmap.getLayerByName('roads').getSource().addFeatures(features) const roads = [] if (response && response.type === 'FeatureCollection') { const features = response.features for (const feature of features) { const others = { responseDept: feature.properties['责任单位'], responsePerson: feature.properties['责任人'], tel: feature.properties['联系方式'], position: feature.properties['位置描述'] } for (const coor of feature.geometry.coordinates[0]) { roads.push({ geo: coor, ...others }) } } this.roads = roads } }) }, // 处理摄像头按钮点击后的操作 showCameras () { this.controlLayersShow('cameraShow') this.getCamerasData() }, // 获取摄像头点位数据 getCamerasData () { this.getVideoToken() // 获取视频token // fetchTrafficCameras().then(response => { // if (response.code === '1') { // this.cameraStaticData = { // total: response.data.total, // online: response.data.total // } // this.cameraData = response.data.data[0].data // } // }) }, // 处理人员按钮后的操作 showShuangChuang () { this.controlLayersShow('peopleShow') this.getShuangchuangData() }, // 获取人员数据 getShuangchuangData () { fetchShuangchuang().then(response => { if (response.code === 200) { this.peopleData = response.data } }) }, // 处理事件按钮后的操作 showCase () { this.controlLayersShow('caseShow') this.getCaseData() }, // 获取事件数据 getCaseData () { fetchCase().then(response => { if (response.code === 200) { const data = response.data // 按照不同类型过滤 this.caseOvertimeData = data.filter((v) => { return v.normState === '5' }) this.caseHandleData = data.filter((v) => { return v.status === '2' }) this.caseWaitData = data.filter((v) => { return v.status === '3' }) } }) }, // 控制各层显示 controlLayersShow (layerName) { for (const key in this.layersShow) { if (key === layerName) { this.layersShow[key] = true } else { if (key !== 'roadShow') { this.layersShow[key] = false } } } }, // 获取视频相关参数 getVideoToken () { fetchVideoToken().then(res => { if (res.code === 1) { this.videoToken = res.data this.getChannels() this.videoTimer = setInterval(() => { if (this.videoCount > 1) { this.videoCount-- } else { this.getFlushVideoToken() } }, 1000) } }) }, // 刷新token getFlushVideoToken () { this.videoCount = 60 let params = { 'token': this.videoToken } fetchFlushVideoToken(params).then(res => { if (res.code === 1) { this.videoToken = res.data } }) }, // 获取所有通道 getChannels () { let params = { 'token': this.videoToken } fetchChannels(params).then(res => { if (res.code === 1) { // this.videoChannels = res.data this.videoChannels = res.data.filter((item) => { return item.online === '1' }) this.offlineVideoChannels = res.data.filter((item) => { return item.online !== '1' }) this.cameraStaticData = { total: res.data.length, online: this.videoChannels.length } } }) }, // 获取视频 getVideo (channelId) { let params = { 'token': this.videoToken, 'channelId': channelId } fetchVideo(params).then(res => { if (res.code === 1) { const videoUrl = res.data.url if (videoUrl) { if (this.currentPlayer === 'player') { this.videoUrl = videoUrl this.videoShow1 = true this.videoPlay1(videoUrl) this.currentPlayer = 'player2' } else if (this.currentPlayer === 'player2') { this.videoUrl2 = videoUrl this.videoShow2 = true this.videoPlay2(videoUrl) this.currentPlayer = 'player3' } else if (this.currentPlayer === 'player3') { this.videoUrl3 = videoUrl this.videoShow3 = true this.videoPlay3(videoUrl) this.currentPlayer = 'player4' } else if (this.currentPlayer === 'player4') { this.videoUrl4 = videoUrl this.videoShow4 = true this.videoPlay4(videoUrl) this.currentPlayer = 'player' } } else { alert('no videoUrl') } } }) }, // 视频播放1 videoPlay1 (videoUrl) { let id = 'player-con' let source = videoUrl !this.player && (this.player = new Aliplayer({ id: id, width: '100%', height: '100%', autoplay: true, // 自动播放 isLive: true, // rePlay: true, // 重复播放 // 支持播放地址播放,此播放优先级最高 source: videoUrl }, function (player) { console.log('播放器创建好了。') })) // 切换视频地址 this.player && this.player.loadByUrl(this.videoUrl) // 播放器暂停/播放 var _video = document.querySelector('video') this.player.on('play', function (e) { _video.removeEventListener('click', play) _video.addEventListener('click', pause) }) this.player.on('pause', function (e) { _video.removeEventListener('click', pause) _video.addEventListener('click', play) }) function play () { if (this.player) this.player.play() } function pause () { if (this.player) this.player.pause() } }, videoPlay2 (videoUrl) { let id = 'player-con2' !this.player2 && (this.player2 = new Aliplayer({ id: id, width: '100%', height: '100%', autoplay: true, // 自动播放 isLive: true, // rePlay: true, // 重复播放 // 支持播放地址播放,此播放优先级最高 source: videoUrl }, function (player) { console.log('播放器创建好了。') })) // 切换视频地址 this.player2 && this.player2.loadByUrl(videoUrl) // 播放器暂停/播放 var _video = document.querySelector('video') this.player2.on('play', function (e) { _video.removeEventListener('click', play) _video.addEventListener('click', pause) }) this.player2.on('pause', function (e) { _video.removeEventListener('click', pause) _video.addEventListener('click', play) }) function play () { if (this.player2) this.player2.play() } function pause () { if (this.player2) this.player2.pause() } }, videoPlay3 (videoUrl) { let id = 'player-con3' !this.player3 && (this.player3 = new Aliplayer({ id: id, width: '100%', height: '100%', autoplay: true, // 自动播放 isLive: true, // rePlay: true, // 重复播放 // 支持播放地址播放,此播放优先级最高 source: videoUrl }, function (player) { console.log('播放器创建好了。') })) // 切换视频地址 this.player3 && this.player3.loadByUrl(videoUrl) // 播放器暂停/播放 var _video = document.querySelector('video') this.player3.on('play', function (e) { _video.removeEventListener('click', play) _video.addEventListener('click', pause) }) this.player3.on('pause', function (e) { _video.removeEventListener('click', pause) _video.addEventListener('click', play) }) function play () { if (this.player3) this.player3.play() } function pause () { if (this.player3) this.player3.pause() } }, videoPlay4 (videoUrl) { let id = 'player-con4' !this.player4 && (this.player4 = new Aliplayer({ id: id, width: '100%', height: '100%', autoplay: true, // 自动播放 isLive: true, // rePlay: true, // 重复播放 // 支持播放地址播放,此播放优先级最高 source: videoUrl }, function (player) { console.log('播放器创建好了。') })) // 切换视频地址 this.player4 && this.player4.loadByUrl(videoUrl) // 播放器暂停/播放 var _video = document.querySelector('video') this.player4.on('play', function (e) { _video.removeEventListener('click', play) _video.addEventListener('click', pause) }) this.player4.on('pause', function (e) { _video.removeEventListener('click', pause) _video.addEventListener('click', play) }) function play () { if (this.player4) this.player4.play() } function pause () { if (this.player4) this.player4.pause() } } }, destroyed () { clearInterval(this.videoTimer) } } </script> <style rel="stylesheet/scss" lang="scss" scoped> .button { float: left; min-width: 150px; max-width: 250px; display: block; margin: 1em; padding: 1em 2em; border: none; background: none; color: white; vertical-align: middle; position: relative; z-index: 1; -webkit-backface-visibility: hidden; -moz-osx-font-smoothing: grayscale; } .button--round-s { border-radius: 5px; } .button--border-thin { border: 1px solid; } button--saqui { border-color: #ECEFF1; overflow: hidden; color: #fff; background: #37474f; -webkit-transition: background-color 0.3s ease-in, color 0.3s ease-in; transition: background-color 0.3s ease-in, color 0.3s ease-in; .button--inverted { background: #fff; color: #37474f; } button--inverted::after { color: #fff; } } .button--saqui::after { content: attr(data-text); position: absolute; top: 0; left: 0; width: 100%; height: 100%; padding: 1em 2em; color: #37474f; -webkit-transform-origin: -25% 50%; transform-origin: -25% 50%; -webkit-transform: rotate3d(0, 0, 1, 45deg); transform: rotate3d(0, 0, 1, 45deg); -webkit-transition: -webkit-transform 0.3s ease-in; transition: transform 0.3s ease-in; } .videoBox{ position:absolute; bottom:0; right:0; z-index:999; width:3.8rem; height:2.55rem; background:#000000; display:flex; align-items: start; flex-wrap: wrap; .videoBox-subBox{ width: 50%; height:50%; position:relative; } } .videoClose{ position: absolute; right: .05rem; top: .06rem; display: inline-block; color:#fff; font-size: .09rem; z-index:999; cursor: pointer; } </style>