293 lines
8.6 KiB
JavaScript
293 lines
8.6 KiB
JavaScript
|
|
|
|||
|
|
import * as maptalks from 'maptalks'
|
|||
|
|
import { PointLayer } from '@maptalks/vt'
|
|||
|
|
import GlobalMap from '../js/GlobalMap.js'
|
|||
|
|
import { getAssetsFile } from '@/utils/common'
|
|||
|
|
import WebSocketClient from '@/utils/WebSocketClient'
|
|||
|
|
import { findByCurrent } from '@/api/map/index.js'
|
|||
|
|
import dayjs from 'dayjs'
|
|||
|
|
|
|||
|
|
const danger = getAssetsFile('map/boat/danger.png')
|
|||
|
|
const passenger = getAssetsFile('map/boat/passenger.png')
|
|||
|
|
const trawler = getAssetsFile('map/boat/trawler.png')
|
|||
|
|
const other = getAssetsFile('map/boat/other.png')
|
|||
|
|
const radar = getAssetsFile('map/boat/radar.png')
|
|||
|
|
const netsonde = getAssetsFile('map/boat/netsonde.png')
|
|||
|
|
|
|||
|
|
let storeInstance = null
|
|||
|
|
let globalMap = null
|
|||
|
|
let glgroup = null
|
|||
|
|
let dynamicBoatInfoWebSocket = null // websock
|
|||
|
|
let boatsMarkerlayer = null // 渔船图层
|
|||
|
|
let cleanupTimer = null
|
|||
|
|
|
|||
|
|
const init = (store) => {
|
|||
|
|
storeInstance = store
|
|||
|
|
globalMap = GlobalMap.instance
|
|||
|
|
glgroup = globalMap.glGroup
|
|||
|
|
glgroup.setZIndex(8)
|
|||
|
|
setStyleToBoatLayer('_trawler_dynamic_boat', 8)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置渔船样式
|
|||
|
|
const setStyleToBoatLayer = (key, zIndex) => {
|
|||
|
|
const style = {
|
|||
|
|
style: [
|
|||
|
|
{
|
|||
|
|
name: 'boatStyle',
|
|||
|
|
filter: true,
|
|||
|
|
renderPlugin: {
|
|||
|
|
dataConfig: {
|
|||
|
|
type: 'point',
|
|||
|
|
only2D: true
|
|||
|
|
},
|
|||
|
|
sceneConfig: {
|
|||
|
|
fading: true,
|
|||
|
|
depthFunc: 'always'
|
|||
|
|
},
|
|||
|
|
type: 'icon'
|
|||
|
|
},
|
|||
|
|
symbol: [
|
|||
|
|
{
|
|||
|
|
markerType: 'triangle',
|
|||
|
|
markerWidth: {
|
|||
|
|
type: 'interval',
|
|||
|
|
stops: [
|
|||
|
|
[ 5, 5 ],
|
|||
|
|
[ 10, 10 ],
|
|||
|
|
[ 11, 0 ]
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
markerHeight: {
|
|||
|
|
type: 'interval',
|
|||
|
|
stops: [
|
|||
|
|
[ 5, 10 ],
|
|||
|
|
[ 10, 20 ],
|
|||
|
|
[ 11, 0 ]
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
markerFill: {
|
|||
|
|
type: 'categorical',
|
|||
|
|
property: 'deviceType',
|
|||
|
|
default: '#f4ea2a',
|
|||
|
|
// stops: [
|
|||
|
|
// [ 'AIS', { type: 'categorical', property: 'boatType', stops: [
|
|||
|
|
// [ '危险品货物运输船', '#d81e06' ],
|
|||
|
|
// [ '液货船', '#d81e06' ],
|
|||
|
|
// [ '客船', '#73f34f' ],
|
|||
|
|
// [ '公务船', '#73f34f' ],
|
|||
|
|
// [ '拖轮', '#73f34f' ],
|
|||
|
|
// [ '渔船', '#fff' ],
|
|||
|
|
// [ '其他', '#f4ea2a' ],
|
|||
|
|
// [ '网位移', '#e6e6e6' ],
|
|||
|
|
// [ '无线索船', '#e6e6e6' ]
|
|||
|
|
// ] } ],
|
|||
|
|
// [ 'RADAR', radar ]
|
|||
|
|
// ],
|
|||
|
|
stops: [
|
|||
|
|
[ 'AIS', '#f4ea2a' ]
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
markerLineColor: [ 0.2, 0.29, 0.39, 1 ],
|
|||
|
|
markerLineWidth: 1,
|
|||
|
|
markerRotation: {
|
|||
|
|
property: 'cog',
|
|||
|
|
type: 'identity'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
markerWidth: {
|
|||
|
|
type: 'interval',
|
|||
|
|
stops: [
|
|||
|
|
[ 10, 0 ],
|
|||
|
|
[ 11, 25 ],
|
|||
|
|
[ 14, 25 ]
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
markerHeight: {
|
|||
|
|
type: 'interval',
|
|||
|
|
stops: [
|
|||
|
|
[ 10, 0 ],
|
|||
|
|
[ 11, 30 ],
|
|||
|
|
[ 14, 30 ]
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
markerRotation: {
|
|||
|
|
property: 'cog',
|
|||
|
|
type: 'identity'
|
|||
|
|
},
|
|||
|
|
markerFile: {
|
|||
|
|
type: 'categorical',
|
|||
|
|
property: 'deviceType',
|
|||
|
|
default: other,
|
|||
|
|
// stops: [
|
|||
|
|
// [ 'AIS', { type: 'categorical', property: 'boatType', stops: [
|
|||
|
|
// [ '危险品货物运输船', danger ],
|
|||
|
|
// [ '液货船', danger ],
|
|||
|
|
// [ '客船', passenger ],
|
|||
|
|
// [ '公务船', passenger ],
|
|||
|
|
// [ '拖轮', passenger ],
|
|||
|
|
// [ '渔船', trawler ],
|
|||
|
|
// [ '其他', other ],
|
|||
|
|
// [ '网位移', netsonde ],
|
|||
|
|
// [ '无线索船', netsonde ]
|
|||
|
|
// ] } ],
|
|||
|
|
// [ 'RADAR', radar ],
|
|||
|
|
// ],
|
|||
|
|
stops: [
|
|||
|
|
[ 'AIS', other ]
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
textName: {
|
|||
|
|
property: 'boatName',
|
|||
|
|
type: 'identity'
|
|||
|
|
},
|
|||
|
|
textFill: '#fff',
|
|||
|
|
textHaloFill: '#3300cc',
|
|||
|
|
textHaloRadius: 2,
|
|||
|
|
textHaloBlur: 20,
|
|||
|
|
textDy: 10,
|
|||
|
|
textSize: {
|
|||
|
|
type: 'interval',
|
|||
|
|
stops: [
|
|||
|
|
[ 14, 0 ],
|
|||
|
|
[ 15, 15 ]
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
const name = `vt_${key}`
|
|||
|
|
if (boatsMarkerlayer) {
|
|||
|
|
boatsMarkerlayer.remove()
|
|||
|
|
}
|
|||
|
|
// 初始化动态渔船图层
|
|||
|
|
boatsMarkerlayer = new PointLayer(name, {
|
|||
|
|
cursor: 'pointer'
|
|||
|
|
})
|
|||
|
|
boatsMarkerlayer.setStyle(style)
|
|||
|
|
boatsMarkerlayer.addTo(glgroup)
|
|||
|
|
glgroup.setZIndex(zIndex)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 单独的清理函数
|
|||
|
|
const cleanupExpiredBoats = () => {
|
|||
|
|
boatsMarkerlayer.getGeometries().forEach(item => {
|
|||
|
|
const properties = item.getProperties()
|
|||
|
|
if (dayjs().diff(properties.gpsTime, 'hours') > 24) {
|
|||
|
|
item.remove()
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const getShip = () => {
|
|||
|
|
findByCurrent().then(res => {
|
|||
|
|
console.log('初始获取')
|
|||
|
|
addBoats(res.result)
|
|||
|
|
})
|
|||
|
|
// ----------船只数据------------------
|
|||
|
|
dynamicBoatInfoWebSocket = new WebSocketClient(`${import.meta.env.VITE_WS_BASE_URL}`)
|
|||
|
|
dynamicBoatInfoWebSocket.onopen(event => {
|
|||
|
|
})
|
|||
|
|
dynamicBoatInfoWebSocket.onmessage(event => {
|
|||
|
|
console.log('接收数据:', JSON.parse(event.data))
|
|||
|
|
if(Array.isArray(JSON.parse(event.data))) {
|
|||
|
|
addBoats(JSON.parse(event.data))
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
dynamicBoatInfoWebSocket.onclose(event => {
|
|||
|
|
// 可以尝试重新连接
|
|||
|
|
dynamicBoatInfoWebSocket.reconnect()
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
dynamicBoatInfoWebSocket.onerror(event => {
|
|||
|
|
dynamicBoatInfoWebSocket.close()
|
|||
|
|
dynamicBoatInfoWebSocket = null
|
|||
|
|
})
|
|||
|
|
// 启动定期清理任务(每5分钟检查一次)
|
|||
|
|
if (cleanupTimer) {
|
|||
|
|
clearInterval(cleanupTimer)
|
|||
|
|
}
|
|||
|
|
cleanupTimer = setInterval(() => {
|
|||
|
|
cleanupExpiredBoats()
|
|||
|
|
}, 5 * 60 * 1000) // 5分钟
|
|||
|
|
// 初始化连接
|
|||
|
|
dynamicBoatInfoWebSocket.connect()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const addBoats = (boatList) => {
|
|||
|
|
|
|||
|
|
boatList.forEach((boat) => {
|
|||
|
|
// let types = [ '危险品货物运输船', '液货船', '客船', '公务船', '拖轮', '渔船', '其他', '网位移', '无线索船' ]
|
|||
|
|
let { longitude, latitude, cog, boatName, sog, terminalCode, deviceType, gpsTime } = boat
|
|||
|
|
let isContain = boatsMarkerlayer.getGeometryById(terminalCode)
|
|||
|
|
if (isContain !== null) {
|
|||
|
|
isContain.setCoordinates([ longitude, latitude ])
|
|||
|
|
isContain.setProperties({
|
|||
|
|
cog: 360 - Number(cog),
|
|||
|
|
angle: Number(cog),
|
|||
|
|
sog: Number(sog),
|
|||
|
|
boatName,
|
|||
|
|
latitude,
|
|||
|
|
longitude,
|
|||
|
|
deviceType,
|
|||
|
|
gpsTime
|
|||
|
|
// boatType: types[Math.floor(Math.random() * types.length)]
|
|||
|
|
})
|
|||
|
|
} else {
|
|||
|
|
let mm = new maptalks.Marker([ longitude, latitude ], {
|
|||
|
|
id: terminalCode,
|
|||
|
|
properties: {
|
|||
|
|
cog: 360 - Number(cog),
|
|||
|
|
angle: Number(cog),
|
|||
|
|
sog: Number(sog),
|
|||
|
|
boatName,
|
|||
|
|
latitude,
|
|||
|
|
longitude,
|
|||
|
|
deviceType,
|
|||
|
|
gpsTime
|
|||
|
|
// boatType: types[Math.floor(Math.random() * types.length)]
|
|||
|
|
},
|
|||
|
|
cursor: 'pointer'
|
|||
|
|
})
|
|||
|
|
mm.on('click', (e) => {
|
|||
|
|
storeInstance.updateWindowInfo({
|
|||
|
|
visible: true,
|
|||
|
|
type: '_trawler_dynamic',
|
|||
|
|
data: { ...boat,
|
|||
|
|
...e.target.getProperties()
|
|||
|
|
// boatType: types[Math.floor(Math.random() * types.length)]
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
globalMap.map.animateTo(
|
|||
|
|
{
|
|||
|
|
zoom: 20,
|
|||
|
|
center: [ boat.longitude, boat.latitude ]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
duration: 1000 * 0.5,
|
|||
|
|
easing: 'out'
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
})
|
|||
|
|
mm.addTo(boatsMarkerlayer)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
const destroyWebsocket = () => {
|
|||
|
|
dynamicBoatInfoWebSocket.close()
|
|||
|
|
if (cleanupTimer) {
|
|||
|
|
clearInterval(cleanupTimer)
|
|||
|
|
cleanupTimer = null
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
export {
|
|||
|
|
destroyWebsocket,
|
|||
|
|
init,
|
|||
|
|
getShip,
|
|||
|
|
boatsMarkerlayer
|
|||
|
|
}
|