first commit
This commit is contained in:
293
src/components/Map/lbtbox/boatTerminal.js
Normal file
293
src/components/Map/lbtbox/boatTerminal.js
Normal file
@@ -0,0 +1,293 @@
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user