|
|
<template>
|
|
|
<div :style="{'height':mapHeight,'width':'100%','position':'relative'}">
|
|
|
<!-- 切换地图 -->
|
|
|
<!-- <div class="chooseMap">
|
|
|
<div>
|
|
|
<el-radio-group v-model="showMap" @change="changeMap">
|
|
|
<el-radio v-for="item in mapRadioList" :label="item.id">{{item.title}}</el-radio>
|
|
|
</el-radio-group>
|
|
|
</div>
|
|
|
<div>
|
|
|
<el-checkbox-group v-model="checkList" @change="changeCheck">
|
|
|
<el-checkbox v-for="item in mapCheckList" :label="item.id">{{item.title}}</el-checkbox>
|
|
|
</el-checkbox-group>
|
|
|
</div>
|
|
|
</div> -->
|
|
|
<!-- 地图 -->
|
|
|
<div id="maps" class="map" :style="{'height':'100%'}" />
|
|
|
<div v-if="showSpeed" class="speedchange">
|
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="24">
|
|
|
<label for="speed">
|
|
|
速度:
|
|
|
<el-slider v-model="speed" :step="30" :max="200" :show-tooltip="false" />
|
|
|
</label>
|
|
|
<el-button id="start-animation" type="primary" @click="startAnimation">开始</el-button>
|
|
|
<el-button id="pause-animation" type="primary" @click="pauseAnimation">暂停</el-button>
|
|
|
<el-button id="continue-animation" type="primary" @click="continueAnimation">继续</el-button>
|
|
|
<el-button id="stop-animation" type="primary" @click="stopAnimation">结束</el-button>
|
|
|
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
</div>
|
|
|
|
|
|
<!-- 轨迹回放 -->
|
|
|
<slot name="maptime" />
|
|
|
<slot name="mapbar" />
|
|
|
<!-- 首页 -->
|
|
|
<slot name="mapindex" />
|
|
|
|
|
|
<!-- 船只弹框 -->
|
|
|
<div v-show="shopPopup" ref="popup" class="popup">
|
|
|
<div class="info">
|
|
|
<div class="infowindow">
|
|
|
<div class="infoheader">
|
|
|
<span>{{ locationObj?locationObj.name:'' }}</span>
|
|
|
</div>
|
|
|
<div class="infowrap">
|
|
|
<table width="100%">
|
|
|
<tr>
|
|
|
<td>设备类型</td>
|
|
|
<td>{{ locationObj?(locationObj.type===1?'泵车':'其他'):'' }}</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>品牌名称</td>
|
|
|
<td>{{ locationObj?locationObj.branch:'' }}</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>型号名称</td>
|
|
|
<td>{{ locationObj?locationObj.model:'' }}</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>车牌/船号</td>
|
|
|
<td>{{ locationObj?locationObj.plate:'' }}</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>购买时间</td>
|
|
|
<td>{{ locationObj?locationObj.buy_date:'' }}</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>GPS</td>
|
|
|
<td>{{ locationObj?locationObj.gps:'' }}</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>电量</td>
|
|
|
<td>{{ locationInfo?(locationInfo.lithium?locationInfo.lithium:'-'):'-' }}</td>
|
|
|
</tr>
|
|
|
|
|
|
<tr>
|
|
|
<td>设备描述</td>
|
|
|
<td>{{ locationObj?locationObj.describe:'' }}</td>
|
|
|
</tr>
|
|
|
</table>
|
|
|
<div class="playback">
|
|
|
<li
|
|
|
@click="showPlayBack(locationInfo.equipment_number,locationObj.name,locationObj.branch,locationObj.model,locationObj.plate)"
|
|
|
>
|
|
|
<img :src="play_back" />轨迹
|
|
|
</li>
|
|
|
<!-- <li @click="showCamera(cameraStatus,cameraNo)" v-if="cameraNo">
|
|
|
<img :src='cameraImg' />摄像头
|
|
|
</li>
|
|
|
<li @click="showAutoCamera(locationInfo.stream_address)" v-if="locationInfo.stream_address">
|
|
|
<img :src='cameraImg' />摄像头
|
|
|
</li>
|
|
|
<li @click="showZJCamera()" v-if="locationInfo.type=='zhenjiang'">
|
|
|
<img :src='cameraImg' />摄像头
|
|
|
</li> -->
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 问题弹框 -->
|
|
|
<div v-show="shopquestionPopup" ref="questionpopup" class="popup">
|
|
|
<div class="info">
|
|
|
<div class="address">问题类型:{{ questionObj.questionName }}</div>
|
|
|
<div class="showinfo" @click="showInfo(questionId)">查看详情</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
<script>
|
|
|
import 'ol/ol.css'
|
|
|
import {
|
|
|
Tile as TileLayer,
|
|
|
Vector as VectorLayer
|
|
|
} from 'ol/layer'
|
|
|
import XYZ from 'ol/source/XYZ'
|
|
|
import {
|
|
|
TileArcGISRest
|
|
|
} from 'ol/source'
|
|
|
import tilegrid from 'ol/tilegrid/TileGrid'
|
|
|
import {
|
|
|
defaults as defaultControls
|
|
|
} from 'ol/control'
|
|
|
import Polyline from 'ol/format/Polyline'
|
|
|
import {
|
|
|
get as getprojection
|
|
|
} from 'ol/proj'
|
|
|
import {
|
|
|
Projection,
|
|
|
addProjection
|
|
|
} from 'ol/proj'
|
|
|
import Map from 'ol/Map.js'
|
|
|
import View from 'ol/View.js'
|
|
|
// 标注点位
|
|
|
import {
|
|
|
Vector as VectorSource
|
|
|
} from 'ol/source'
|
|
|
import * as olProj from 'ol/proj'
|
|
|
import {
|
|
|
Feature,
|
|
|
Overlay
|
|
|
} from 'ol'
|
|
|
import {
|
|
|
Point,
|
|
|
LineString
|
|
|
} from 'ol/geom'
|
|
|
import {
|
|
|
Style,
|
|
|
Icon,
|
|
|
Fill,
|
|
|
Stroke,
|
|
|
Circle as sCircle
|
|
|
} from 'ol/style'
|
|
|
import {
|
|
|
getVectorContext
|
|
|
} from 'ol/render'
|
|
|
|
|
|
import proj4 from 'proj4'
|
|
|
|
|
|
import {
|
|
|
CONFIGS,
|
|
|
MAPCONFIGS
|
|
|
} from '@/components/maps/config.js'
|
|
|
export default {
|
|
|
components: {
|
|
|
CONFIGS,
|
|
|
MAPCONFIGS
|
|
|
},
|
|
|
props: {
|
|
|
// 定位单个点位
|
|
|
locationObj: {
|
|
|
type: Object,
|
|
|
default: () => {}
|
|
|
},
|
|
|
// 首页全部点位
|
|
|
locationArray: {
|
|
|
type: Array,
|
|
|
default: () => []
|
|
|
},
|
|
|
// 首页问题
|
|
|
questionArr: {
|
|
|
type: Array,
|
|
|
default: () => []
|
|
|
},
|
|
|
// 轨迹回放
|
|
|
pointsArr: {
|
|
|
type: Array,
|
|
|
default: () => []
|
|
|
},
|
|
|
showWhichBoat: {
|
|
|
type: String,
|
|
|
default: 'all'
|
|
|
}
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
map: null,
|
|
|
projection: 'EPSG:4490',
|
|
|
mapHeight: '400px',
|
|
|
// 地图切换
|
|
|
showMap: 'M2',
|
|
|
mapRadioList: [{
|
|
|
id: 'M2',
|
|
|
title: '天地图'
|
|
|
}, {
|
|
|
id: 'S1',
|
|
|
title: '水利图'
|
|
|
}, {
|
|
|
id: 'H1',
|
|
|
title: '河道图'
|
|
|
}],
|
|
|
checkList: ['M1', 'L1'],
|
|
|
mapCheckList: [{
|
|
|
id: 'M1',
|
|
|
title: '高清影像'
|
|
|
}, {
|
|
|
id: 'L1',
|
|
|
title: '路网'
|
|
|
}],
|
|
|
configs: CONFIGS,
|
|
|
mapConfigs: MAPCONFIGS,
|
|
|
// 定位
|
|
|
featuresArr: [],
|
|
|
flagLayer: '', // 点位
|
|
|
shopPopup: false,
|
|
|
infoObj: {},
|
|
|
locationInfo: {},
|
|
|
play_back: require('@/assets/imgs/playback.png'),
|
|
|
cameraImg: require('@/assets/imgs/camera.png'),
|
|
|
camera: {},
|
|
|
cameraNo: '',
|
|
|
cameraStatus: '',
|
|
|
// 轨迹
|
|
|
drawLayer: null,
|
|
|
showSpeed: false,
|
|
|
center: [120.612720, 31.321883],
|
|
|
polyline: '',
|
|
|
route: null,
|
|
|
routes: null,
|
|
|
routeLength: 0,
|
|
|
routeCoords: [],
|
|
|
routeCoordsX: [],
|
|
|
routeCoordsY: [],
|
|
|
routeFeature: null,
|
|
|
geoMarker: null,
|
|
|
startMarker: null,
|
|
|
endMarker: null,
|
|
|
styles: {},
|
|
|
animating: false,
|
|
|
vectorLayer: null,
|
|
|
speed: 30,
|
|
|
startTime: undefined,
|
|
|
speedInput: undefined,
|
|
|
startButton: undefined,
|
|
|
stoptime: null,
|
|
|
timer: null,
|
|
|
elapsedTime: 0,
|
|
|
timerFlag: false,
|
|
|
index: 0,
|
|
|
|
|
|
// 不同船只
|
|
|
flagLayerIndex: null,
|
|
|
autoLayerIndex: null,
|
|
|
autoLayerIndex2: null,
|
|
|
// 问题类型
|
|
|
questionfeaturesArr: [],
|
|
|
questionflagLayer: '', // 点位
|
|
|
shopquestionPopup: false,
|
|
|
questionObj: {},
|
|
|
questionId: ''
|
|
|
}
|
|
|
},
|
|
|
watch: {
|
|
|
locationObj(val) {
|
|
|
if (val) {
|
|
|
this.setLocationMarker()
|
|
|
}
|
|
|
},
|
|
|
locationArray(val, newval) {
|
|
|
if (val || newval) {
|
|
|
this.setIndexMarker()
|
|
|
}
|
|
|
},
|
|
|
pointsArr(val) {
|
|
|
if (val) {
|
|
|
this.pointsArr = val
|
|
|
this.$nextTick(function() {
|
|
|
this.lineBack()
|
|
|
})
|
|
|
}
|
|
|
},
|
|
|
questionArr(val) {
|
|
|
if (val) {
|
|
|
this.questionArr = val
|
|
|
this.$nextTick(function() {
|
|
|
this.setQuestionMarker()
|
|
|
})
|
|
|
}
|
|
|
},
|
|
|
showWhichBoat(val) {
|
|
|
if (val.indexOf('baojie') > -1) {
|
|
|
this.flagLayerIndex.setVisible(true)
|
|
|
} else {
|
|
|
this.flagLayerIndex.setVisible(false)
|
|
|
}
|
|
|
if (val.indexOf('yiming') > -1) {
|
|
|
this.autoLayerIndex.setVisible(true)
|
|
|
} else {
|
|
|
this.autoLayerIndex.setVisible(false)
|
|
|
}
|
|
|
if (val.indexOf('zhenjiang') > -1) {
|
|
|
this.autoLayerIndex2.setVisible(true)
|
|
|
} else {
|
|
|
this.autoLayerIndex2.setVisible(false)
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
created() {},
|
|
|
mounted() {
|
|
|
// 转换坐标系
|
|
|
proj4.defs('EPSG:4490', '+proj=longlat +ellps=GRS80 +no_defs')
|
|
|
this.projection = new Projection({
|
|
|
code: this.mapConfigs.Map_Code,
|
|
|
units: this.mapConfigs.Map_units,
|
|
|
axisOrientation: this.mapConfigs.Map_axisOrientation,
|
|
|
global: this.mapConfigs.Map_global
|
|
|
})
|
|
|
addProjection(this.projection)
|
|
|
this.initLoad()
|
|
|
},
|
|
|
methods: {
|
|
|
initLoad() {
|
|
|
var that = this
|
|
|
var clientHeight = document.documentElement.clientHeight
|
|
|
var topHeight = 50 // 页面 头部
|
|
|
const tableHeight = clientHeight - topHeight
|
|
|
that.mapHeight = tableHeight + 'px'
|
|
|
this.$emit('mapHeight', that.mapHeight)
|
|
|
this.showMaps(that.mapHeight)
|
|
|
},
|
|
|
showMaps() {
|
|
|
this.$nextTick(function() {
|
|
|
this.initMap()
|
|
|
})
|
|
|
},
|
|
|
initMap() {
|
|
|
const map = new Map({
|
|
|
target: 'maps',
|
|
|
view: new View({
|
|
|
center: this.mapConfigs.MAP_center, // 中心点经纬度
|
|
|
zoom: this.mapConfigs.Map_Zooms[0], // 图层缩放大小
|
|
|
maxZoom: this.mapConfigs.Map_Zooms[1],
|
|
|
minZoom: this.mapConfigs.Map_Zooms[2],
|
|
|
projection: this.projection
|
|
|
}),
|
|
|
layers: []
|
|
|
// interactions: defaultControls({
|
|
|
// doubleClickZoom: false,
|
|
|
// }),
|
|
|
})
|
|
|
this.map = map
|
|
|
// 添加天地图
|
|
|
let url = 'http://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}'
|
|
|
url = `${url}&T=vec_c&tk=2eecd3d615e01cf6dbe6d4b8b686d264`
|
|
|
// let sourceMark = `http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=5a257cd2df1b3311723bd77b0de14baf`
|
|
|
const sourceMark = 'http://t3.tianditu.com/DataServer?T=cva_c&x={x}&y={y}&l={z}&tk=2eecd3d615e01cf6dbe6d4b8b686d264'
|
|
|
const tdtLayer = new TileLayer({
|
|
|
title: '天地图',
|
|
|
id: 'M2',
|
|
|
type: 'overlay',
|
|
|
visible: true,
|
|
|
layerType: 'TD地图',
|
|
|
opacity: 1,
|
|
|
source: new XYZ({
|
|
|
crossOrigin: 'anonymous',
|
|
|
url: url,
|
|
|
projection: 'EPSG:4326'
|
|
|
})
|
|
|
})
|
|
|
|
|
|
// console.log("tdtLayer1",tdtLayer1)
|
|
|
this.map.addLayer(tdtLayer)
|
|
|
const tdtLayer1 = new TileLayer({
|
|
|
title: '天地图1',
|
|
|
id: 'M23',
|
|
|
type: 'overlay',
|
|
|
visible: true,
|
|
|
layerType: 'TD地图1',
|
|
|
opacity: 1,
|
|
|
zIndex: 2,
|
|
|
source: new XYZ({
|
|
|
crossOrigin: 'anonymous',
|
|
|
url: sourceMark,
|
|
|
projection: 'EPSG:4326'
|
|
|
})
|
|
|
})
|
|
|
this.map.addLayer(tdtLayer1)
|
|
|
this.ShowLayers()
|
|
|
this.addOverlay()
|
|
|
this.singleclick()
|
|
|
this.addQuestionOverlay()
|
|
|
// this.singleQuestionclick()
|
|
|
// this.map.layer2.setVisible(false)
|
|
|
},
|
|
|
|
|
|
// 加载图层
|
|
|
ShowLayers() {
|
|
|
for (var i = 0; i < this.configs.length; i++) {
|
|
|
var result = this.configs[i]
|
|
|
if (result.layerType == 'GIS地图') {
|
|
|
const projection = getprojection(result.projection)
|
|
|
const origin = [-400.0, 399.9999999999998]
|
|
|
const resolutions = [0.0027465820824835565, 0.0013732910412417782, 6.866455206208891E-4,
|
|
|
3.4332276031044456E-4, 1.7166138015522228E-4, 8.583069007761114E-5, 4.291534503880557E-5,
|
|
|
2.1457672519402785E-5, 1.0728836259701392E-5
|
|
|
]
|
|
|
|
|
|
const fullExtent = [118.63622216442072, 30.12564516975147, 122.81217622965288, 32.74305227616479]
|
|
|
|
|
|
const tileGrid = new tilegrid({
|
|
|
tileSize: 256,
|
|
|
origin: origin,
|
|
|
extent: fullExtent,
|
|
|
resolutions: resolutions
|
|
|
})
|
|
|
const layer = new TileLayer({
|
|
|
title: result.title,
|
|
|
id: result.id,
|
|
|
type: result.type,
|
|
|
visible: result.visible,
|
|
|
layerType: result.layerType,
|
|
|
opacity: result.opacity,
|
|
|
source: new XYZ({
|
|
|
tileGrid: tileGrid,
|
|
|
url: result.url,
|
|
|
projection: projection
|
|
|
})
|
|
|
})
|
|
|
this.map.addLayer(layer)
|
|
|
} else {
|
|
|
const layer = new TileLayer({
|
|
|
title: result.title,
|
|
|
id: result.id,
|
|
|
type: result.type,
|
|
|
visible: result.visible,
|
|
|
layerType: result.layerType,
|
|
|
opacity: result.opacity,
|
|
|
source: new TileArcGISRest({
|
|
|
url: result.url,
|
|
|
projection: result.projection
|
|
|
})
|
|
|
})
|
|
|
this.map.addLayer(layer)
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
// 切换地图
|
|
|
changeMap(val) {
|
|
|
for (var m of this.mapRadioList) {
|
|
|
if (m.id == val) {
|
|
|
this.checkLayers(val, true)
|
|
|
} else {
|
|
|
this.checkLayers(m.id, false)
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
changeCheck(val) {
|
|
|
if (val.length == 0) {
|
|
|
for (var m of this.mapCheckList) {
|
|
|
this.checkLayers(m.id, false)
|
|
|
}
|
|
|
} else if (val.length == this.mapCheckList.length) {
|
|
|
console.log(val)
|
|
|
for (var m of this.mapCheckList) {
|
|
|
this.checkLayers(m.id, true)
|
|
|
}
|
|
|
} else {
|
|
|
for (var m of this.mapCheckList) {
|
|
|
if (m.id == val[0]) {
|
|
|
this.checkLayers(m.id, true)
|
|
|
} else {
|
|
|
this.checkLayers(m.id, false)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 切换地图
|
|
|
checkLayers(id, bool) {
|
|
|
const layers = this.map.getLayers().getArray()
|
|
|
for (let i = 0; i < layers.length; i++) {
|
|
|
if (layers[i].get('id') == id) {
|
|
|
if (bool) {
|
|
|
layers[i].setVisible(true)
|
|
|
} else {
|
|
|
layers[i].setVisible(false)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
// 单个点位 实时定位
|
|
|
setLocationMarker() {
|
|
|
this.flagLayer = new VectorLayer({
|
|
|
source: new VectorSource()
|
|
|
})
|
|
|
// 添加图层
|
|
|
this.map.addLayer(this.flagLayer)
|
|
|
// 创建feature,一个feature就是一个点坐标信息
|
|
|
const feature = new Feature({
|
|
|
geometry: new Point([this.locationObj.location.longitude, this.locationObj.location.latitude])
|
|
|
})
|
|
|
// 设置 展示信息
|
|
|
feature.set('obj', this.locationObj)
|
|
|
feature.set('locationInfo', this.locationObj.location)
|
|
|
feature.setStyle(
|
|
|
new Style({
|
|
|
image: new Icon({
|
|
|
src: require('@/assets/imgs/boaticon.png'),
|
|
|
scale: 0.15,
|
|
|
anchor: [0.48, 0.52]
|
|
|
})
|
|
|
})
|
|
|
)
|
|
|
console.log('locationInfo', this.locationObj)
|
|
|
this.featuresArr.push(feature)
|
|
|
this.flagLayer.getSource().addFeatures(this.featuresArr)
|
|
|
this.$nextTick(function() {
|
|
|
// 根据定位点 移动地图
|
|
|
this.moveto(this.locationObj.location.longitude, this.locationObj.location.latitude)
|
|
|
this.autoOpen(feature)
|
|
|
})
|
|
|
},
|
|
|
// 首页全部点位
|
|
|
setIndexMarker() {
|
|
|
if (this.flagLayerIndex) {
|
|
|
this.flagLayerIndex.getSource().clear()
|
|
|
}
|
|
|
if (this.autoLayerIndex) {
|
|
|
this.autoLayerIndex.getSource().clear()
|
|
|
}
|
|
|
if (this.autoLayerIndex2) {
|
|
|
this.autoLayerIndex2.getSource().clear()
|
|
|
}
|
|
|
|
|
|
// 设置图层
|
|
|
const featuresArrIndex = []
|
|
|
const autoArrIndex = []
|
|
|
const autoArrIndex2 = []
|
|
|
this.flagLayerIndex = new VectorLayer({
|
|
|
source: new VectorSource()
|
|
|
})
|
|
|
this.autoLayerIndex = new VectorLayer({
|
|
|
source: new VectorSource()
|
|
|
})
|
|
|
this.autoLayerIndex2 = new VectorLayer({
|
|
|
source: new VectorSource()
|
|
|
})
|
|
|
// 添加图层
|
|
|
this.map.addLayer(this.autoLayerIndex2)
|
|
|
this.map.addLayer(this.autoLayerIndex)
|
|
|
this.map.addLayer(this.flagLayerIndex)
|
|
|
// 循环添加feature
|
|
|
for (let i = 0; i < this.locationArray.length; i++) {
|
|
|
const mod = this.locationArray[i]
|
|
|
// 创建feature,一个feature就是一个点坐标信息
|
|
|
const feature = new Feature({
|
|
|
type: 'boat',
|
|
|
geometry: new Point([mod.location.longitude, mod.location.latitude])
|
|
|
})
|
|
|
// 设置 展示信息
|
|
|
feature.set('obj', mod)
|
|
|
feature.set('locationInfo', mod.location)
|
|
|
var logo_url = require('@/assets/imgs/boaticon.png')
|
|
|
if (mod.type == 'yiming') {
|
|
|
logo_url = require('@/assets/imgs/autoboat.png')
|
|
|
} else if (mod.type == 'zhenjiang') {
|
|
|
logo_url = require('@/assets/imgs/zautoboat.png')
|
|
|
}
|
|
|
feature.setStyle(
|
|
|
new Style({
|
|
|
image: new Icon({
|
|
|
src: logo_url,
|
|
|
scale: 0.15,
|
|
|
anchor: [0.28, 0.32]
|
|
|
})
|
|
|
})
|
|
|
)
|
|
|
if (mod.type == 'yiming') {
|
|
|
autoArrIndex.push(feature)
|
|
|
} else if (mod.type == 'zhenjiang') {
|
|
|
autoArrIndex2.push(feature)
|
|
|
} else {
|
|
|
featuresArrIndex.push(feature)
|
|
|
}
|
|
|
} // for 结束
|
|
|
this.flagLayerIndex.getSource().addFeatures(featuresArrIndex)
|
|
|
this.autoLayerIndex.getSource().addFeatures(autoArrIndex)
|
|
|
this.autoLayerIndex2.getSource().addFeatures(autoArrIndex2)
|
|
|
},
|
|
|
// 设置 问题巡查 点位
|
|
|
setQuestionMarker() {
|
|
|
if (this.questionArr.length == 0) {
|
|
|
this.$message({
|
|
|
message: '暂无相关问题巡查信息',
|
|
|
type: 'warning'
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
// 设置图层
|
|
|
this.questionflagLayer = new VectorLayer({
|
|
|
source: new VectorSource()
|
|
|
})
|
|
|
// 添加图层
|
|
|
this.map.addLayer(this.questionflagLayer)
|
|
|
// 循环添加feature
|
|
|
|
|
|
for (let i = 0; i < this.questionArr.length; i++) {
|
|
|
// 创建feature,一个feature就是一个点坐标信息
|
|
|
console.log(this.questionArr[i])
|
|
|
const feature = new Feature({
|
|
|
type: 'question',
|
|
|
geometry: new Point([this.questionArr[i]['questionArrs']['lng'], this.questionArr[i]['questionArrs'][
|
|
|
'lat'
|
|
|
]])
|
|
|
})
|
|
|
// 设置展示
|
|
|
feature.set('questionObj', this.questionArr[i])
|
|
|
feature.set('questionId', this.questionArr[i]['questionArrs']['id'])
|
|
|
// 设置 巡查ID
|
|
|
var logo_url = require('@/assets/imgs/questionimg.png')
|
|
|
feature.setStyle(
|
|
|
new Style({
|
|
|
image: new Icon({
|
|
|
src: logo_url,
|
|
|
scale: 0.15,
|
|
|
anchor: [0.28, 0.32]
|
|
|
})
|
|
|
})
|
|
|
)
|
|
|
this.questionfeaturesArr.push(feature)
|
|
|
} // for 结束
|
|
|
this.questionflagLayer.getSource().addFeatures(this.questionfeaturesArr)
|
|
|
},
|
|
|
|
|
|
// 船只弹出窗口
|
|
|
addOverlay() {
|
|
|
// 创建Overlay
|
|
|
const elPopup = this.$refs.popup
|
|
|
this.popup = new Overlay({
|
|
|
element: elPopup,
|
|
|
positioning: 'bottom-center',
|
|
|
stopEvent: false,
|
|
|
offset: [0, -20]
|
|
|
})
|
|
|
this.map.addOverlay(this.popup)
|
|
|
},
|
|
|
singleclick() {
|
|
|
// 点击
|
|
|
this.map.on('singleclick', (e) => {
|
|
|
// 判断是否点击在点上
|
|
|
// if (this.pointsArr.length > 0) {
|
|
|
// return
|
|
|
// }
|
|
|
const feature = this.map.forEachFeatureAtPixel(
|
|
|
e.pixel,
|
|
|
(feature) => feature
|
|
|
)
|
|
|
if (!feature) {
|
|
|
return
|
|
|
}
|
|
|
console.log(feature)
|
|
|
this.shopPopup = true
|
|
|
this.shopquestionPopup = false
|
|
|
// 设置弹窗位置
|
|
|
const coordinates = feature.getGeometry().getCoordinates()
|
|
|
this.infoObj = feature.get('obj')
|
|
|
this.locationObj = feature.get('obj')
|
|
|
this.locationInfo = feature.get('locationInfo')
|
|
|
// this.camera = this.infoObj.camera
|
|
|
// this.cameraNo = this.camera ? this.camera.idno : ""
|
|
|
// this.cameraStatus = this.camera ? this.camera.state : ""
|
|
|
this.popup.setPosition(coordinates)
|
|
|
})
|
|
|
},
|
|
|
// 问题弹出窗口
|
|
|
addQuestionOverlay() {
|
|
|
// 创建Overlay
|
|
|
const elPopup = this.$refs.questionpopup
|
|
|
this.questionpopup = new Overlay({
|
|
|
element: elPopup,
|
|
|
positioning: 'bottom-center',
|
|
|
stopEvent: false,
|
|
|
offset: [0, -20]
|
|
|
})
|
|
|
this.map.addOverlay(this.questionpopup)
|
|
|
},
|
|
|
|
|
|
showInfo(id) {
|
|
|
if (id) {
|
|
|
// this.$refs.showBook.infoId = id
|
|
|
// this.$refs.showBook.isShow = true
|
|
|
}
|
|
|
},
|
|
|
// autoopen 生成点位后自动打开
|
|
|
autoOpen(feature) {
|
|
|
this.shopPopup = true
|
|
|
// 设置弹窗位置
|
|
|
const coordinates = feature.getGeometry().getCoordinates()
|
|
|
this.infoObj = feature.get('obj')
|
|
|
this.locationInfo = feature.get('locationInfo')
|
|
|
this.camera = this.infoObj.camera
|
|
|
this.cameraNo = this.camera ? this.camera.idno : ''
|
|
|
this.cameraStatus = this.camera ? this.camera.state : ''
|
|
|
this.popup.setPosition(coordinates)
|
|
|
},
|
|
|
// 移动地图
|
|
|
moveto(longitude, latitude) {
|
|
|
this.map.getView().animate({
|
|
|
center: [longitude, latitude], // 中心点
|
|
|
rotation: undefined,
|
|
|
duration: 1000
|
|
|
})
|
|
|
},
|
|
|
// 实时定位 跳转轨迹回放
|
|
|
showPlayBack(gps, name, branch, model, plate) {
|
|
|
console.log('plat', plate)
|
|
|
this.$router.push({
|
|
|
path: '/car/playback',
|
|
|
query: {
|
|
|
boatEquipment: gps,
|
|
|
boatName: name,
|
|
|
boatBranch: branch,
|
|
|
modelName: model,
|
|
|
boatPlate: plate
|
|
|
// type: type
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
// 船只状态码转中文
|
|
|
toGetDirection(num) {
|
|
|
let name = '未知'
|
|
|
if (num >= 0 && num < 90) {
|
|
|
name = num == 0 ? '正北' : '东北'
|
|
|
} else if (num >= 90 && num < 180) {
|
|
|
name = num == 90 ? '正东' : '东南'
|
|
|
} else if (num >= 180 && num < 270) {
|
|
|
name = num == 180 ? '正南' : '西南'
|
|
|
} else if (num >= 270 && num < 360) {
|
|
|
name = num == 270 ? '正北' : '西北'
|
|
|
}
|
|
|
return name
|
|
|
},
|
|
|
toGetWarn(str) {
|
|
|
if (!str) {
|
|
|
return '无'
|
|
|
}
|
|
|
if (str.indexOf(1) > -1) {
|
|
|
return '有'
|
|
|
} else {
|
|
|
return '无'
|
|
|
}
|
|
|
},
|
|
|
toGetStatus(str) {
|
|
|
console.log('Number(str)', Number(str))
|
|
|
if (Number(str) != 11) {
|
|
|
return '异常信号'
|
|
|
} else {
|
|
|
return '正常信号'
|
|
|
}
|
|
|
},
|
|
|
isEmpty(val) {
|
|
|
if (val) {
|
|
|
return val
|
|
|
} else {
|
|
|
return ''
|
|
|
}
|
|
|
},
|
|
|
// 轨迹回放画线
|
|
|
lineBack() {
|
|
|
const that = this
|
|
|
if (this.vectorLayer) {
|
|
|
this.vectorLayer.getSource().clear()
|
|
|
this.vectorLayer = null
|
|
|
this.elapsedTime = 0
|
|
|
this.routeCoords = []
|
|
|
// this.stopAnimation()
|
|
|
}
|
|
|
if (this.pointsArr.length == 0) {
|
|
|
this.$message({
|
|
|
message: '暂无点位信息',
|
|
|
type: 'warning'
|
|
|
})
|
|
|
this.showSpeed = false
|
|
|
return
|
|
|
}
|
|
|
|
|
|
this.showSpeed = true
|
|
|
// this.animating = true
|
|
|
this.animating = false
|
|
|
for (var m of this.pointsArr) {
|
|
|
this.routeCoords.push([parseFloat(m.longitude), parseFloat(m.latitude)])
|
|
|
}
|
|
|
this.center = this.routeCoords[0]
|
|
|
this.map.getView().animate({
|
|
|
center: this.center, // 中心点
|
|
|
zoom: 16,
|
|
|
rotation: undefined,
|
|
|
duration: 1000
|
|
|
})
|
|
|
// this.routeCoords = lines
|
|
|
// 矢量元素要呈现的几何图形的特征属性LineString代表线段
|
|
|
this.routes = new LineString(this.routeCoords)
|
|
|
console.log(this.routes)
|
|
|
this.routeLength = this.routeCoords.length
|
|
|
this.routeFeature = new Feature({
|
|
|
type: 'route',
|
|
|
geometry: this.routes
|
|
|
})
|
|
|
this.geoMarker = new Feature({
|
|
|
type: 'geoMarker',
|
|
|
geometry: new Point(this.routeCoords[0])
|
|
|
})
|
|
|
this.startMarker = new Feature({
|
|
|
type: 'iconStart',
|
|
|
geometry: new Point(this.routeCoords[0])
|
|
|
})
|
|
|
this.endMarker = new Feature({
|
|
|
type: 'iconEnd',
|
|
|
geometry: new Point(this.routeCoords[this.routeLength - 1])
|
|
|
})
|
|
|
this.styles = {
|
|
|
route: new Style({
|
|
|
stroke: new Stroke({
|
|
|
width: 3,
|
|
|
color: '#338de3'
|
|
|
})
|
|
|
}),
|
|
|
iconStart: new Style({
|
|
|
image: new Icon({
|
|
|
anchor: [0.5, 0.5],
|
|
|
src: require('@/assets/imgs/map-start.png')
|
|
|
})
|
|
|
}),
|
|
|
iconEnd: new Style({
|
|
|
image: new Icon({
|
|
|
anchor: [0.5, 0.5],
|
|
|
src: require('@/assets/imgs/map-end.png')
|
|
|
})
|
|
|
}),
|
|
|
geoMarker: new Style({
|
|
|
image: new Icon({
|
|
|
anchor: [0.5, 0.5], // 图标中心
|
|
|
src: require('@/assets/imgs/boaticon.png'),
|
|
|
scale: 0.15,
|
|
|
rotation: -Math.atan2(
|
|
|
this.routeCoords[0][1] - this.routeCoords[1][1],
|
|
|
this.routeCoords[0][0] - this.routeCoords[1][0]
|
|
|
),
|
|
|
rotateWithView: true
|
|
|
})
|
|
|
})
|
|
|
}
|
|
|
this.vectorLayer = new VectorLayer({
|
|
|
source: new VectorSource({
|
|
|
features: [
|
|
|
this.routeFeature,
|
|
|
this.geoMarker,
|
|
|
this.startMarker,
|
|
|
this.endMarker
|
|
|
]
|
|
|
}),
|
|
|
style: function(feature) {
|
|
|
if (that.animating && feature.get('type') === 'geoMarker') {
|
|
|
return null
|
|
|
}
|
|
|
return that.styles[feature.get('type')]
|
|
|
}
|
|
|
})
|
|
|
this.map.addLayer(this.vectorLayer)
|
|
|
},
|
|
|
moveFeature(event) {
|
|
|
// if (!this.vectorLayer.getVisible()) {
|
|
|
// this.vectorLayer.setVisible(true)
|
|
|
// }
|
|
|
var carStyle, rotation
|
|
|
// 开始动画
|
|
|
this.elapsedTime++ // elapsedTime 已过时间
|
|
|
this.index = Math.round((Number(this.speed) * this.elapsedTime) / 60) // 已经走了多少个点
|
|
|
var x, y
|
|
|
if (this.index >= this.routeCoords.length) {
|
|
|
clearInterval(this.timer)
|
|
|
return
|
|
|
}
|
|
|
if (this.routeCoords[this.index] && this.routeCoords[this.index + 1]) {
|
|
|
x =
|
|
|
this.routeCoords[this.index][0] - this.routeCoords[this.index + 1][0]
|
|
|
y =
|
|
|
this.routeCoords[this.index][1] - this.routeCoords[this.index + 1][1]
|
|
|
// 返回从原点(0,0)到(x,y)点的线段与x轴正方向之间的弧度值
|
|
|
rotation = Math.atan2(y, x)
|
|
|
} else {
|
|
|
rotation = 0
|
|
|
}
|
|
|
carStyle = new Style({
|
|
|
image: new Icon({
|
|
|
src: require('@/assets/imgs/boaticon.png'),
|
|
|
rotateWithView: false,
|
|
|
rotation:
|
|
|
-rotation +
|
|
|
Math.atan2(
|
|
|
this.routeCoords[0][1] - this.routeCoords[1][1],
|
|
|
this.routeCoords[0][0] - this.routeCoords[1][0]
|
|
|
) /
|
|
|
2,
|
|
|
scale: 0.15,
|
|
|
anchor: [0.5, 0.5] // 图标中心
|
|
|
})
|
|
|
})
|
|
|
var line = new Feature({
|
|
|
geometry: new LineString(this.routeCoords)
|
|
|
})
|
|
|
var lineStyle = new Style({
|
|
|
stroke: new Stroke({
|
|
|
width: 6,
|
|
|
color: [237, 212, 0, 0.8]
|
|
|
})
|
|
|
})
|
|
|
line.setStyle(lineStyle)
|
|
|
var currentPoint = new Point(this.routeCoords[this.index])
|
|
|
// 添加矢量元素
|
|
|
var feature = new Feature(currentPoint)
|
|
|
this.vectorLayer.getSource().clear()
|
|
|
feature.setStyle(carStyle)
|
|
|
|
|
|
this.vectorLayer.getSource().addFeature(this.routeFeature)
|
|
|
this.vectorLayer.getSource().addFeature(this.startMarker)
|
|
|
this.vectorLayer.getSource().addFeature(this.endMarker)
|
|
|
this.vectorLayer.getSource().addFeature(feature)
|
|
|
this.map.render()
|
|
|
},
|
|
|
startAnimation() {
|
|
|
this.animating = true
|
|
|
this.startTime = new Date().getTime()
|
|
|
// this.speed = this.speedInput.value
|
|
|
// 隐藏geoMarker
|
|
|
this.geoMarker.changed()
|
|
|
this.map.getView().setCenter(this.center)
|
|
|
// 添加事件,地图渲染时触发
|
|
|
if (this.timer) {
|
|
|
clearInterval(this.timer)
|
|
|
}
|
|
|
this.timer = setInterval(() => {
|
|
|
this.moveFeature()
|
|
|
}, 60)
|
|
|
this.elapsedTime = 0
|
|
|
},
|
|
|
pauseAnimation() {
|
|
|
clearInterval(this.timer)
|
|
|
this.timerFlag = true
|
|
|
},
|
|
|
continueAnimation() {
|
|
|
if (this.timerFlag) {
|
|
|
this.map.getView().setCenter(this.center)
|
|
|
// 添加事件,地图渲染时触发
|
|
|
this.timer = setInterval(() => {
|
|
|
this.moveFeature()
|
|
|
}, 60)
|
|
|
}
|
|
|
this.timerFlag = false
|
|
|
},
|
|
|
stopAnimation(ended) {
|
|
|
clearInterval(this.timer)
|
|
|
this.vectorLayer.getSource().clear()
|
|
|
this.vectorLayer.getSource().addFeature(this.routeFeature)
|
|
|
this.vectorLayer.getSource().addFeature(this.startMarker)
|
|
|
this.vectorLayer.getSource().addFeature(this.endMarker)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
<style scoped>
|
|
|
/deep/ .ol-zoom {
|
|
|
display: none;
|
|
|
}
|
|
|
|
|
|
.chooseMap {
|
|
|
position: absolute;
|
|
|
margin: 15px 20px;
|
|
|
/* width: 350px; */
|
|
|
background-color: #fff;
|
|
|
border-radius: 4px;
|
|
|
border: 0.8px solid hsla(0, 0%, 60%, .2);
|
|
|
z-index: 99;
|
|
|
top: 0;
|
|
|
right: 0;
|
|
|
line-height: 40px;
|
|
|
/* text-align: center; */
|
|
|
padding: 0 40px 0 20px;
|
|
|
}
|
|
|
|
|
|
.popup {
|
|
|
width: 350px;
|
|
|
background-color: white;
|
|
|
/* padding: 18px; */
|
|
|
border-radius: 10px;
|
|
|
box-shadow: 0 0 15px rgb(177, 177, 177);
|
|
|
}
|
|
|
|
|
|
.info {
|
|
|
font-size: 14px;
|
|
|
text-align: left;
|
|
|
padding: 20px;
|
|
|
}
|
|
|
|
|
|
.info ul {
|
|
|
padding-left: 0;
|
|
|
}
|
|
|
|
|
|
.showinfo {
|
|
|
color: red;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
|
|
|
.infoheader {
|
|
|
color: rgb(255, 255, 255);
|
|
|
width: 100%;
|
|
|
padding: 5px;
|
|
|
background-color: rgb(64, 150, 209);
|
|
|
}
|
|
|
|
|
|
.infowrap {}
|
|
|
|
|
|
.infowrap table {
|
|
|
font-size: 0;
|
|
|
border: none;
|
|
|
border-collapse: separate;
|
|
|
border-spacing: 0 0px;
|
|
|
border-bottom: 1px solid rgb(214, 214, 214);
|
|
|
}
|
|
|
|
|
|
.infowrap table tr {
|
|
|
background-color: #f1f1f1;
|
|
|
}
|
|
|
|
|
|
.infowrap table tr td {
|
|
|
padding: 3px 10px;
|
|
|
font-size: 14px;
|
|
|
}
|
|
|
|
|
|
.infowrap table tr td:first-child {
|
|
|
width: 80px;
|
|
|
display: inline-block;
|
|
|
color: rgb(44, 120, 191);
|
|
|
|
|
|
}
|
|
|
|
|
|
.infowrap table tr td:first-child+td {
|
|
|
background-color: #fff;
|
|
|
width: 270px
|
|
|
}
|
|
|
|
|
|
.bm1 td {
|
|
|
border-bottom: 1px solid rgb(214, 214, 214);
|
|
|
/* border-top: 1px solid rgb(214, 214, 214); */
|
|
|
}
|
|
|
|
|
|
.playback {
|
|
|
padding: 10px;
|
|
|
font-size: 16px;
|
|
|
}
|
|
|
|
|
|
.playback li {
|
|
|
display: inline-block;
|
|
|
margin-right: 10px;
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
|
|
|
.playback li img {
|
|
|
width: 20px;
|
|
|
vertical-align: sub;
|
|
|
margin-right: 5px
|
|
|
}
|
|
|
|
|
|
.speedchange {
|
|
|
position: absolute;
|
|
|
top: 10px;
|
|
|
left: 240px;
|
|
|
background-color: #fff;
|
|
|
z-index: 1000;
|
|
|
padding: 13px
|
|
|
}
|
|
|
</style>
|