添加搜索显示隐藏具体的车辆,船舶,游艇数据
This commit is contained in:
@@ -1,32 +1,275 @@
|
||||
<template>
|
||||
<div class="ship-type-box" id="ship-type-box">
|
||||
<ul>
|
||||
<li v-for="(item,index) in shipTypes" :key="index">
|
||||
<div :style="'background-color:'+ item.color"></div>
|
||||
<span>{{ language === 'zh' ? item.name : item.tran }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- 筛选搜索按钮 -->
|
||||
<div class="filter-btn" @click="toggleFilter">
|
||||
<!-- {{ isShowFilter ? '−' : '+' }} -->
|
||||
<img v-if="isShowFilter" src="@/util/map/img/search-fold.png" alt="筛选搜索" />
|
||||
<img v-else src="@/util/map/img/search-ex.png" alt="筛选搜索" />
|
||||
</div>
|
||||
|
||||
<!-- 筛选搜索弹窗 -->
|
||||
<div v-if="isShowFilter" class="filter-popup">
|
||||
<div class="filter-item">
|
||||
<el-checkbox v-model="checkedTypes.ship" @change="handleTypeChange('ship')">
|
||||
<!-- {{ language === 'zh' ? '船舶' : 'Ship' }} -->
|
||||
</el-checkbox>
|
||||
<div class="filter-title">{{ language === 'zh' ? '船舶' : 'Ship' }}</div>
|
||||
<el-select
|
||||
v-model="searchValues.ship"
|
||||
:placeholder="language === 'zh' ? '搜索MMSI' : 'Search Ship Name/MMSI'"
|
||||
:disabled="!checkedTypes.ship"
|
||||
filterable
|
||||
clearable
|
||||
remote
|
||||
:remote-method="handleShipSearch"
|
||||
:loading="false"
|
||||
@change="handleShipSelect"
|
||||
class="ship-select"
|
||||
no-match-text="没有匹配结果"
|
||||
>
|
||||
<el-option
|
||||
v-for="ship in shipOptions"
|
||||
:key="ship.shipId"
|
||||
:label="ship.mmsi"
|
||||
:value="ship.mmsi"
|
||||
>
|
||||
<div class="ship-option-content">
|
||||
<div class="ship-mmsi">MMSI: {{ ship.mmsi }}</div>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<el-checkbox v-model="checkedTypes.car" @change="handleTypeChange('car')">
|
||||
<!-- {{ language === 'zh' ? '车辆' : 'Car' }} -->
|
||||
</el-checkbox>
|
||||
<div class="filter-title"> {{ language === 'zh' ? '车辆' : 'Car' }}</div>
|
||||
|
||||
<el-select
|
||||
style="width: 300px"
|
||||
v-model="searchValues.car"
|
||||
:placeholder="language === 'zh' ? '搜索车牌号' : 'Search Car Number'"
|
||||
:disabled="!checkedTypes.car"
|
||||
filterable
|
||||
clearable
|
||||
no-match-text="请输入车牌号,超过4位才搜索"
|
||||
remote
|
||||
:remote-method="handleCarSearch"
|
||||
:loading="false"
|
||||
@change="handleCarSelect"
|
||||
class="car-select"
|
||||
>
|
||||
<el-option
|
||||
v-for="car in carOptions"
|
||||
:key="car.carNum"
|
||||
:label="car.carNum"
|
||||
:value="car.carNum"
|
||||
>
|
||||
<div class="car-option-content">
|
||||
<div class="car-num">{{ car.carNum }}</div>
|
||||
<div class="car-company">{{ car.companyName || '' }}</div>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<el-checkbox v-model="checkedTypes.yacht" @change="handleTypeChange('yacht')">
|
||||
<!-- {{ language === 'zh' ? '游艇' : 'Yacht' }} -->
|
||||
</el-checkbox>
|
||||
<div class="filter-title"> {{ language === 'zh' ? '游艇' : 'Yacht' }}</div>
|
||||
|
||||
<el-select
|
||||
v-model="searchValues.yacht"
|
||||
:placeholder="language === 'zh' ? '搜索游艇名/MMSI' : 'Search Yacht Name/MMSI'"
|
||||
:disabled="!checkedTypes.yacht"
|
||||
filterable
|
||||
clearable
|
||||
remote
|
||||
:remote-method="handleYachtSearch"
|
||||
:loading="false"
|
||||
@change="handleYachtSelect"
|
||||
class="yacht-select"
|
||||
no-match-text="没有匹配结果"
|
||||
>
|
||||
<el-option
|
||||
v-for="yacht in yachtOptions"
|
||||
:key="yacht.shipId"
|
||||
:label="yacht.mmsi"
|
||||
:value="yacht.mmsi"
|
||||
>
|
||||
<div class="yacht-option-content">
|
||||
<div class="yacht-mmsi">MMSI: {{ yacht.mmsi }}</div>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {Vue, Component} from 'vue-property-decorator'
|
||||
import {Vue, Component, Prop} from 'vue-property-decorator'
|
||||
import bus from '@/util/bus'
|
||||
import storeUtil from '@/util/store'
|
||||
|
||||
@Component({})
|
||||
export default class MapBottomShipType extends Vue {
|
||||
private language = window.localStorage.getItem('language')
|
||||
private shipTypes: any[] = [
|
||||
{
|
||||
name: '货船',
|
||||
tran: 'Cargo Ship',
|
||||
color: '#BD3154'
|
||||
},
|
||||
{
|
||||
name: '游艇',
|
||||
tran: 'Fishing vessel',
|
||||
color: '#FFC24D'
|
||||
private isShowFilter = false
|
||||
|
||||
// 接收父组件传递的车辆数据
|
||||
@Prop({
|
||||
type: Array,
|
||||
default: () => []
|
||||
})
|
||||
private carData!: any[]
|
||||
|
||||
// 接收父组件传递的船舶数据
|
||||
@Prop({
|
||||
type: Array,
|
||||
default: () => []
|
||||
})
|
||||
private shipData!: any[]
|
||||
|
||||
// 勾选状态
|
||||
private checkedTypes: { [key: string]: boolean } = {
|
||||
ship: true,
|
||||
car: true,
|
||||
yacht: true
|
||||
}
|
||||
|
||||
// 搜索值
|
||||
private searchValues: { [key: string]: string } = {
|
||||
ship: '',
|
||||
car: '',
|
||||
yacht: ''
|
||||
}
|
||||
|
||||
// 车辆搜索选项
|
||||
private carOptions: any[] = []
|
||||
|
||||
// 船舶搜索选项
|
||||
private shipOptions: any[] = []
|
||||
|
||||
// 游艇搜索选项
|
||||
private yachtOptions: any[] = []
|
||||
// 控制车辆下拉框是否显示
|
||||
private carSelectVisible = false
|
||||
|
||||
// 切换筛选弹窗显示状态
|
||||
private toggleFilter() {
|
||||
this.isShowFilter = !this.isShowFilter
|
||||
}
|
||||
|
||||
// 处理类型勾选变化
|
||||
private handleTypeChange(type: string) {
|
||||
const isChecked = this.checkedTypes[type]
|
||||
|
||||
// 取消勾选时,清空并禁用搜索框
|
||||
if (!isChecked) {
|
||||
this.searchValues[type] = ''
|
||||
// 触发搜索,清空结果
|
||||
this.handleSearch(type)
|
||||
// 如果有打开的弹窗或轨迹,重置地图
|
||||
this.resetMap()
|
||||
}
|
||||
|
||||
// 触发全局事件,通知地图更新显示
|
||||
bus.$emit('filterTypeChange', {
|
||||
type,
|
||||
isChecked
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// 处理搜索
|
||||
private handleSearch(type: string) {
|
||||
const value = this.searchValues[type]
|
||||
|
||||
// 车牌号需要超过4位才搜索
|
||||
if (type === 'car' && value.length < 4) {
|
||||
return
|
||||
}
|
||||
|
||||
// 触发全局事件,通知地图更新搜索结果
|
||||
bus.$emit('filterSearch', {
|
||||
type,
|
||||
value
|
||||
})
|
||||
}
|
||||
|
||||
// 处理车辆搜索 - 当输入超过4位时触发
|
||||
private handleCarSearch(query: string) {
|
||||
// 车牌号需要超过4位才搜索
|
||||
if (query.length < 4) {
|
||||
this.carOptions = []
|
||||
return
|
||||
}
|
||||
|
||||
// 模糊搜索车辆数据
|
||||
this.carOptions = this.carData.filter((car: any) => {
|
||||
const carNum = car.carNum || ''
|
||||
return carNum.includes(query)
|
||||
})
|
||||
}
|
||||
|
||||
// 处理车辆选择
|
||||
private handleCarSelect(value: string) {
|
||||
// 触发搜索事件,更新地图显示
|
||||
this.handleSearch('car')
|
||||
}
|
||||
|
||||
// 处理船舶搜索
|
||||
private handleShipSearch(query: string) {
|
||||
// 过滤出船舶数据(shipTypeName !== '其他')
|
||||
const shipData = this.shipData.filter((ship: any) => {
|
||||
return ship.shipTypeName !== '其他'
|
||||
})
|
||||
console.log(shipData,'船舶数据')
|
||||
// 模糊搜索船舶数据(匹配船名或MMSI)
|
||||
this.shipOptions = shipData.filter((ship: any) => {
|
||||
const mmsi = ship.mmsi || ''
|
||||
return mmsi.includes(query)
|
||||
})
|
||||
}
|
||||
|
||||
// 处理船舶选择
|
||||
private handleShipSelect(value: string) {
|
||||
// 触发搜索事件,更新地图显示
|
||||
this.handleSearch('ship')
|
||||
}
|
||||
|
||||
// 处理游艇搜索
|
||||
private handleYachtSearch(query: string) {
|
||||
// 过滤出游艇数据(shipTypeName === '其他')
|
||||
const yachtData = this.shipData.filter((ship: any) => {
|
||||
return ship.shipTypeName === '其他'
|
||||
})
|
||||
console.log(yachtData,'游艇数据')
|
||||
// 模糊搜索游艇数据(匹配船名或MMSI)
|
||||
this.yachtOptions = yachtData.filter((yacht: any) => {
|
||||
const mmsi = yacht.mmsi || ''
|
||||
return mmsi.includes(query)
|
||||
})
|
||||
}
|
||||
|
||||
// 处理游艇选择
|
||||
private handleYachtSelect(value: string) {
|
||||
// 触发搜索事件,更新地图显示
|
||||
this.handleSearch('yacht')
|
||||
}
|
||||
|
||||
// 重置地图
|
||||
private resetMap() {
|
||||
const mapFun = storeUtil.getMapFun()
|
||||
const mapInstance = storeUtil.getMapInstance()
|
||||
|
||||
if (mapFun && mapInstance) {
|
||||
// 这里需要根据实际情况调用地图工具的方法来重置地图
|
||||
// 例如关闭弹窗、擦除轨迹、取消聚焦等
|
||||
console.log('重置地图')
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
public mounted() {
|
||||
window.addEventListener('setItemEvent', (e: any) => {
|
||||
@@ -45,33 +288,65 @@ export default class MapBottomShipType extends Vue {
|
||||
align-items: center;
|
||||
height: 2.5rem;
|
||||
z-index: 999;
|
||||
right: 1.25rem;
|
||||
bottom: 1.25rem;
|
||||
left: 1.1rem;
|
||||
bottom: 3.8rem;
|
||||
border-radius: 0.25rem;
|
||||
background-color: #FFFFFF;
|
||||
color: #333333;
|
||||
padding: 0 0 0 1.25rem;
|
||||
|
||||
ul {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin-right: 0.625rem;
|
||||
padding: 0 0.3125rem;
|
||||
line-height: 0.625rem;
|
||||
justify-content: space-between;
|
||||
|
||||
li {
|
||||
:first-child {
|
||||
display: inline-block;
|
||||
border-radius: 0.5625rem;
|
||||
width: 0.5625rem;
|
||||
height: 0.5625rem;
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
font-size: 0.75rem;
|
||||
display: inline-block;
|
||||
margin-right: 0.625rem;
|
||||
.filter-btn {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 1.5rem;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
border-radius: 0.25rem;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.filter-title{
|
||||
color: #2c469b;
|
||||
margin-right: 0.5rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.filter-popup {
|
||||
position: absolute;
|
||||
bottom: 3rem;
|
||||
left: 0;
|
||||
background-color: white;
|
||||
border-radius: 0.25rem;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
padding: 1rem;
|
||||
width: 25rem;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0.75rem;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.el-checkbox {
|
||||
margin-right: 1rem;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
.el-select {
|
||||
flex: 1;
|
||||
}
|
||||
.ship-select, .yacht-select {
|
||||
flex: 1;
|
||||
}
|
||||
.el-input {
|
||||
flex: 1;
|
||||
::v-deep .el-input__inner {
|
||||
height: 2rem;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
src/util/map/img/search-ex.png
Normal file
BIN
src/util/map/img/search-ex.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
BIN
src/util/map/img/search-fold.png
Normal file
BIN
src/util/map/img/search-fold.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
@@ -44,6 +44,7 @@ import WKT from 'ol/format/WKT'
|
||||
import {Circle, Fill, Stroke, Style, Text} from 'ol/style.js'
|
||||
import unByKey from 'ol/Observable.js'
|
||||
|
||||
// 地图全局配置对象,存储所有地图相关的实例和状态
|
||||
const shipMap = new Object({
|
||||
map: null, //地图
|
||||
view: null, //地图的资源
|
||||
@@ -73,15 +74,20 @@ const shipMap = new Object({
|
||||
__selectPort: null,//点击港口
|
||||
|
||||
})
|
||||
// 地图工具覆盖物数组
|
||||
let mapToolOver = []
|
||||
// 地图功能方法集合,提供对外API
|
||||
const shipFun = new Object({})
|
||||
// 设置地图实例
|
||||
shipFun.setmap = function (map) {
|
||||
shipMap.map = map
|
||||
}
|
||||
|
||||
var __pathData = {};
|
||||
var __pathDrawData = {};
|
||||
var __pathArray = {};
|
||||
// 路径数据存储对象
|
||||
var __pathData = {}; // 原始路径数据
|
||||
var __pathDrawData = {}; // 绘制用路径数据
|
||||
var __pathArray = {}; // 路径ID数组
|
||||
// 示例边界线数据(ABC线),用于判断船舶位置
|
||||
const abcLineData = [
|
||||
[
|
||||
11822129.922245655,
|
||||
@@ -110,18 +116,20 @@ const abcLineData = [
|
||||
]
|
||||
//地图
|
||||
shipMap.view = new View({
|
||||
projection: 'EPSG:3857', //使用这个坐标系
|
||||
center: transform([120, 36], 'EPSG:4326', 'EPSG:3857'), //定义中心位置
|
||||
zoom: 6, //定义等级
|
||||
minZoom: 3, //最小等级
|
||||
maxZoom: 18 //最大等级
|
||||
// rotation:120
|
||||
projection: 'EPSG:3857', // 使用Web墨卡托投影
|
||||
center: transform([120, 36], 'EPSG:4326', 'EPSG:3857'), // 中心点设置为东经120°,北纬36°
|
||||
zoom: 6, // 初始缩放级别
|
||||
minZoom: 3, // 最小缩放级别
|
||||
maxZoom: 18 // 最大缩放级别
|
||||
// rotation:120 // 旋转角度(注释掉)
|
||||
})
|
||||
// 初始化OSM基础图层
|
||||
shipMap.layer = new TileLayer({
|
||||
source: new OSM(), //资源
|
||||
zIndex: 1
|
||||
})
|
||||
|
||||
// 定义EPSG:3395投影(墨卡托投影)
|
||||
var projection_3395 = new Projection({
|
||||
code: 'EPSG:3395',
|
||||
extent: [-20026376.39, -15496570.74, 20026376.39, 18764656.23],
|
||||
@@ -129,6 +137,7 @@ var projection_3395 = new Projection({
|
||||
axisOrientation: 'neu'
|
||||
})
|
||||
|
||||
// 注册EPSG:3395投影定义
|
||||
proj4.defs(
|
||||
'EPSG:3395',
|
||||
'+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'
|
||||
@@ -137,7 +146,12 @@ register(proj4)
|
||||
|
||||
var seaMapPath = 'http://cm191.myships.com/ChartMap'
|
||||
|
||||
/**
|
||||
* 获取海图数据源
|
||||
* @returns {XYZ} 海图XYZ数据源
|
||||
*/
|
||||
function getSeaMapSource() {
|
||||
// 获取EPSG:3857投影的范围
|
||||
var projectionExtent = get('EPSG:3857').getExtent()
|
||||
var height = getHeight(projectionExtent)
|
||||
var width = getWidth(projectionExtent)
|
||||
@@ -145,27 +159,35 @@ function getSeaMapSource() {
|
||||
var maxResolution = Math.max(width / tileSize[0], height / tileSize[1])
|
||||
var length = 18 + 1
|
||||
var resolutions = new Array(length)
|
||||
// 生成各级分辨率数组
|
||||
for (var z = 0; z < length; ++z) {
|
||||
resolutions[z] = maxResolution / Math.pow(2, z)
|
||||
}
|
||||
// 创建瓦片网格
|
||||
var tilegrid = new TileGrid({
|
||||
origin: [projectionExtent[0], projectionExtent[3]],
|
||||
tileSize: tileSize,
|
||||
resolutions: resolutions
|
||||
})
|
||||
// 监听分辨率变化,刷新路径
|
||||
shipMap.view.on('change:resolution', function (event) {
|
||||
freshPath();
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* 刷新路径数据
|
||||
*/
|
||||
function freshPath() {
|
||||
for (var pathId in __pathData) {
|
||||
var data = __pathData[pathId];
|
||||
// 生成绘制用路径数据
|
||||
var re = __makePathData(data, shipMap.map, pathId);
|
||||
var old_re = __pathDrawData[pathId];
|
||||
// 如果路径数据发生变化
|
||||
if (!old_re || re.length != old_re.length) {
|
||||
__pathDrawData[pathId] = re;
|
||||
var ids = __pathArray[pathId];
|
||||
// 移除旧的路径要素
|
||||
if (ids && ids.length > 0) {
|
||||
ids.forEach(function (item, index) {
|
||||
var f = shipMap.sourceList.pathLineSource.getFeatureById(item);
|
||||
@@ -176,15 +198,23 @@ function getSeaMapSource() {
|
||||
}
|
||||
})
|
||||
}
|
||||
// 绘制新的路径
|
||||
__drawPathData(re, pathId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数字补零函数
|
||||
* @param {number} num - 补零后的总长度
|
||||
* @param {string|number} val - 要补零的值
|
||||
* @returns {string} 补零后的字符串
|
||||
*/
|
||||
function padLeft(num, val) {
|
||||
return (new Array(num).join('0') + val).slice(-num)
|
||||
}
|
||||
|
||||
// 创建并返回XYZ数据源
|
||||
return new XYZ({
|
||||
cacheSize: 256,
|
||||
projection: projection_3395,
|
||||
@@ -193,20 +223,25 @@ function getSeaMapSource() {
|
||||
if (!xyz) {
|
||||
return ''
|
||||
}
|
||||
// 计算瓦片URL参数
|
||||
var z = xyz[0] - 2
|
||||
if (z <= -1) return ''
|
||||
var x = Math.abs(xyz[1])
|
||||
var y = Math.abs(xyz[2])
|
||||
// 格式化参数
|
||||
x = 'C' + padLeft(8, x.toString(16))
|
||||
y = 'R' + padLeft(8, y.toString(16))
|
||||
z = 'L' + padLeft(2, z)
|
||||
// 返回完整的瓦片URL
|
||||
return seaMapPath + '/' + z + '/' + y + '/' + x + '.jpg'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 初始化海图数据源
|
||||
shipMap.seaView = getSeaMapSource()
|
||||
|
||||
// 创建海图图层
|
||||
shipMap.seaLayer = new TileLayer({
|
||||
preload: Infinity,
|
||||
source: shipMap.seaView,
|
||||
@@ -217,21 +252,24 @@ shipMap.sateView = new XYZ({
|
||||
url:
|
||||
'http://mt{0-1}.google.cn/maps/vt?lyrs=s@198&hl=zh-CN&gl=CN&&x={x}&y={y}&z={z}'
|
||||
})
|
||||
// 创建卫星图图层
|
||||
shipMap.sateLayer = new TileLayer({
|
||||
preload: Infinity,
|
||||
source: shipMap.sateView,
|
||||
zIndex: 1
|
||||
})
|
||||
|
||||
|
||||
// 初始化天地图图层组
|
||||
shipMap.tdtLayer = new Group({
|
||||
layers: [
|
||||
// 天地图矢量底图
|
||||
new TileLayer({
|
||||
source: new XYZ({
|
||||
crossOrigin: 'anonymous',
|
||||
url: 'https://t{0-7}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=f68226212bdd3ffed1b0bb884f81ddda'
|
||||
})
|
||||
}),
|
||||
// 天地图矢量注记
|
||||
new TileLayer({
|
||||
source: new XYZ({
|
||||
crossOrigin: 'anonymous',
|
||||
@@ -240,7 +278,7 @@ shipMap.tdtLayer = new Group({
|
||||
})
|
||||
]
|
||||
})
|
||||
//分布图
|
||||
// 初始化船舶分布图层
|
||||
shipMap.distributeLayer = new TileLayer({
|
||||
preload: Infinity,
|
||||
visible: true,
|
||||
@@ -259,7 +297,7 @@ shipMap.distributeLayer = new TileLayer({
|
||||
})
|
||||
|
||||
|
||||
//船舶
|
||||
// 初始化船舶数据源
|
||||
shipMap.sourceList.shipSource = new SourceVector()
|
||||
shipMap.layerList.shipLayer = new Vector({
|
||||
source: shipMap.sourceList.shipSource,
|
||||
@@ -267,8 +305,9 @@ shipMap.layerList.shipLayer = new Vector({
|
||||
style: (f, r) => shipStyle.newshipStyle(f, r, shipMap.map),
|
||||
zIndex: 21
|
||||
})
|
||||
//船舶
|
||||
// 初始化车辆数据源
|
||||
shipMap.sourceList.carSource = new SourceVector()
|
||||
// 创建车辆图层
|
||||
shipMap.layerList.carLayer = new Vector({
|
||||
source: shipMap.sourceList.carSource,
|
||||
name: 'carLayer',
|
||||
@@ -277,28 +316,31 @@ shipMap.layerList.carLayer = new Vector({
|
||||
})
|
||||
|
||||
|
||||
// 港资源
|
||||
// 初始化港口数据源
|
||||
shipMap.sourceList.portSource = new SourceVector()
|
||||
// 创建港口图层
|
||||
shipMap.layerList.portLayer = new Vector({
|
||||
source: shipMap.sourceList.portSource,
|
||||
zIndex: 15
|
||||
})
|
||||
|
||||
// 泊位图层资源
|
||||
// 初始化泊位数据源
|
||||
shipMap.sourceList.berthSource = new SourceVector()
|
||||
// 创建泊位图层
|
||||
shipMap.layerList.berthLayer = new Vector({
|
||||
source: shipMap.sourceList.berthSource,
|
||||
zIndex: 17
|
||||
})
|
||||
|
||||
//轨迹
|
||||
// 初始化轨迹路径数据源
|
||||
shipMap.sourceList.pathLineSource = new SourceVector()
|
||||
// 创建轨迹路径图层
|
||||
shipMap.layerList.pathLineLayer = new Vector({
|
||||
source: shipMap.sourceList.pathLineSource,
|
||||
zIndex: 4
|
||||
})
|
||||
|
||||
// 轨迹上的点
|
||||
// 初始化轨迹点数据源
|
||||
shipMap.sourceList.pathPointSource = new SourceVector()
|
||||
shipMap.layerList.pathPointLayer = new Vector({
|
||||
source: shipMap.sourceList.pathPointSource,
|
||||
@@ -306,20 +348,24 @@ shipMap.layerList.pathPointLayer = new Vector({
|
||||
})
|
||||
|
||||
|
||||
// 地图上显示的点
|
||||
// 初始化地图标记点数据源
|
||||
shipMap.sourceList.PointSource = new SourceVector()
|
||||
// 创建地图标记点图层
|
||||
shipMap.layerList.PointLayer = new Vector({
|
||||
source: shipMap.sourceList.PointSource,
|
||||
zIndex: 5
|
||||
})
|
||||
|
||||
// 定义台风警戒线样式
|
||||
var lineStyle = new Style({
|
||||
stroke: new Stroke({
|
||||
color: '#FF0000',
|
||||
width: 1
|
||||
})
|
||||
});
|
||||
// 初始化台风警戒线数据源
|
||||
shipMap.sourceList.jjxSource = new SourceVector();
|
||||
// 创建台风警戒线图层
|
||||
shipMap.layerList.jjxLayer = new Vector({
|
||||
source: shipMap.sourceList.jjxSource,
|
||||
style: lineStyle,
|
||||
@@ -327,7 +373,9 @@ shipMap.layerList.jjxLayer = new Vector({
|
||||
zIndex: 3
|
||||
});
|
||||
|
||||
// 初始化台风数据源
|
||||
shipMap.sourceList.taifeng = new SourceVector();
|
||||
// 创建台风图层
|
||||
shipMap.layerList.taifengLayer = new Vector({
|
||||
source: shipMap.sourceList.taifeng,
|
||||
style: function (feature, res) {
|
||||
@@ -355,11 +403,13 @@ var max = [50.9, 17.1, 24.4, 32.6, 41.4, 1000];
|
||||
function getTyphoonStyle(f, r) {
|
||||
var maxWindSpeed = f.get('maxWindSpeed');
|
||||
var level = 0;
|
||||
// 确定台风等级
|
||||
for (var i = 0; i <= 5; i++) {
|
||||
if (min[i] <= maxWindSpeed && maxWindSpeed <= max[i]) {
|
||||
level = i;
|
||||
}
|
||||
}
|
||||
// 根据等级设置颜色
|
||||
var color = '';
|
||||
switch (level) {
|
||||
case 0:
|
||||
@@ -384,6 +434,7 @@ function getTyphoonStyle(f, r) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 创建主样式
|
||||
var s = new Style({
|
||||
fill: new Fill({
|
||||
color: color
|
||||
@@ -399,6 +450,7 @@ function getTyphoonStyle(f, r) {
|
||||
})
|
||||
})
|
||||
});
|
||||
// 在高分辨率下显示预报信息
|
||||
if (r < 3000) {
|
||||
var ntext = new Text({
|
||||
textAlign: "left",
|
||||
@@ -418,6 +470,7 @@ function getTyphoonStyle(f, r) {
|
||||
s.setText(ntext);
|
||||
}
|
||||
|
||||
// 创建时间文本样式
|
||||
const style2 = new Style({
|
||||
text: new Text({
|
||||
textAlign: "left",
|
||||
@@ -438,6 +491,12 @@ function getTyphoonStyle(f, r) {
|
||||
return [s, style2];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取台风预报点样式
|
||||
* @param {Feature} f - 台风要素
|
||||
* @param {number} r - 分辨率
|
||||
* @returns {Array<Style>} 样式数组
|
||||
*/
|
||||
function getTyphoonFutureStyle(f, r) {
|
||||
var maxWindSpeed = f.get('maxWindSpeed');
|
||||
|
||||
@@ -529,6 +588,12 @@ function getTyphoonFutureStyle(f, r) {
|
||||
return [s, style2];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取台风路径线样式
|
||||
* @param {Feature} f - 台风要素
|
||||
* @param {number} r - 分辨率
|
||||
* @returns {Array<Style>} 样式数组
|
||||
*/
|
||||
function getTyphoonStyleLine(f, r) {
|
||||
var ss = [];
|
||||
var s = new Style({
|
||||
@@ -584,7 +649,7 @@ function getTyphoonStyleLine(f, r) {
|
||||
return ss;
|
||||
}
|
||||
|
||||
//船舶选择框
|
||||
// 船舶选择框数据源和图层
|
||||
shipMap.sourceList.selectSource = new SourceVector()
|
||||
shipMap.layerList.selectLayer = new Vector({
|
||||
source: shipMap.sourceList.selectSource,
|
||||
@@ -662,8 +727,7 @@ shipMap.layerList.circlePathLayer = new Vector({
|
||||
source: shipMap.sourceList.circlePath,
|
||||
zIndex: 10
|
||||
})
|
||||
//我的修改
|
||||
//eez线
|
||||
// EEZ线(专属经济区线)图层(用户添加)
|
||||
shipMap.sourceList.eezSource = new XYZ({
|
||||
cacheSize: 256,
|
||||
tileUrlFunction: function (xyz, obj1, obj2) {
|
||||
@@ -882,76 +946,105 @@ shipMap.layerList.pLayer.setZIndex(6);
|
||||
})
|
||||
})
|
||||
|
||||
//监听返回zoom
|
||||
// 设置选中的港口
|
||||
shipFun.getSelectPortFun = function (selectPort) {
|
||||
shipMap.__selectPort = selectPort
|
||||
}
|
||||
|
||||
//九方温度
|
||||
/**
|
||||
* 加载九方温度图层
|
||||
* @param {string} url - 温度数据URL
|
||||
*/
|
||||
shipFun.loadTemp = function (url) {
|
||||
// 如果气象图层不存在,添加到地图
|
||||
if (!hasLayerInMap(shipMap.layerList.iLayer)) {
|
||||
shipMap.map.addLayer(shipMap.layerList.iLayer)
|
||||
}
|
||||
// 如果行政区划图层不存在,添加到地图
|
||||
if (!hasLayerInMap(shipMap.layerList.vtLayer)) {
|
||||
shipMap.map.addLayer(shipMap.layerList.vtLayer)
|
||||
}
|
||||
// 设置温度图层参数
|
||||
mapClient.colorMapTileLayer.setOption({
|
||||
url: url,
|
||||
factor: Factor.Temp,
|
||||
})
|
||||
// 刷新气象图层
|
||||
sourceImageCanvas.refresh()
|
||||
|
||||
}
|
||||
// 加载气压
|
||||
shipFun.loadPressure = function (url) {
|
||||
// 如果气象图层不存在,添加到地图
|
||||
if (!hasLayerInMap(shipMap.layerList.iLayer)) {
|
||||
shipMap.map.addLayer(shipMap.layerList.iLayer)
|
||||
}
|
||||
// 如果行政区划图层不存在,添加到地图
|
||||
if (!hasLayerInMap(shipMap.layerList.vtLayer)) {
|
||||
shipMap.map.addLayer(shipMap.layerList.vtLayer)
|
||||
}
|
||||
// 气压色斑图
|
||||
// 设置气压图层参数
|
||||
mapClient.colorMapTileLayer.setOption({
|
||||
url: url,
|
||||
factor: Factor.Pressure,
|
||||
})
|
||||
// 刷新气象图层
|
||||
sourceImageCanvas.refresh()
|
||||
}
|
||||
// 加载风场
|
||||
|
||||
/**
|
||||
* 加载风场图层
|
||||
* @param {string} url - 风场数据URL
|
||||
*/
|
||||
shipFun.loadWind = function (url) {
|
||||
// 如果气象图层不存在,添加到地图
|
||||
if (!hasLayerInMap(shipMap.layerList.iLayer)) {
|
||||
shipMap.map.addLayer(shipMap.layerList.iLayer)
|
||||
}
|
||||
// 如果行政区划图层不存在,添加到地图
|
||||
if (!hasLayerInMap(shipMap.layerList.vtLayer)) {
|
||||
shipMap.map.addLayer(shipMap.layerList.vtLayer)
|
||||
}
|
||||
// 设置风场图层参数
|
||||
mapClient.colorMapTileLayer.setOption({
|
||||
url: url,
|
||||
factor: Factor.Wind,
|
||||
})
|
||||
// 刷新气象图层
|
||||
sourceImageCanvas.refresh()
|
||||
}
|
||||
// 加载洋流
|
||||
|
||||
/**
|
||||
* 加载洋流图层
|
||||
* @param {string} url - 洋流数据URL
|
||||
*/
|
||||
shipFun.loadSeacurrents = function (url) {
|
||||
// 如果气象图层不存在,添加到地图
|
||||
if (!hasLayerInMap(shipMap.layerList.iLayer)) {
|
||||
shipMap.map.addLayer(shipMap.layerList.iLayer)
|
||||
}
|
||||
// 如果行政区划图层不存在,添加到地图
|
||||
if (!hasLayerInMap(shipMap.layerList.vtLayer)) {
|
||||
shipMap.map.addLayer(shipMap.layerList.vtLayer)
|
||||
}
|
||||
// 气压色斑图
|
||||
// 设置洋流图层参数
|
||||
mapClient.colorMapTileLayer.setOption({
|
||||
url: url,
|
||||
factor: Factor.SeaCurrents,
|
||||
})
|
||||
// 刷新气象图层
|
||||
sourceImageCanvas.refresh()
|
||||
}
|
||||
//加载洋流粒子
|
||||
/**
|
||||
* 加载洋流粒子动画
|
||||
* @param {string} url - 洋流粒子数据URL
|
||||
*/
|
||||
shipFun.loadNineParticleSeacurrents = function (url) {
|
||||
// 如果粒子图层不存在,添加到地图
|
||||
if (!hasLayerInMap(shipMap.layerList.pLayer)) {
|
||||
shipMap.map.addLayer(shipMap.layerList.pLayer)
|
||||
}
|
||||
// 粒子动画
|
||||
// 配置粒子动画参数
|
||||
mapClient.particleAnimationLayer.setConfig({
|
||||
lineWidth: 0.95,
|
||||
speedFactor: 1.8,
|
||||
@@ -964,32 +1057,42 @@ shipFun.loadNineParticleSeacurrents = function (url) {
|
||||
1.0: 'rgba(255,255,255,0.5)',
|
||||
}
|
||||
})
|
||||
// 设置粒子动画数据源
|
||||
mapClient.particleAnimationLayer.setOption({
|
||||
url: url,
|
||||
type: 'image',
|
||||
factor: Factor.SeaCurrents,
|
||||
})
|
||||
}
|
||||
//加载风粒子
|
||||
/**
|
||||
* 加载风粒子动画
|
||||
* @param {string} url - 风粒子数据URL
|
||||
*/
|
||||
shipFun.loadNineParticleWind = function (url) {
|
||||
// 如果粒子图层不存在,添加到地图
|
||||
if (!hasLayerInMap(shipMap.layerList.pLayer)) {
|
||||
shipMap.map.addLayer(shipMap.layerList.pLayer)
|
||||
}
|
||||
// 粒子动画
|
||||
// 配置粒子动画参数
|
||||
mapClient.particleAnimationLayer.setConfig({
|
||||
lineWidth: 0.95,
|
||||
speedFactor: 0.2,
|
||||
fadeOpacity: 0.85,
|
||||
particlesNumber: 15000
|
||||
lineWidth: 0.95, // 线条宽度
|
||||
speedFactor: 0.2, // 速度因子
|
||||
fadeOpacity: 0.85, // 衰减透明度
|
||||
particlesNumber: 15000 // 粒子数量
|
||||
})
|
||||
// 设置粒子动画数据源
|
||||
mapClient.particleAnimationLayer.setOption({
|
||||
url: url,
|
||||
type: 'image',
|
||||
factor: Factor.Wind,
|
||||
})
|
||||
}
|
||||
// 加载等值线
|
||||
/**
|
||||
* 加载等值线图层
|
||||
* @param {string} url - 等值线数据URL
|
||||
*/
|
||||
shipFun.loadIsobar = function (url) {
|
||||
// 如果等值线图层不存在,创建并添加到地图
|
||||
if (!hasLayerInMap(shipMap.layerList.isobarLayer)) {
|
||||
shipMap.layerList.isobarLayer = new Vector({
|
||||
source: new SourceVector({
|
||||
@@ -998,6 +1101,7 @@ shipFun.loadIsobar = function (url) {
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
style: function (feature) {
|
||||
// 设置等值线文本
|
||||
if (shipStyle.isobarStyle && shipStyle.isobarStyle.getText()) {
|
||||
shipStyle.isobarStyle.getText().setText(feature.get('values_'))
|
||||
}
|
||||
@@ -1009,32 +1113,50 @@ shipFun.loadIsobar = function (url) {
|
||||
}
|
||||
}
|
||||
|
||||
//隐藏台风警戒线
|
||||
/**
|
||||
* 隐藏台风警戒线
|
||||
*/
|
||||
shipFun.hidejjx = function () {
|
||||
shipMap.layerList.jjxLayer.setVisible(false)
|
||||
}
|
||||
|
||||
//显示台风警戒线
|
||||
/**
|
||||
* 显示台风警戒线
|
||||
*/
|
||||
shipFun.showjjx = function () {
|
||||
shipMap.layerList.jjxLayer.setVisible(true)
|
||||
}
|
||||
|
||||
//清除九方气象
|
||||
/**
|
||||
* 清除九方气象图层
|
||||
*/
|
||||
shipFun.clearJfWeather = function () {
|
||||
shipMap.map.removeLayer(shipMap.layerList.iLayer)
|
||||
shipMap.map.removeLayer(shipMap.layerList.vtLayer)
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除九方气象等值线图层
|
||||
*/
|
||||
shipFun.clearJfWeatherIsobar = function () {
|
||||
if (hasLayerInMap(shipMap.layerList.isobarLayer)) {
|
||||
shipMap.map.removeLayer(shipMap.layerList.isobarLayer)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 清除九方粒子图层
|
||||
*/
|
||||
shipFun.clearJfParticle = function () {
|
||||
if (hasLayerInMap(shipMap.layerList.pLayer)) {
|
||||
shipMap.map.removeLayer(shipMap.layerList.pLayer)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 显示港口
|
||||
* @param {Object} portInfo - 港口信息
|
||||
*/
|
||||
shipFun.showPort = function (portInfo) {
|
||||
// 坐标转换:从WGS84到Web墨卡托
|
||||
let coor = transform(
|
||||
[portInfo.lon, portInfo.lat],
|
||||
'EPSG:4326',
|
||||
@@ -1058,7 +1180,12 @@ shipFun.showPort = function (portInfo) {
|
||||
shipMap.sourceList.portSource.addFeature(f)
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示泊位
|
||||
* @param {Object} berthInfo - 泊位信息
|
||||
*/
|
||||
shipFun.showBerth = function (berthInfo) {
|
||||
// 坐标转换:从WGS84到Web墨卡托
|
||||
let coor = transform(
|
||||
[berthInfo.decLongitude, berthInfo.decLatitude],
|
||||
'EPSG:4326',
|
||||
@@ -1073,23 +1200,37 @@ shipFun.showBerth = function (berthInfo) {
|
||||
berthLon: berthInfo.decLongitude,
|
||||
berthLat: berthInfo.decLatitude,
|
||||
})
|
||||
f.setStyle(shipStyle.berthStyle(f))
|
||||
f.set('geom', geom)
|
||||
f.setId('berth-' + berthInfo.berthId)
|
||||
shipMap.sourceList.berthSource.addFeature(f)
|
||||
|
||||
f.setStyle(shipStyle.berthStyle(f)) // 设置泊位样式
|
||||
f.set('geom', geom) // 存储几何对象
|
||||
f.setId('berth-' + berthInfo.berthId) // 设置唯一ID
|
||||
shipMap.sourceList.berthSource.addFeature(f) // 添加到泊位数据源
|
||||
}
|
||||
// 清除所有泊位
|
||||
/**
|
||||
* 清除所有泊位
|
||||
* @param {Map} map - 地图实例
|
||||
* @returns {boolean} 清除结果
|
||||
*/
|
||||
shipFun.clearallBerth = (map) => {
|
||||
shipMap.sourceList.berthSource.clear()
|
||||
shipMap.sourceList.berthSource.clear() // 清空泊位数据源
|
||||
return true
|
||||
}
|
||||
//清除所有港口
|
||||
|
||||
/**
|
||||
* 清除所有港口
|
||||
* @param {Map} map - 地图实例
|
||||
* @returns {boolean} 清除结果
|
||||
*/
|
||||
shipFun.clearallPort = (map) => {
|
||||
shipMap.sourceList.portSource.clear()
|
||||
return true
|
||||
}
|
||||
//判定图层是否存在map
|
||||
//判断当前图层是否存在地图中
|
||||
|
||||
/**
|
||||
* 判断图层是否存在于地图中
|
||||
* @param {Layer} layer - 要检查的图层
|
||||
* @returns {boolean} 检查结果
|
||||
*/
|
||||
function hasLayerInMap(layer) {
|
||||
var layers = shipMap.map.getLayers()
|
||||
for (var i = 0; i < layers.getLength(); i++) {
|
||||
@@ -1101,18 +1242,33 @@ function hasLayerInMap(layer) {
|
||||
return false
|
||||
}
|
||||
|
||||
//清除所有船舶
|
||||
/**
|
||||
* 清除所有船舶
|
||||
* @param {Map} map - 地图实例
|
||||
* @returns {boolean} 清除结果
|
||||
*/
|
||||
shipFun.clearallship = (map) => {
|
||||
shipMap.sourceList.shipSource.clear()
|
||||
shipMap.sourceList.shipSource.clear() // 清空船舶数据源
|
||||
return true
|
||||
}
|
||||
/**
|
||||
* 清除所有车辆
|
||||
* @param {Map} map - 地图实例
|
||||
* @returns {boolean} 清除结果
|
||||
*/
|
||||
shipFun.clearAllCar = (map) => {
|
||||
shipMap.sourceList.carSource.clear()
|
||||
shipMap.sourceList.carSource.clear() // 清空车辆数据源
|
||||
return true
|
||||
}
|
||||
/**
|
||||
* 添加车辆
|
||||
* @param {Array} data - 车辆数据数组
|
||||
* @param {Map} map - 地图实例
|
||||
*/
|
||||
shipFun.addCar = (data, map) => {
|
||||
const source = shipMap.sourceList.carSource
|
||||
const features = source.getFeatures()
|
||||
// 移除已存在的车辆要素
|
||||
if (features) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const item = data[i]
|
||||
@@ -1123,10 +1279,12 @@ shipFun.addCar = (data, map) => {
|
||||
})
|
||||
}
|
||||
}
|
||||
// 创建新的车辆要素
|
||||
const newFeatures = []
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const item = data[i]
|
||||
if(item.carNum){
|
||||
// 创建点几何对象
|
||||
const f = new Feature({
|
||||
geometry: new Point(transform([Number(item.longitude), Number(item.latitude)], 'EPSG:4326', 'EPSG:3857'))
|
||||
})
|
||||
@@ -1138,15 +1296,22 @@ shipFun.addCar = (data, map) => {
|
||||
newFeatures.push(f)
|
||||
}
|
||||
}
|
||||
// 添加新的车辆要素到数据源
|
||||
source.addFeatures(newFeatures)
|
||||
}
|
||||
/**
|
||||
* 判断点在线段的南北方向
|
||||
* @param {Array} lines - 线段的坐标数组
|
||||
* @param {Array} point - 要判断的点坐标
|
||||
* @returns {boolean} true表示点在线段南边,false表示点在线段北边
|
||||
*/
|
||||
function identifySouOrNor(lines, point) {
|
||||
// 将线段的点切割为数组,数组的每个元素为一条线段
|
||||
const lineData = []
|
||||
for(let i = 0; i<lines.length-1; i++){
|
||||
lineData.push([lines[i], lines[i+1]])
|
||||
}
|
||||
//先根据经度判断。这个点垂直投影在哪一条线段上
|
||||
// 先根据经度判断,这个点垂直投影在哪一条线段上
|
||||
let projectionLine = []
|
||||
lineData.forEach(line => {
|
||||
if(point[0]>line[0][0] && point[0]<line[1][0]){
|
||||
@@ -1155,6 +1320,7 @@ function identifySouOrNor(lines, point) {
|
||||
})
|
||||
// 判断这个点是在线段的上(北)还是下(南)
|
||||
if(projectionLine.length == 0){
|
||||
// 如果没有找到投影线段,比较点的纬度与所有线段点的最大纬度
|
||||
const latitudeArr = []
|
||||
lines.map(item => {
|
||||
latitudeArr.push(item[1])
|
||||
@@ -1166,6 +1332,7 @@ function identifySouOrNor(lines, point) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// 处理水平线情况
|
||||
if (projectionLine[0][1] == projectionLine[1][1]) {
|
||||
if (point[1]<projectionLine[0][1]) {
|
||||
return true
|
||||
@@ -1173,6 +1340,7 @@ function identifySouOrNor(lines, point) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// 使用线性方程判断点在线段的哪一侧
|
||||
const A = projectionLine[1][1] - projectionLine[0][1]
|
||||
const B = projectionLine[0][0] - projectionLine[1][0]
|
||||
const C = projectionLine[1][0]*projectionLine[1][1] - projectionLine[0][0]*projectionLine[1][1]
|
||||
@@ -1183,11 +1351,18 @@ function identifySouOrNor(lines, point) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
//添加 船舶
|
||||
/**
|
||||
* 添加船舶
|
||||
* @param {Array} dataList - 船舶数据数组
|
||||
* @param {number} zoom - 缩放级别
|
||||
* @param {Map} map - 地图实例
|
||||
* @param {Array} selectlist - 选中的船舶列表
|
||||
*/
|
||||
shipFun.addShip = (dataList, zoom, map, selectlist) => {
|
||||
// shipMap.sourceList.shipSource.clear()
|
||||
for (let i = 0; i < dataList.length; i++) {
|
||||
const element = dataList[i]
|
||||
// 坐标转换:将经纬度(单位:分)转换为Web墨卡托
|
||||
let coor = transform(
|
||||
[dataList[i].n / 600000, dataList[i].a / 600000],
|
||||
'EPSG:4326',
|
||||
@@ -1201,25 +1376,25 @@ shipFun.addShip = (dataList, zoom, map, selectlist) => {
|
||||
let f = new Feature({
|
||||
geometry: geom, //添加点图形
|
||||
type: 'ship',
|
||||
shiptype: element.y,
|
||||
mmsi: element.m,
|
||||
heading: element.h,
|
||||
callsign: element.g,
|
||||
cog: element.c,
|
||||
imo: element.o,
|
||||
sog: element.s,
|
||||
aisNavStatus: element.v,
|
||||
length: element.l,
|
||||
destPort: element.p,
|
||||
breadth: element.b,
|
||||
eta: element.r,
|
||||
draught: element.d,
|
||||
posTime: element.t,
|
||||
shipId: element.i,
|
||||
lon: dataList[i].n,
|
||||
lat: dataList[i].a,
|
||||
shipnameEn: dataList[i].e,
|
||||
color: element.color
|
||||
shiptype: element.y, // 船舶类型
|
||||
mmsi: element.m, // MMSI号
|
||||
heading: element.h, // 航向
|
||||
callsign: element.g, // 呼号
|
||||
cog: element.c, // 对地航向
|
||||
imo: element.o, // IMO号
|
||||
sog: element.s, // 对地航速
|
||||
aisNavStatus: element.v, // AIS导航状态
|
||||
length: element.l, // 长度
|
||||
destPort: element.p, // 目的港
|
||||
breadth: element.b, // 宽度
|
||||
eta: element.r, // 预计到达时间
|
||||
draught: element.d, // 吃水
|
||||
posTime: element.t, // 位置时间
|
||||
shipId: element.i, // 船舶ID
|
||||
lon: dataList[i].n, // 经度
|
||||
lat: dataList[i].a, // 纬度
|
||||
shipnameEn: dataList[i].e, // 英文船名
|
||||
color: element.color // 颜色
|
||||
})
|
||||
f.setId(dataList[i].i)
|
||||
f.set('geom', geom)
|
||||
@@ -1227,7 +1402,12 @@ shipFun.addShip = (dataList, zoom, map, selectlist) => {
|
||||
}
|
||||
}
|
||||
|
||||
shipFun.getShipFeaturesByIds = (shipIds) => { //根据shipId找到对应的feature
|
||||
/**
|
||||
* 根据船舶ID获取船舶要素
|
||||
* @param {Array} shipIds - 船舶ID数组
|
||||
* @returns {Array} 船舶要素数组
|
||||
*/
|
||||
shipFun.getShipFeaturesByIds = (shipIds) => {
|
||||
const features = []
|
||||
shipIds.forEach(id => {
|
||||
let f = shipMap.sourceList.shipSource.getFeatureById(id)
|
||||
@@ -1244,10 +1424,17 @@ shipFun.getCarFeaturesByIds = (carIds) => { //根据shipId找到对应的featur
|
||||
return features
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘图相关函数
|
||||
* @param {number} number - 绘图参数
|
||||
*/
|
||||
shipFun.plotting = function (number) {
|
||||
shipStyle.plotting(number)
|
||||
}
|
||||
//添加全屏控件
|
||||
/**
|
||||
* 添加全屏控件
|
||||
* @param {Map} map - 地图实例
|
||||
*/
|
||||
shipFun.addFullScreen = (map) => {
|
||||
let FullScreenControl = new FullScreen({
|
||||
// units: 'metric',
|
||||
@@ -1257,7 +1444,10 @@ shipFun.addFullScreen = (map) => {
|
||||
map.addControl(FullScreenControl)
|
||||
}
|
||||
|
||||
//添加比例尺控件
|
||||
/**
|
||||
* 添加比例尺控件
|
||||
* @param {Map} map - 地图实例
|
||||
*/
|
||||
shipFun.addScaleLine = (map) => {
|
||||
let scaleLineControl = new ScaleLine({
|
||||
units: 'nautical',
|
||||
@@ -1783,14 +1973,21 @@ shipFun.addMousePos = function (map) {
|
||||
shipFun.hideShips = (idList) => {
|
||||
let type = typeof idList
|
||||
if (type == 'string') {
|
||||
// 隐藏单个船舶
|
||||
let f = shipMap.sourceList.shipSource.getFeatureById(idList)
|
||||
if (f) {
|
||||
shipMap.sourceList.shipSource.removeFeature(f)
|
||||
} else if (type == 'object') {
|
||||
idList.forEach((x, i) => {
|
||||
let f = shipMap.sourceList.shipSource.getFeatureById(x)
|
||||
}
|
||||
} else if (Array.isArray(idList)) {
|
||||
// 隐藏多个船舶(遍历逐个移除,兼容不支持removeFeatures的OpenLayers版本)
|
||||
if (idList.length === 0) return ''
|
||||
|
||||
idList.forEach(id => {
|
||||
let f = shipMap.sourceList.shipSource.getFeatureById(id)
|
||||
if (f) {
|
||||
shipMap.sourceList.shipSource.removeFeature(f)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
@@ -1,57 +1,68 @@
|
||||
<template>
|
||||
<div class="my-ships-main" id="map">
|
||||
<!--气象点击显示内容-->
|
||||
<!-- 气象点击显示内容组件 -->
|
||||
<OnClickWeather></OnClickWeather>
|
||||
<!-- 港口鼠标悬浮显示内容 -->
|
||||
<!-- 港口鼠标悬浮显示内容组件 -->
|
||||
<PortHoverView></PortHoverView>
|
||||
<!--船舶鼠标悬浮时显示信息-->
|
||||
<!-- 船舶鼠标悬浮时显示信息组件 -->
|
||||
<ShipHoverView></ShipHoverView>
|
||||
<!-- 地图底部船舶类型备注框-->
|
||||
<MapBottomShipType></MapBottomShipType>
|
||||
<!-- 地图底部鼠标位置经纬度显示-->
|
||||
<!-- 地图底部船舶类型备注框组件 -->
|
||||
<MapBottomShipType :carData="carData" :shipData="shipData"></MapBottomShipType>
|
||||
<!-- 地图底部鼠标位置经纬度显示组件 -->
|
||||
<MapBottomMousePos></MapBottomMousePos>
|
||||
<!-- 弹窗最小化-->
|
||||
<!-- 弹窗最小化组件 -->
|
||||
<MiniBox></MiniBox>
|
||||
<!-- 船舶轨迹鼠标悬浮时显示信息-->
|
||||
<!-- 船舶轨迹鼠标悬浮时显示信息组件 -->
|
||||
<TrackHoverView></TrackHoverView>
|
||||
<!-- 消息列表循环滚动展示-->
|
||||
<!-- 消息列表循环滚动展示组件 -->
|
||||
<realTimeInfo></realTimeInfo>
|
||||
<!-- 显示全部港口 -->
|
||||
<!-- 显示全部港口组件 -->
|
||||
<ViewAllPort></ViewAllPort>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
// 地图工具函数集合
|
||||
import ShipFun from '@/util/map/map.js'
|
||||
// Vue装饰器
|
||||
import {Component, Vue} from 'vue-property-decorator'
|
||||
// 状态管理工具
|
||||
import storeUtil from '@/util/store'
|
||||
import OnClickWeather from "@/components/on-map-view/OnClickWeather.vue";
|
||||
import PortHoverView from "@/components/on-map-view/PortHoverView.vue";
|
||||
import ShipHoverView from "@/components/on-map-view/ShipHoverView.vue";
|
||||
import MapBottomShipType from "@/components/on-map-view/MapBottomShipType.vue";
|
||||
import MapBottomMousePos from "@/components/on-map-view/MapBottomMousePos.vue";
|
||||
import MiniBox from "@/components/on-map-view/MiniBox.vue";
|
||||
import TrackHoverView from "@/components/on-map-view/TrackHoverView.vue";
|
||||
import realTimeInfo from "@/components/real-time-info/realTimeInfo.vue";
|
||||
import HttpApi from "@/api";
|
||||
import DialogUtil from "@/util/new-dialog";
|
||||
import PortQueryTemp from '../new-dialog/PortQueryTemp.vue';
|
||||
import {DialogType} from '@/util/temp-interface';
|
||||
import {SearchLogUtil} from "@/util/tool";
|
||||
import bus from '@/util/bus';
|
||||
import ShipInfoTemp from '../new-dialog/ShipInfoTemp.vue';
|
||||
import CarInfoTemp from '../new-dialog/CarInfoTemp.vue';
|
||||
import ViewAllPort from "@/components/on-map-view/ViewAllPort.vue";
|
||||
import {Style} from 'ol/style.js'
|
||||
import Icon from 'ol/style/Icon'
|
||||
import styleText from 'ol/style/Text' //添加文字标注
|
||||
import styleFill from 'ol/style/Fill' //添加填充样式
|
||||
import styleStroke from 'ol/style/Stroke' //添加填充样式
|
||||
|
||||
const warningImg = require('../../util/map/img/shipWarningIcon.png')
|
||||
const config = require('../../../public/config/sys-config.json')
|
||||
const elementResizeDetectorMaker = require("element-resize-detector")
|
||||
// 组件导入
|
||||
import OnClickWeather from "@/components/on-map-view/OnClickWeather.vue"; // 气象点击显示组件
|
||||
import PortHoverView from "@/components/on-map-view/PortHoverView.vue"; // 港口悬浮显示组件
|
||||
import ShipHoverView from "@/components/on-map-view/ShipHoverView.vue"; // 船舶悬浮显示组件
|
||||
import MapBottomShipType from "@/components/on-map-view/MapBottomShipType.vue"; // 船舶类型备注组件
|
||||
import MapBottomMousePos from "@/components/on-map-view/MapBottomMousePos.vue"; // 鼠标位置显示组件
|
||||
import MiniBox from "@/components/on-map-view/MiniBox.vue"; // 弹窗最小化组件
|
||||
import TrackHoverView from "@/components/on-map-view/TrackHoverView.vue"; // 轨迹悬浮显示组件
|
||||
import realTimeInfo from "@/components/real-time-info/realTimeInfo.vue"; // 实时消息组件
|
||||
import ViewAllPort from "@/components/on-map-view/ViewAllPort.vue"; // 显示全部港口组件
|
||||
// API调用
|
||||
import HttpApi from "@/api"; // HTTP请求API
|
||||
// 弹窗工具
|
||||
import DialogUtil from "@/util/new-dialog"; // 弹窗管理工具
|
||||
// 弹窗模板
|
||||
import PortQueryTemp from '../new-dialog/PortQueryTemp.vue'; // 港口查询弹窗模板
|
||||
import ShipInfoTemp from '../new-dialog/ShipInfoTemp.vue'; // 船舶信息弹窗模板
|
||||
import CarInfoTemp from '../new-dialog/CarInfoTemp.vue'; // 车辆信息弹窗模板
|
||||
// 类型定义
|
||||
import {DialogType,DialogType as DialogType2} from '@/util/temp-interface'; // 弹窗类型枚举'
|
||||
// 工具类
|
||||
import {SearchLogUtil,ShipUtils} from "@/util/tool"; // 搜索日志工具
|
||||
import bus from '@/util/bus'; // 事件总线
|
||||
// OpenLayers样式
|
||||
import {Style} from 'ol/style.js' // 样式基础类
|
||||
import Icon from 'ol/style/Icon' // 图标样式
|
||||
import styleText from 'ol/style/Text' // 文字标注样式
|
||||
import styleFill from 'ol/style/Fill' // 填充样式
|
||||
import styleStroke from 'ol/style/Stroke' // 描边样式
|
||||
// 常量定义
|
||||
const warningImg = require('../../util/map/img/shipWarningIcon.png') // 警告图标
|
||||
const config = require('../../../public/config/sys-config.json') // 系统配置
|
||||
const elementResizeDetectorMaker = require("element-resize-detector") // 元素大小变化检测工具
|
||||
|
||||
// 组件装饰器,注册子组件
|
||||
@Component({
|
||||
components: {
|
||||
OnClickWeather,
|
||||
@@ -66,15 +77,24 @@ const elementResizeDetectorMaker = require("element-resize-detector")
|
||||
}
|
||||
})
|
||||
export default class Main extends Vue {
|
||||
private map: any
|
||||
private map: any // 地图实例对象
|
||||
|
||||
private shipData = []
|
||||
private carData = []
|
||||
private shipData = [] // 船舶数据数组
|
||||
private carData = [] // 车辆数据数组
|
||||
/**
|
||||
* 获取船舶数据并处理
|
||||
* 1. 从API获取船舶分组数据
|
||||
* 2. 提取船舶ID并获取详细信息
|
||||
* 3. 处理船舶数据并添加到地图
|
||||
*/
|
||||
private async getShips() {
|
||||
const ships: any = []
|
||||
// 获取船舶分组数据
|
||||
await HttpApi.getShipRanks({}).then((res: any) => {
|
||||
res.forEach((item: any) => {
|
||||
// 筛选有效的船舶分组
|
||||
if (item.idw !== -1 && item.followShipList && item.followShipList.length) {
|
||||
// 处理每个船舶的分组信息
|
||||
item.followShipList.forEach(async (item2: any) => {
|
||||
item2.groupName = item.name;
|
||||
item2.color = item.color;
|
||||
@@ -84,12 +104,16 @@ export default class Main extends Vue {
|
||||
})
|
||||
})
|
||||
|
||||
// 提取船舶ID数组
|
||||
const shipIds: any[] = []
|
||||
for (let i = 0; i < ships.length; i++) {
|
||||
shipIds.push(ships[i].shipId)
|
||||
}
|
||||
// 处理船舶详细信息,根据ID数量选择不同的请求方式
|
||||
if (shipIds.length <= 100) {
|
||||
// 单次请求获取船舶详细信息
|
||||
await HttpApi.getShipMessage({shipId: shipIds.toString()}).then((res: any[]) => {
|
||||
// 合并船舶详细信息到现有数据
|
||||
for (let i = 0; i < ships.length; i++) {
|
||||
res.forEach((item: any) => {
|
||||
if (ships[i].shipId === item.shipId) {
|
||||
@@ -101,10 +125,12 @@ export default class Main extends Vue {
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 批量请求获取船舶详细信息(每100个ID一组)
|
||||
const p: any[] = []
|
||||
const idGroup = this.spArray(shipIds, 100);
|
||||
for (let i = 0; i < idGroup.length; i++) {
|
||||
const ids = idGroup[i];
|
||||
// 创建批量请求Promise
|
||||
p.push(new Promise((resolve) => {
|
||||
HttpApi.getShipMessage({shipId: ids.toString()}).then((res) => {
|
||||
resolve(res)
|
||||
@@ -113,7 +139,9 @@ export default class Main extends Vue {
|
||||
}
|
||||
|
||||
const newGetShips: any[] = []
|
||||
// 等待所有请求完成
|
||||
await Promise.all(p).then((res) => {
|
||||
// 合并所有返回的船舶数据
|
||||
for (let i = 0; i < res.length; i++) {
|
||||
const shipG: any[] = res[i];
|
||||
for (let j = 0; j < shipG.length; j++) {
|
||||
@@ -122,6 +150,7 @@ export default class Main extends Vue {
|
||||
}
|
||||
})
|
||||
|
||||
// 合并详细信息到现有船舶数据
|
||||
for (let i = 0; i < ships.length; i++) {
|
||||
newGetShips.forEach((item: any) => {
|
||||
if (ships[i].shipId === item.shipId) {
|
||||
@@ -132,93 +161,135 @@ export default class Main extends Vue {
|
||||
})
|
||||
}
|
||||
}
|
||||
// 更新船舶数据
|
||||
this.shipData = ships
|
||||
// 解析船舶数据并添加到地图
|
||||
this.jiexiRanks(ships);
|
||||
// 存储船舶数据到状态管理
|
||||
storeUtil.setShipFleet(ships);
|
||||
// 设置船舶警告(注释掉)
|
||||
// this.setShipWarning(ships);
|
||||
}
|
||||
/**
|
||||
* 获取车辆数据并添加到地图
|
||||
* 1. 从API获取车辆数据
|
||||
* 2. 处理车辆数据格式
|
||||
* 3. 将有效的车辆数据添加到地图
|
||||
* 4. 设置车辆警告
|
||||
*/
|
||||
private getCars() {
|
||||
const carData: any = []
|
||||
// 获取车辆数据
|
||||
HttpApi.getCarInfo().then((res) => {
|
||||
// 处理车辆数据,转换为统一格式
|
||||
for (let i = 0; i < Object.keys(res).length; i++) {
|
||||
const key = Object.keys(res)[i];
|
||||
carData.push({
|
||||
carNum: res[key].carNum,
|
||||
companyName: res[key].companyName,
|
||||
customsCreateDate: res[key].customsCreateDate,
|
||||
gpsTime: res[key].data && res[key].data.GpsTime ? res[key].data.GpsTime : '',
|
||||
latitude: res[key].data && res[key].data.Latitude ? res[key].data.Latitude : '',
|
||||
longitude: res[key].data && res[key].data.Longitude ? res[key].data.Longitude : '',
|
||||
entryId: res[key].entryId,
|
||||
firstRegistrationDate: res[key].firstRegistrationDate,
|
||||
vehicleModel: res[key].vehicleModel
|
||||
carNum: res[key].carNum, // 车牌号
|
||||
companyName: res[key].companyName, // 公司名称
|
||||
customsCreateDate: res[key].customsCreateDate, // 海关创建日期
|
||||
gpsTime: res[key].data && res[key].data.GpsTime ? res[key].data.GpsTime : '', // GPS时间
|
||||
latitude: res[key].data && res[key].data.Latitude ? res[key].data.Latitude : '', // 纬度
|
||||
longitude: res[key].data && res[key].data.Longitude ? res[key].data.Longitude : '', // 经度
|
||||
entryId: res[key].entryId, // 入境ID
|
||||
firstRegistrationDate: res[key].firstRegistrationDate, // 首次注册日期
|
||||
vehicleModel: res[key].vehicleModel // 车辆型号
|
||||
})
|
||||
}
|
||||
// 更新车辆数据
|
||||
this.carData = carData
|
||||
console.log(carData,'carData')
|
||||
// 将有效的车辆数据(有经纬度)添加到地图
|
||||
ShipFun.addCar(carData.filter((item: any) => {
|
||||
return item.latitude && item.longitude
|
||||
}), this.map)
|
||||
// 设置车辆警告
|
||||
this.setCarWarning(carData.filter((item: any) => {
|
||||
return item.latitude && item.longitude
|
||||
}))
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 将数组按指定长度分组
|
||||
* @param {Array} array - 要分组的数组
|
||||
* @param {number} len - 每组的长度
|
||||
* @returns {Array} 分组后的二维数组
|
||||
*/
|
||||
private spArray(array: any[], len: number) {
|
||||
const newArray: any[] = [];
|
||||
item(array, len)
|
||||
|
||||
// 递归分组函数
|
||||
function item(array: any[], len: number) {
|
||||
if (array.length && array.length > len) {
|
||||
// 截取指定长度的数组并添加到结果
|
||||
newArray.push(array.splice(0, len))
|
||||
// 递归处理剩余数组
|
||||
item(array, len);
|
||||
} else if (array.length && array.length < len) {
|
||||
// 将剩余数组作为一组添加到结果
|
||||
newArray.push(array)
|
||||
array = []
|
||||
}
|
||||
}
|
||||
|
||||
// 调用分组函数
|
||||
item(array, len)
|
||||
return newArray
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析船舶数据并添加到地图
|
||||
* @param {Array} data - 船舶数据数组
|
||||
* 将船舶数据转换为地图工具需要的格式,并添加到地图
|
||||
*/
|
||||
private jiexiRanks(data: any) {
|
||||
const newShipList: any = []
|
||||
// 遍历船舶数据,转换为地图工具需要的格式
|
||||
data.forEach((item: any) => {
|
||||
newShipList.push({
|
||||
y: item.shiptype,
|
||||
m: item.mmsi,
|
||||
h: item.heading,
|
||||
g: item.callsign,
|
||||
c: item.cog,
|
||||
o: item.imo,
|
||||
s: item.sog,
|
||||
v: item.aisNavStatus,
|
||||
l: item.length,
|
||||
p: item.destPort,
|
||||
b: item.breadth,
|
||||
r: item.eta,
|
||||
d: item.draught,
|
||||
t: item.posTime,
|
||||
i: item.shipId,
|
||||
n: item.lon,
|
||||
a: item.lat,
|
||||
e: item.shipnameEn,
|
||||
color: item.color,
|
||||
isFleet: true
|
||||
y: item.shiptype, // 船舶类型
|
||||
m: item.mmsi, // MMSI号
|
||||
h: item.heading, // 航向
|
||||
g: item.callsign, // 呼号
|
||||
c: item.cog, // 对地航向
|
||||
o: item.imo, // IMO号
|
||||
s: item.sog, // 对地航速
|
||||
v: item.aisNavStatus, // AIS导航状态
|
||||
l: item.length, // 长度
|
||||
p: item.destPort, // 目的港
|
||||
b: item.breadth, // 宽度
|
||||
r: item.eta, // 预计到达时间
|
||||
d: item.draught, // 吃水
|
||||
t: item.posTime, // 位置时间
|
||||
i: item.shipId, // 船舶ID
|
||||
n: item.lon, // 经度
|
||||
a: item.lat, // 纬度
|
||||
e: item.shipnameEn, // 英文船名
|
||||
color: item.color, // 颜色
|
||||
isFleet: true // 是否为船队
|
||||
})
|
||||
})
|
||||
// 深拷贝数组并添加船舶到地图
|
||||
ShipFun.addShip(JSON.parse(JSON.stringify(newShipList)), 11, storeUtil.getMapInstance())
|
||||
}
|
||||
|
||||
private setShipWarning(ships: any[]) { //将更新时间超出30天的游艇的图标设置为感叹号
|
||||
const nowTime: number = (new Date()).getTime()
|
||||
const temp: string[] = []
|
||||
/**
|
||||
* 设置船舶警告
|
||||
* 将更新时间超出30天的船舶图标设置为感叹号
|
||||
* @param {Array} ships - 船舶数据数组
|
||||
*/
|
||||
private setShipWarning(ships: any[]) {
|
||||
const nowTime: number = (new Date()).getTime() // 当前时间戳
|
||||
const temp: string[] = [] // 超过30天未更新的船舶ID数组
|
||||
// 遍历船舶数据,筛选超过30天未更新的船舶
|
||||
ships.forEach((item: any) => {
|
||||
// 计算船舶数据更新时间与当前时间的差值(天数)
|
||||
let timeDiff: number = item.posTime ? (nowTime - (item.posTime * 1000)) / (24 * 60 * 60 * 1000) : 0
|
||||
if (timeDiff > 30) {
|
||||
temp.push(item.shipId)
|
||||
temp.push(item.shipId) // 添加到警告列表
|
||||
}
|
||||
})
|
||||
// 获取需要警告的船舶要素
|
||||
const features = ShipFun.getShipFeaturesByIds(temp)
|
||||
// 创建警告图标样式
|
||||
const iconStyle = new Style({
|
||||
image: new Icon({
|
||||
color: '#ffffff',
|
||||
@@ -227,21 +298,30 @@ export default class Main extends Vue {
|
||||
scale: 0.18
|
||||
})
|
||||
})
|
||||
// 为超过30天未更新的船舶设置警告图标
|
||||
features.forEach((f: any) => {
|
||||
f.setStyle(iconStyle)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置车辆警告
|
||||
* 将更新时间超出3天的车辆图标设置为感叹号
|
||||
* @param {Array} dataList - 车辆数据数组
|
||||
*/
|
||||
private setCarWarning(dataList: any[]) {
|
||||
const nowTime: number = (new Date()).getTime()
|
||||
const temp: string[] = []
|
||||
const nowTime: number = (new Date()).getTime() // 当前时间戳
|
||||
const temp: string[] = [] // 超过3天未更新的车辆ID数组
|
||||
// 遍历车辆数据,筛选超过3天未更新的车辆
|
||||
dataList.forEach((item: any) => {
|
||||
// 计算车辆数据更新时间与当前时间的差值(天数)
|
||||
let timeDiff: number = item.gpsTime ? (nowTime - new Date(item.gpsTime).getTime()) / (24 * 60 * 60 * 1000) : 0
|
||||
if (timeDiff > 3) {
|
||||
temp.push(item.carNum)
|
||||
temp.push(item.carNum) // 添加到警告列表
|
||||
}
|
||||
})
|
||||
// 获取需要警告的车辆要素
|
||||
const features = ShipFun.getCarFeaturesByIds(temp)
|
||||
// 为每个警告车辆设置警告样式
|
||||
features.forEach((f: any) => {
|
||||
const iconStyle = new Style({
|
||||
image: new Icon({
|
||||
@@ -268,32 +348,58 @@ export default class Main extends Vue {
|
||||
f.setStyle(iconStyle)
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 重新显示所有数据
|
||||
* 从已有的数据中重新添加船舶和车辆到地图,并设置警告
|
||||
*/
|
||||
private showAllData() {
|
||||
//展示所有数据
|
||||
//this.getShips()
|
||||
//this.getCars()
|
||||
// 重新解析船舶数据并添加到地图
|
||||
this.jiexiRanks(this.shipData);
|
||||
// 重新设置船舶警告(注释掉)
|
||||
// this.setShipWarning(this.shipData);
|
||||
// 重新添加车辆数据到地图
|
||||
ShipFun.addCar(this.carData.filter((item: any) => {
|
||||
return item.latitude && item.longitude
|
||||
}), this.map)
|
||||
// 重新设置车辆警告
|
||||
this.setCarWarning(this.carData.filter((item: any) => {
|
||||
return item.latitude && item.longitude
|
||||
}))
|
||||
}
|
||||
/**
|
||||
* 组件挂载完成后的初始化
|
||||
* 1. 初始化地图
|
||||
* 2. 配置地图参数
|
||||
* 3. 添加地图控件
|
||||
* 4. 添加地图事件监听
|
||||
* 5. 获取初始数据
|
||||
*/
|
||||
public mounted() {
|
||||
// 创建地图实例
|
||||
this.map = ShipFun.creatMap()
|
||||
// 更新地图大小
|
||||
this.map.updateSize()
|
||||
// 存储地图实例到状态管理
|
||||
storeUtil.setMapInstance(this.map)
|
||||
// 存储地图工具函数到状态管理
|
||||
storeUtil.setMapFun(ShipFun);
|
||||
// 设置地图实例到工具函数
|
||||
ShipFun.setmap(this.map)
|
||||
// 设置地图中心点
|
||||
ShipFun.setCenter([110, 19]);
|
||||
// 设置地图缩放级别
|
||||
ShipFun.setZoom(9)
|
||||
// 切换地图类型为天地图
|
||||
ShipFun.changeMap(this.map, 'tdt')
|
||||
// 创建测距显示工具
|
||||
ShipFun.createMeasureTooltip(this.map) // 测距显示
|
||||
// 添加全屏按钮(注释掉)
|
||||
// ShipFun.addFullScreen(this.map) // 全屏按钮显示
|
||||
// 添加比例尺
|
||||
ShipFun.addScaleLine(this.map) // 添加比例尺
|
||||
// 添加鼠标位置显示
|
||||
ShipFun.addMousePos(this.map) // 添加显示鼠标位置的经纬度信息
|
||||
// 添加地图缩放监听器
|
||||
ShipFun.addZoomListener(this.map, () => {
|
||||
this.map
|
||||
.getControls()
|
||||
@@ -309,15 +415,20 @@ export default class Main extends Vue {
|
||||
}
|
||||
})
|
||||
})
|
||||
// 添加地图点击事件监听
|
||||
ShipFun.addClick(async (res: any) => {
|
||||
// 处理港口点击
|
||||
if (res.isType === 'port') {
|
||||
let port: any = {}
|
||||
// 获取港口详细信息
|
||||
await HttpApi.getPortInfo(res.portId).then((res2: any) => {
|
||||
port = res2
|
||||
Object.assign(port, res)
|
||||
})
|
||||
// 计算港口坐标
|
||||
port.cLon = port.portLon * 600000
|
||||
port.cLat = port.portLat * 600000
|
||||
// 显示港口查询弹窗
|
||||
DialogUtil.showDialog(PortQueryTemp, DialogType.PORT_QUERY, {
|
||||
dialogData: {
|
||||
title: `${port.nameCn}-${port.nameEn}`,
|
||||
@@ -331,9 +442,11 @@ export default class Main extends Vue {
|
||||
} else if (res.isType === 'ship') {
|
||||
let shipData: any = {}
|
||||
let docData = {}
|
||||
// 获取船舶详细信息
|
||||
await HttpApi.getShipMessage({shipId: res.shipId}).then((res: any) => {
|
||||
const SearchLog = (this as any).$SearchLog
|
||||
let flag = true
|
||||
// 检查是否已存在于搜索日志
|
||||
if (SearchLog.length) {
|
||||
for (let i = 0; i < SearchLog.length; i++) {
|
||||
const item = SearchLog[i]
|
||||
@@ -343,23 +456,27 @@ export default class Main extends Vue {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加到搜索日志
|
||||
if (flag) {
|
||||
SearchLogUtil.addSearchLog(res[0])
|
||||
}
|
||||
// 存储船舶数据到状态管理
|
||||
storeUtil.setShipData(res[0])
|
||||
shipData = res[0]
|
||||
})
|
||||
// 获取船舶文档信息
|
||||
await HttpApi.getShipDoc({shipId: res.shipId}).then((res: any) => {
|
||||
if (res) {
|
||||
docData = res
|
||||
}
|
||||
})
|
||||
// 获取船舶中文名称
|
||||
await HttpApi.getShipCnName({mmsi: shipData.mmsi}).then((res: any) => {
|
||||
if (res) {
|
||||
shipData.shipnameCn = res.nameCn
|
||||
}
|
||||
})
|
||||
// 显示船舶信息弹窗
|
||||
DialogUtil.showDialog(ShipInfoTemp, DialogType.SHIP_INFO, {
|
||||
dialogData: {
|
||||
title: shipData.shipnameCn,
|
||||
@@ -384,15 +501,174 @@ export default class Main extends Vue {
|
||||
})
|
||||
}
|
||||
})
|
||||
// 当侧边栏修改的时候去地图去适应宽高的变化
|
||||
// 监听地图容器大小变化,更新地图大小
|
||||
elementResizeDetectorMaker().listenTo(document.getElementById('map'), () => {
|
||||
this.map.updateSize()
|
||||
})
|
||||
// 获取初始船舶数据
|
||||
this.getShips()
|
||||
// 获取初始车辆数据
|
||||
this.getCars()
|
||||
// 监听全局事件,重新显示所有数据
|
||||
bus.$on('showAllData', () => {
|
||||
this.showAllData()
|
||||
})
|
||||
// 初始化筛选和搜索事件监听
|
||||
this.initFilterEvent()
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化筛选和搜索事件
|
||||
*/
|
||||
private initFilterEvent() {
|
||||
// 类型筛选事件
|
||||
bus.$on('filterTypeChange', (data: any) => {
|
||||
this.handleFilterTypeChange(data)
|
||||
})
|
||||
// 搜索事件
|
||||
bus.$on('filterSearch', (data: any) => {
|
||||
this.handleFilterSearch(data)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理类型筛选变化
|
||||
* @param {Object} data - 筛选数据
|
||||
* @param {string} data.type - 类型:ship, car, yacht
|
||||
* @param {boolean} data.isChecked - 是否勾选
|
||||
*/
|
||||
private handleFilterTypeChange(data: any) {
|
||||
const { type, isChecked } = data
|
||||
switch (type) {
|
||||
case 'ship':
|
||||
if (isChecked) {
|
||||
// 显示船舶
|
||||
const filteredShips = this.shipData.filter((ship: any) => {
|
||||
return ship.shipTypeName !== '其他'
|
||||
})
|
||||
this.jiexiRanks(filteredShips)
|
||||
} else {
|
||||
// 只隐藏船舶,保留游艇
|
||||
const shipIds = this.shipData
|
||||
.filter((ship: any) => ship.shipTypeName !== '其他')
|
||||
.map((ship: any) => ship.shipId)
|
||||
console.log(shipIds,'shipIds')
|
||||
ShipFun.hideShips(shipIds)
|
||||
DialogUtil.closeCom(DialogType.SHIP_INFO)
|
||||
DialogUtil.closeCom(DialogType2.TRACK_RECORD)
|
||||
}
|
||||
break
|
||||
case 'car':
|
||||
if (isChecked) {
|
||||
// 显示车辆
|
||||
ShipFun.addCar(this.carData.filter((item: any) => {
|
||||
return item.latitude && item.longitude
|
||||
}), this.map)
|
||||
} else {
|
||||
// 隐藏车辆
|
||||
ShipFun.clearAllCar(this.map)
|
||||
DialogUtil.closeCom(DialogType.CAR_INFO)
|
||||
DialogUtil.closeCom(DialogType2.TRACK_RECORD)
|
||||
ShipFun.delPath()
|
||||
}
|
||||
break
|
||||
case 'yacht':
|
||||
if (isChecked) {
|
||||
// 显示游艇
|
||||
const yachts = this.shipData.filter((ship: any) => {
|
||||
return ship.shipTypeName === '其他'
|
||||
})
|
||||
this.jiexiRanks(yachts)
|
||||
} else {
|
||||
// 只隐藏游艇,保留船舶
|
||||
const yachtIds = this.shipData
|
||||
.filter((ship: any) => ship.shipTypeName === '其他')
|
||||
.map((ship: any) => ship.shipId)
|
||||
console.log(yachtIds,'yachtIds')
|
||||
ShipFun.hideShips(yachtIds)
|
||||
DialogUtil.closeCom(DialogType.SHIP_INFO)
|
||||
DialogUtil.closeCom(DialogType2.TRACK_RECORD)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理搜索
|
||||
* @param {Object} data - 搜索数据
|
||||
* @param {string} data.type - 类型:ship, car, yacht
|
||||
* @param {string} data.value - 搜索值
|
||||
*/
|
||||
private handleFilterSearch(data: any) {
|
||||
const { type, value } = data
|
||||
if (!value) {
|
||||
// 搜索值为空,显示所有数据
|
||||
this.handleFilterTypeChange({ type, isChecked: true })
|
||||
return
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'ship': {
|
||||
// 船舶搜索
|
||||
const allShips = this.shipData.filter((ship: any) => {
|
||||
const isShip = ship.shipTypeName !== '其他'
|
||||
return isShip
|
||||
})
|
||||
console.log(allShips,'所有的船舶数据')
|
||||
console.log(value,'搜索值')
|
||||
// 再根据mmsi包含value筛选
|
||||
const filteredaShips = allShips.filter((ship: any) => {
|
||||
const mmsi = ship.mmsi || ''
|
||||
const isMatch = mmsi.includes(value)
|
||||
return isMatch
|
||||
})
|
||||
// 清空现有船舶数据
|
||||
console.log(filteredaShips,'筛选后的船舶数据')
|
||||
ShipFun.clearallship(this.map)
|
||||
if (filteredaShips.length > 0) {
|
||||
this.jiexiRanks(filteredaShips)
|
||||
} else {
|
||||
console.log('没有匹配到船舶数据')
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'car': {
|
||||
// 车辆搜索
|
||||
const filteredCars = this.carData.filter((car: any) => {
|
||||
const carNum = car.carNum || ''
|
||||
return carNum.includes(value)
|
||||
})
|
||||
ShipFun.clearAllCar(this.map)
|
||||
ShipFun.addCar(filteredCars.filter((item: any) => {
|
||||
return item.latitude && item.longitude
|
||||
}), this.map)
|
||||
break
|
||||
}
|
||||
case 'yacht': {
|
||||
// 游艇搜索 - 先过滤游艇数据,再根据mmsi包含value筛选
|
||||
// 先过滤出游艇数据
|
||||
const allYachts = this.shipData.filter((ship: any) => {
|
||||
const isYacht = ship.shipTypeName === '其他'
|
||||
return isYacht
|
||||
})
|
||||
// 再根据mmsi包含value筛选
|
||||
const filteredYachts = allYachts.filter((ship: any) => {
|
||||
const mmsi = ship.mmsi || ''
|
||||
const isMatch = mmsi.includes(value)
|
||||
return isMatch
|
||||
})
|
||||
// 清空现有船舶数据
|
||||
ShipFun.clearallship(this.map)
|
||||
|
||||
if (filteredYachts.length > 0) {
|
||||
// 直接调用jiexiRanks方法处理数据并添加到地图
|
||||
this.jiexiRanks(filteredYachts)
|
||||
} else {
|
||||
console.log('没有匹配到游艇数据')
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user