<template> <div style="padding: 12px;"> <div style="float: left;" class="left-box"> <div class="infoBox"> <div class="infoChild"> <img src="../../assets/img/map/syn.png" alt=""> <span class="textCon"> <div>分析资源</div> <div class="colorText"><span>64</span>路</div> </span> </div> <div class="infoChild"> <img src="../../assets/img/map/car.png" alt=""> <span class="textCon"> <div>运行路数</div> <div class="colorText"><span>47</span>路</div> </span> </div> <div class="infoChild"> <img src="../../assets/img/map/warn.png" alt=""> <span class="textCon"> <div>运行异常</div> <div class="colorText"><span>7</span>个</div> </span> </div> <div class="infoChild"> <img src="../../assets/img/map/total.png" alt=""> <span class="textCon"> <div>数量总数</div> <div class="colorText"><span>23548</span>路</div> </span> </div> </div> <div id="map" class="maps"> <div class="inMapBox"> <div class="lDiv" :key="index" v-for="(item,index) in typeList"> <span class="ltext">{{item.event_name}}</span> <span class="lnum">{{item.total_num}}</span> <div style="clear: both;"></div> </div> </div> </div> <div> <div style="float: left; margin-right: 8px;"> <div class="numBox"> <div class="title">今日抓拍量</div> <span class="num">{{snap_num}}</span> <img src="../../assets/img/map/catch.png" alt="" class="catch"> </div> <div class="numBox"> <div class="title">今日审核量</div> <span class="num">{{audit_num}}</span> <img src="../../assets/img/map/back.png" alt="" class="backSea"> </div> </div> <div style="float: left;background: #FFFFFF;"> <div class="title">今日事件趋势</div> <div id="myChart" style="width: 523px; height: 224px;"></div> </div> </div> <div style="clear: both;"></div> </div> <div style="float: left;"> <div style="width: 789px;height: 446px;position: relative;margin-bottom: 11px;"> <ocxplay ref="ocx"></ocxplay> </div> <div style="background: #FFFFFF;width: 789px"> <div class="title">实时数据</div> <el-table height="349" :data="tableData" style="width: 100%;padding: 11px;"> <el-table-column type="index" align="center" label="序号"> </el-table-column> <el-table-column align="center" prop="eventType" label="事件类型" :formatter="eventFormatter"> </el-table-column> <el-table-column align="center" prop="locationName" label="地点名称"> </el-table-column> <el-table-column align="center" prop="startDt" width="180" label="首次抓拍时间"> </el-table-column> <el-table-column align="center" prop="endDt" width="180" label="最后抓拍时间"> </el-table-column> <el-table-column align="center" prop="operation" label="操作"> <template slot-scope="scope"> <el-tooltip content="详情及审核" placement="bottom" effect="light" :visible-arrow=false> <img src="../../assets/img/home/look.png" alt="" class="edit" @click="editVideo(scope.$index, scope.row)"> </el-tooltip> <span class="tableSpanBorder"></span> <el-tooltip content="删除" placement="bottom" effect="light" :visible-arrow=false> <img src="../../assets/img/home/del.png" alt="" class="del" @click="delFun(scope.$index, scope.row)"> </el-tooltip> </template> </el-table-column> </el-table> </div> <div style="clear: both;"></div> </div> <editset :setvisible.sync="setShow" :archiveunid="archiveUnid"></editset> </div> </template> <script> import {inherits} from 'ol/util.js'; import Map from 'ol/Map'; import View from 'ol/View'; import Feature from 'ol/Feature'; //元素 import Overlay from 'ol/Overlay'; //弹出框 import {toStringHDMS} from 'ol/coordinate'; import {fromLonLat, toLonLat} from 'ol/proj'; import {Tile as TileLayer, Vector as VectorLayer, VectorTile,Heatmap as HeatmapLayer} from 'ol/layer'; //瓦片图层 , 矢量图层等基础图层 import {Cluster, OSM, Vector as VectorSource, XYZ, TileJSON} from 'ol/source'; import KML from 'ol/format/KML.js'; import { defaults, Select, DragBox, Pointer, DragAndDrop, Draw, defaults as defaultInteractions, Pointer as PointerInteraction } from 'ol/interaction'; //交互,选择,画框等 import {Circle as CircleStyle, Fill, Stroke, Style, Text, Icon} from 'ol/style'; //添加图层,点,圆等的样式调节 import {Point, Geometry, LineString} from 'ol/geom' import GeoJSON from 'ol/format/GeoJSON.js'; import 'ol/ol.css' //地图默认样式 import editset from '../taskManage/editSet' import ocxplay from '../../components/ocxplay.vue' import moment from 'moment' var map = ''; var Views = ''; export default{ data(){ return{ typeList:[], tableData:[], eventTypeList:[], setShow:false, archiveUnid:0, startDt:moment(moment().format('YYYY-MM-DD')+' 00:00:00').utc().format('YYYY-MM-DD HH:mm:ss'), endDt:moment(moment().format('YYYY-MM-DD')+' 23:59:59').utc().format('YYYY-MM-DD HH:mm:ss'), snap_num:0, audit_num:0 } }, components:{ editset,ocxplay }, mounted(){ setTimeout(()=>{ this.drawLine(); this.getEventTypeList(); this.InitMap(); },300) }, methods:{ getNum(){ this.$api.map.homeNum({ startDt:this.startDt, endDt:this.endDt, _t: Date.parse(new Date())/1000 }).then((res)=>{ this.typeList=res.list_data }).catch((error)=>{ }) this.$api.map.homeCatch({ startDt:this.startDt, endDt:this.endDt, _t: Date.parse(new Date())/1000 }).then((res)=>{ this.snap_num=res.snap_num; this.audit_num=res.audit_num; }).catch((error)=>{ }) }, getEventTypeList(){ this.$api.map.eventTypeData({ _t: Date.parse(new Date())/1000 }).then((res)=>{ this.eventTypeList=res.list_data; this.getData() }) }, getData(){ this.$api.map.archive({ startDt:this.startDt, endDt:this.endDt, _t: Date.parse(new Date())/1000 }).then((res)=>{ this.tableData=res.content; }) }, editVideo(index,row){ this.setShow=true; this.archiveUnid=row.archive_unid; }, delFun(index,row){ this.$api.map.delEvent({},row.archive_unid).then((res)=>{ console.log(res) }) console.log(row) }, eventFormatter(row, column, cellValue, index){ let value='' this.eventTypeList.forEach(item=>{ if(item.code==cellValue){ value=item.name; } }) return value; }, drawLine(){ this.$api.map.homeLine({ startDt:this.startDt, endDt:this.endDt, _t: Date.parse(new Date())/1000 }).then((res)=>{ let xData=[]; let seriesData=[]; let legendData=[]; res.list_data.forEach(item=>{ if(!xData.includes(item.hour)){ xData.push(item.hour); } if(!legendData.includes(item.event_name)){ legendData.push(item.event_name); seriesData.push({ name: item.event_name, type: 'line', data: [item.total_num] }) }else{ seriesData.forEach(serItem=>{ if(serItem.name==item.event_name){ serItem.data.push(item.total_num) } }) } }) console.log(seriesData) // 基于准备好的dom,初始化echarts实例 let myChart = this.$echarts.init(document.getElementById('myChart')) // 绘制图表 myChart.setOption({ tooltip: {}, color:['#0069FF'], xAxis: { data: xData, axisTick:false, axisLine:{ lineStyle:{ color:'#d9d9d9' } }, axisLabel:{ color:'#666666', fontSize:'10px' } }, grid:{ left:38, bottom:30, top:13, right:21 }, yAxis: { axisTick:false, axisLine:{ lineStyle:{ color:'#d9d9d9' } }, axisLabel:{ color:'#666666', fontSize:'10px' } }, series: seriesData }); }).catch((error)=>{ console.log('e2',error) }) }, InitMap(){ let _this = this; //坐标 // var heatData = { "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [116.357068,39.954021, 0] }, "properties": { "name": "M 5 - 2012 Dec 25, PAKISTAN" } }] } for(var i =0; i< 300; i++){ let c = Math.random(1)*1000 let e = Math.random(1)*100 let b = (116.357068 * 1000000 + i*c)/1000000; let d = (39.954021 * 1000000 + i*e)/1000000 let a = { "type": "Feature", "geometry": { "type": "Point", "coordinates": [b,d, 0] }, "properties": { "name": "M 5 - 2012 Dec 25, PAKISTAN" +i } } heatData.features.push(a) } var vectorSources = new VectorSource({ features: (new GeoJSON()).readFeatures(heatData,{ dataProjection : 'EPSG:4326' }) }); var path = "http://192.168.9.62:20080/static/pics/qingdaoMap/roadmap/{z}/{x}/{y}.png" var offlineMapLayer = new TileLayer({ source: new XYZ({ // 设置本地离线瓦片所在路径,由于例子里面只有一张瓦片,页面显示时就只看得到一张瓦片。 url: path }) }); Views = new View({ projection: 'EPSG:4326', zoom: 2,// 并且定义地图显示层级为2 minZoom:13, maxZoom:18, center:[120.324447,36.064594] }) map = new Map({ // 设置地图图层 layers: [ // 创建一个使用Open Street Map地图源的瓦片图层 offlineMapLayer, ], Interactions: [ defaults, Select, DragBox ], loadTilesWhileAnimating:true, // 设置显示地图的视图 view:Views , // 让id为map的div作为地图的容器 target: 'map', }); var heatmapvector = new HeatmapLayer({ source: vectorSources, blur: parseInt(20, 6), radius:parseInt(3, 5), }); map.addLayer(heatmapvector); // 添加一个使用离线瓦片地图的层 var CameraVertorlayer = new VectorLayer({ source: _this.addCameraLayer([120.324447,36.064594],"相机A") }); map.addLayer(CameraVertorlayer); this.addLayer(); map.on('click',(e)=>{ var pixel = map.getEventPixel(e.originalEvent); console.log(pixel); //点击相机标注点 map.forEachFeatureAtPixel(pixel,function(feature){ var coodinate = e.coordinate; _this.unid = feature.getProperties().unid; Overlay.setPosition(coodinate); map.addOverlay(Overlay); }); }); }, addLayer(data){ var pos = data; var marker = new Overlay({ position: pos, positioning: 'center-center', element: document.getElementById('canvasDiv') }); map.addOverlay(marker); }, addCameraLayer(coordinate,phonetext) { let vectorSource = new VectorSource({id:1}); let icon = new Feature({ geometry: new Point(coordinate), unid:'1' }); let color = '#156BB1'; //设置气泡颜色 //添加svg图标需注意 width,height要和 new Icon 的imgSize保持一致 let svg = '<svg t="1540524238971" class="icon" style="text-align:center" x="0px" y="0px" width="28px" height="28px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4126" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"><defs><style type="text/css"></style></defs>'+ '<path fill="' + color + '" d="M865.309 291.918c-19.289-45.606-46.897-86.557-82.06-121.719-35.161-35.162-76.114-62.771-121.718-82.06-47.23-19.976-97.385-30.105-149.072-30.105S410.618 68.163 363.388 88.139c-45.605 19.289-86.557 46.898-121.719 82.06-35.162 35.161-62.771 76.114-82.06 121.719-19.976 47.229-30.105 97.384-30.105 149.071 0 51.687 10.129 101.841 30.105 149.07 19.289 45.605 46.898 86.558 82.06 121.72 35.162 35.161 76.114 62.771 121.719 82.06 11.201 4.738 22.569 8.914 34.081 12.541l-58.051 143.991-17.783 0c-14.129 0-25.583 11.454-25.583 25.583s11.454 25.583 25.583 25.583l352.169 0c0.063 0 0.124 0.007 0.187 0.007 0.101 0 0.203-0.006 0.303-0.007l35.985 0c14.13 0 25.583-11.454 25.583-25.583s-11.453-25.583-25.583-25.583l-18.876 0-57.565-146.13c24.322-8.109 47.832-18.654 70.119-31.546 57.156-33.063 105.093-80.61 138.628-137.502 34.561-58.633 52.83-125.787 52.83-194.204C895.414 389.302 885.285 339.148 865.309 291.918zM513.814 146.1c26.472 0 48.01 21.537 48.01 48.01 0 26.472-21.537 48.01-48.01 48.01s-48.011-21.537-48.011-48.01C465.804 167.638 487.342 146.1 513.814 146.1zM512.54 688.835c-111.982 0-203.086-91.104-203.086-203.086 0-111.982 91.104-203.086 203.086-203.086 111.981 0 203.086 91.104 203.086 203.086C715.626 597.731 624.521 688.835 512.54 688.835z" p-id="4127"></path><path d="M512.54 333.829c-83.769 0-151.921 68.152-151.921 151.921 0 83.769 68.15 151.921 151.921 151.921 83.769 0 151.921-68.15 151.921-151.921C664.461 401.98 596.309 333.829 512.54 333.829z" p-id="4128"></path><path d="M513.814 197.265c1.739 0 3.154-1.415 3.154-3.155 0-1.74-1.415-3.155-3.154-3.155-1.74 0-3.155 1.415-3.155 3.155C510.659 195.85 512.074 197.265 513.814 197.265z" p-id="4129"></path><path d="M636.408 950.372 636.408 950.372 636.408 950.373Z" p-id="4130"></path></svg>' let cameraIcon = new Image(); cameraIcon.src = 'data:image/svg+xml,' + escape(svg); icon.setStyle(new Style({ //设置样式和大小 image: new Icon({ img: cameraIcon, crossOrigin: 'anonymous', // src:'http://192.168.9.233:20080/static/pics/cache/biaozhu.svg', imgSize: [28, 28], zIndex:20, marginTop:100 }), text:new Text({ text:phonetext, textBaseline: 'top', font: 'normal 12px 微软雅黑', lineHeight:'0px', fill: new Fill({ color: 'red', }), }), stroke: new Stroke({ color: 'red', width: 21, marginTop:100, }) })); vectorSource.addFeature(icon); return vectorSource; }, addFeature(){ function createStyle(src, img) { return new Style({ image: new Icon(/** @type {module:ol/style/Icon~Options} */ ({ anchor: [0.5, 0.96], crossOrigin: 'anonymous', src: src, img: img, imgSize: img ? [img.width, img.height] : undefined })) }); } var iconFeature = new Feature(new Point([113.338591,34.506910])); iconFeature.set('style', createStyle('../../../assets/img/dianli.png', undefined)); var CameraVertorlayer = new VectorLayer({ source: iconFeature, id:1 }); map.addLayer(this.CameraVertorlayer); }, } } </script> <style scoped="scoped"> .left-box{ } .infoBox{ margin-bottom: 8px; } .infoChild{ width: 204px; height: 70px; display: inline-block; background: #FFFFFF; margin-right: 8px; } .infoChild:nth-child(1) img{ width: 27px; height: 27px; margin: 22px 20px 21px 40px; } .infoChild:nth-child(2) img{ width: 30px; height: 27px; margin: 22px 22px 21px 37px; } .infoChild:nth-child(3) img{ width: 28px; height: 28px; margin: 22px 22px 20px 34px; } .infoChild:nth-child(4) img{ width: 27px; height: 28px; margin: 22px 22px 20px 34px; } .textCon{ display: inline-block; vertical-align: top; font-size: 12px; color: #666666; margin-top: 14px; } .textCon span{ font-size: 20px; margin-right: 2px; } .colorText{ margin-top: 6px; color: #444444; } .ol-control button{ display:none!important; background:red!important } .ol-popup { position: absolute; background-color: #eeeeee; -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2)); filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2)); padding: 15px; border-radius: 10px; border: 1px solid #cccccc; bottom: 12px; left: -50px; min-width: 280px; } .ol-popup:after, .ol-popup:before { top: 100%; border: solid transparent; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; } .ol-popup:after { border-top-color: #eeeeee; border-width: 10px; left: 48px; margin-left: -10px; } .ol-popup:before { border-top-color: #cccccc; border-width: 11px; left: 48px; margin-left: -11px; } .ol-popup-closer { text-decoration: none; position: absolute; top: 2px; right: 8px; } .ol-popup-closer:after { content: "✖"; } .popup-content{ height:300px; overflow:auto } .pop-info-box{ overflow: hidden; border-bottom :2px solid #fff } .pop-img-box { float: left; height: 100px; width :120px; img{ height: 100%; width: 100%; } } .pop-info{ float: left; padding-left: 20px; width :100px } .map-box { position: relative; background :#f8f8f8; border-radius: 10px; .content-info{ position :absolute; z-index :1000; color: red } } .numBox{ width: 307px; height: 125px; background: #FFFFFF; color: #444444; position: relative; } .numBox:nth-child(1){ margin-bottom: 6px; } .num{ font-size: 30px; margin: 27px 0 0 13px; display: inline-block; font-weight:bold; } .catch{ width: 57px; position: absolute; top:59px; right: 16px; } .backSea{ width: 100%; position: absolute; bottom: 0; left: 0; } .title{ padding: 12px 0 0 11px; color: #444444; font-size: 16px; } .inMapBox{ background: #f8f8f8; display: inline-block; position: absolute; z-index: 99; border: 1px solid #E5E5E5; border-bottom: none; top: 5px; left: 5px; box-shadow:0px 2px 4px 0px rgba(0,0,0,0.18); } .lDiv{ width: 110px; height: 36px; line-height:36px; border-bottom: 1px solid #E5E5E5; } .lDiv span{ display: inline-block; text-align: center; font-size: 12px; float: left; } .ltext{ width: 71px; height: 100%; border-right:1px solid #E5E5E5; } .lnum{ width: 37px; } .maps{ height: 491px; width:840px; margin-bottom: 8px; position: relative; } .canvasDiv{ height :30px; width :30px; background :red; border-radius :30px; color: #ffffff; font-size :12px; text-align :center; line-height :30px; z-index :10; opacity :0.5; } .pl3{ padding-left: 3px } .rotate-north { top: 65px; left: .5em; } .ol-touch .rotate-north { top: 80px; } .canvasDiv{ height:30px; width:30px; border-radius: 25px; background: rgba(255, 0, 0, 1); transform: scale(0); animation: myfirst 3s; animation-iteration-count: infinite; } @keyframes myfirst{ to{ transform: scale(2); background: rgba(0, 0, 0, 0); } } .el-table th, .el-table tr{ background:rgba(248,249,250,1)!important; } .ol-overlaycontainer-stopevent{ display:none!important; } .alarm-active{ display :none } .alarm-makerbox{ display:block; height :200px; width: 200px; border-radius :5px; background: rgba(39, 41, 48, .9); color: #ffffff; font-family :'微软雅黑'; font-size :14px; animation: op 1s; -moz-animation: op 1s; /* Firefox */ -webkit-animation: op 1s; /* Safari 和 Chrome */ -o-animation: op 1s; } @keyframes op { from {opacity: 0;} to {opacity: 1;} } @-moz-keyframes op /* Firefox */ { from {opacity: 0;} to {opacity: 1;} } @-webkit-keyframes op /* Safari 和 Chrome */ { from {opacity: 0;} to {opacity: 1;} } @-o-keyframes op /* Opera */ { from {opacity: 0;} to {opacity: 1;} } .exit-alarm::after{ float :right; height: 20px; width :20px; margin :5px; content: "✖"; cursor: pointer; } .img-box{ width: 200px; height :100px; overflow :hidden; img{ height :100%; width :100%; text-align: center } } .info-list { padding :1px 10px } .edit{ cursor: pointer; width: 18px; } .play{ cursor: pointer; width:17px; } .pause,.del{ cursor: pointer; width: 12px; } .tableSpanBorder{ display: inline-block; height: 18px; border-left:2px solid #E5E5E5; margin: 0 17px; } .lines{ display: inline-block; width: 10px; border-top:1px solid #cccccc ; margin: 3px; } .el-table__body tr{ background: #FFFFFF!important; } </style>