调整参航单位统计页面地图

This commit is contained in:
80937518651731347 2026-04-03 04:09:35 +08:00
parent f0608a28b0
commit f61af1183d
1 changed files with 90 additions and 226 deletions

View File

@ -35,11 +35,11 @@
</div>
</div>
</div>
<!-- 地图板块-->
<!-- 地图板块与科考船汇总统计页 ships 一致Mapbox + shipUnit + shipVoyage -->
<div class="map-module">
<div class="bezel">
<div class="map-title">参航单位</div>
<div id="baiduCesiumContainer" ref="baiduCesiumContainer" style="height: 100%;width:100%;" />
<div id="workUnitMap_uuv" ref="workUnitMap_uuv" style="height: 100%;width:100%;" />
</div>
<div class="bezel">
<div class="map-title">航次地图</div>
@ -56,7 +56,7 @@
@change="selectVoyageYear"
/>
</div>
<div id="cesiumContainer" ref="cesiumContainer" style="height: 100%;width:100%;" />
<div id="voyageMap_uuv" ref="voyageMap_uuv" style="height: 100%;width:100%;" />
</div>
</div>
<!-- echarts板块-->
@ -109,11 +109,13 @@
</template>
<script>
import Vue from 'vue'
import BarChart from './components/BarChart.vue'
import { setImageryViewModels } from '../../utils/common'
import { unitTotal, hovUnit, hovDiving } from '../../api/statistics'
import { unitTotal, hovUnit, shipUnit, shipVoyage } from '../../api/statistics'
import { getYearRange } from '../../utils/index'
const Cesium = window.Cesium
import { initMapbox, handleWheel } from '@/utils/mapbox-utils'
import { loadVectorLayer, loadJsonPointFeature } from '@/utils/vector-layer-utils'
import { ColorGenerator } from '@/utils/color-generator'
/**
* @param {*} v 原始值
@ -134,12 +136,10 @@ export default {
currentTitle: '参航单位统计',
voyageYear: '',
unitOptions: [],
/** 与 Banner 多选绑定:筛选单位汇总图表与航次地图轨迹(空表示全部) */
/** 与 Banner 多选绑定:筛选单位汇总图表(空表示全部) */
selectedUnits: [],
/** unitTotal 全量缓存,便于按 Banner 选择做前端过滤 */
unitTotalRawList: [],
// hovDiving 便
hovDivingItems: [],
numbers: [
{
label: '参航单位数量',
@ -157,13 +157,6 @@ export default {
unit: '次'
}
],
// Cesium -
baiduCesiumViewer: null,
baiduCesiumEntities: [], //
viewer: null,
//
CesiumHostAddr: `${window.location.protocol}//${window.location.hostname}:${window.location.port}/`,
trackLineLayers: [],
/** 航行次数(柱状) */
barVoyageCount: { title: '航行次数', salesData: [], productCategories: [] },
/** 参航天数(柱状) */
@ -200,64 +193,44 @@ export default {
created() {
this.loadUnitTotalFromApi()
this.getHovUnit()
this.gitHovDiving()
this.getShipUnit()
this.gitShipVoyage()
},
mounted() {
this.imageryViewModels = setImageryViewModels(this.CesiumHostAddr)
this.initCesium() //
this.initBaiduCesium() //
this.refreshTrackLines()
initMapbox('workUnitMap_uuv', {
tileKey: 'gaode',
zoom: 3,
center: [110, 31],
minZoom: 2,
maxZoom: 29
})
initMapbox('voyageMap_uuv', {
tileKey: 'GEBCO_basemap_NCEI',
zoom: 4,
center: [113, 15],
minZoom: 2,
maxZoom: 29
})
},
beforeDestroy() {
// Cesium
if (this.baiduCesiumViewer) {
this.baiduCesiumViewer.destroy()
const unitMap = Vue.config.maps && Vue.config.maps['workUnitMap_uuv']
if (unitMap) {
unitMap.remove()
delete Vue.config.maps['workUnitMap_uuv']
}
if (this.viewer) {
this.viewer.destroy()
const voyageMap = Vue.config.maps && Vue.config.maps['voyageMap_uuv']
if (voyageMap) {
voyageMap.remove()
delete Vue.config.maps['voyageMap_uuv']
}
},
methods: {
/**
* 刷新航次地图轨迹图层按单位多选进行前端过滤
* @returns {void}
*/
refreshTrackLines() {
if (!this.viewer) return
this.removeSingleLineImg()
const selectedNameSet = new Set(
(this.selectedUnits || [])
.map(u => u && u.unit_name)
.filter(Boolean)
)
const selectedIdSet = new Set(
(this.selectedUnits || [])
.map(u => (u && (u.unit_id || u.unitId)) || null)
.filter(Boolean)
)
const unitFilterEnabled = selectedNameSet.size > 0 || selectedIdSet.size > 0
const itemsToShow = unitFilterEnabled
? (this.hovDivingItems || []).filter(item => {
const itemName = item.unit_name || item.unitName || item.unit_name_cn || null
const itemId = item.unit_id || item.unitId || item.unit_code || null
return selectedNameSet.has(itemName) || selectedIdSet.has(itemId)
})
: (this.hovDivingItems || [])
itemsToShow.forEach(item => {
this.addSingleLineImg(item)
})
},
/**
* Banner 统计单位多选变更刷新汇总图表与航次地图轨迹
* Banner 统计单位多选变更刷新汇总图表
* @returns {void}
*/
onBannerUnitsChange() {
this.applyFilteredUnitTotal()
this.refreshTrackLines()
},
/**
@ -384,189 +357,80 @@ export default {
]
}
},
//
/**
* 载人潜水器参航单位列表仅用于 Banner 多选筛选图表
* @returns {void}
*/
getHovUnit() {
hovUnit().then(res => {
//
const map = new Map()
;(res.array || []).forEach(unit => {
const k = unit.unit_id || unit.unitId || unit.unit_name
if (!map.has(k)) map.set(k, unit)
})
this.unitOptions = Array.from(map.values())
//
this.clearBaiduCesiumMarkers()
//
this.createBaiduCesiumMarkers(res.array || [])
})
},
// Cesium
createBaiduCesiumMarkers(units) {
if (!this.baiduCesiumViewer) return
const entities = []
units.forEach((item, index) => {
//
const entity = this.baiduCesiumViewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(item.unit_lon, item.unit_lat),
billboard: {
image: '../../../static/img/01.png', //
width: 32,
height: 32,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER
},
label: {
text: item.unit_name,
font: '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 2,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(0, -40), //
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK
},
unitData: item, //
index: index //
})
entities.push(entity)
})
this.baiduCesiumEntities = entities
//
if (entities.length > 0) {
this.baiduCesiumViewer.zoomTo(entities)
}
},
//
clearBaiduCesiumMarkers() {
if (this.baiduCesiumViewer && this.baiduCesiumEntities.length > 0) {
this.baiduCesiumEntities.forEach(entity => {
this.baiduCesiumViewer.entities.remove(entity)
})
this.baiduCesiumEntities = []
}
},
//
gitHovDiving(params = {}) {
hovDiving(params).then(res => {
this.hovDivingItems = res.array || []
this.refreshTrackLines()
})
},
// Cesium -
initBaiduCesium() {
this.baiduCesiumViewer = new Cesium.Viewer(this.$refs.baiduCesiumContainer, {
sceneMode: Cesium.SceneMode.SCENE2D,
shadows: false,
timeline: false,
baseLayerPicker: false,
imageryProviderViewModels: this.imageryViewModels,
terrainProviderViewModels: [],
fullscreenButton: false,
selectionIndicator: false,
homeButton: false,
sceneModePicker: false,
animation: false,
infoBox: false,
geocoder: false,
navigationHelpButton: false
})
this.baiduCesiumViewer._cesiumWidget._creditContainer.style.display = 'none'
this.baiduCesiumViewer.scene.sun.show = false
this.baiduCesiumViewer.scene.moon.show = false
this.baiduCesiumViewer.scene.fog.enabled = false
this.baiduCesiumViewer.scene.skyAtmosphere.show = false
this.baiduCesiumViewer.scene.sun.show = false
this.baiduCesiumViewer.scene.skyBox.show = false
this.baiduCesiumViewer.scene.globe.enableLighting = false
this.baiduCesiumViewer.shadowMap.darkness = 0.8
this.baiduCesiumViewer.scene._sunBloom = false
this.baiduCesiumViewer.scene.globe.showGroundAtmosphere = false
this.baiduCesiumViewer.scene.postProcessStages.fxaa.enabled = true
this.baiduCesiumViewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(114.4040, 30.5196, 4000000)
})
},
// cesium
initCesium() {
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkY2Y5NWY2Ni1mODQ1LTQ3YTUtYjc4Zi1jYzhjMGI2YzcxMWYiLCJpZCI6MTI5ODMwLCJpYXQiOjE2Nzk0Njk5NTd9.DTH54ioOH-HLqeNIetBe9hFyrPOX2Vp1AQmZzw8TIZ4'
this.viewer = new Cesium.Viewer('cesiumContainer', {
sceneMode: Cesium.SceneMode.SCENE2D,
shadows: false,
timeline: false,
baseLayerPicker: false,
//
imageryProviderViewModels: this.imageryViewModels,
//
terrainProviderViewModels: [],
fullscreenButton: false,
selectionIndicator: false,
homeButton: false,
sceneModePicker: false,
animation: false,
infoBox: false,
geocoder: false,
navigationHelpButton: false
})
this.viewer._cesiumWidget._creditContainer.style.display = 'none'
this.viewer.scene.sun.show = false
this.viewer.scene.moon.show = false
this.viewer.scene.fog.enabled = false
this.viewer.scene.skyAtmosphere.show = false
this.viewer.scene.sun.show = false
this.viewer.scene.skyBox.show = false
this.viewer.scene.globe.enableLighting = false
this.viewer.shadowMap.darkness = 0.8
this.viewer.scene._sunBloom = false
this.viewer.scene.globe.showGroundAtmosphere = false
this.viewer.scene.postProcessStages.fxaa.enabled = true
this.viewer.camera.setView({
//
destination: Cesium.Cartesian3.fromDegrees(112, 18, 4000000)
})
},
//
addSingleLineImg(item) {
const trackLine = new Cesium.WebMapTileServiceImageryProvider(
{
url: `${this.CesiumHostAddr}geoserver/gwc/service/wmts/rest/dsds:${item.diving_sn}/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png`,
layer: `dsds:${item.diving_sn}`,
style: 'default',
format: 'image/png',
tileMatrixSetID: 'EPSG:4326',
tilingScheme: new Cesium.GeographicTilingScheme()
/**
* 科考船侧参航单位点位 ships 页地图同源接口通过 Mapbox GeoJSON 渲染
* @returns {void}
*/
getShipUnit() {
shipUnit().then(res => {
const geojson = {
type: 'FeatureCollection',
features: []
}
)
const trackLineLayer = this.viewer.imageryLayers.addImageryProvider(trackLine)
this.trackLineLayers.push(trackLineLayer)
},
//
removeSingleLineImg() {
if (this.viewer && this.trackLineLayers.length) {
this.trackLineLayers.forEach(line => {
this.viewer.imageryLayers.remove(line)
;(res.array || []).forEach(element => {
geojson.features.push({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [element.unit_lon, element.unit_lat]
},
properties: {
unit_name: element.unit_name,
unit_type: element.unit_type,
create_time: element.create_time,
tsy_id: element.tsy_id
}
})
})
}
// remove
this.trackLineLayers = []
loadJsonPointFeature('workUnit', 'blue', geojson, 'unit_name', 'workUnitMap_uuv')
})
},
//
/**
* 科考船航次轨迹 ships 页地图同源接口通过 Mapbox 矢量图层渲染
* @param {Object} [params] 查询参数
* @returns {void}
*/
gitShipVoyage(params = {}) {
shipVoyage(params).then(res => {
let i = 0
const colors = ColorGenerator.generateDivergingColors((res.array || []).length)
;(res.array || []).forEach(item => {
loadVectorLayer(item.voyage_name, ['line', 'symbol'], [colors[i], '#FFFFFF'], 'visible', 'voyageMap_uuv', 'dsds')
i++
})
})
},
/**
* 选择航次地图年份
* @param {*} val 年份值
* @returns {void}
*/
selectVoyageYear(val) {
this.removeSingleLineImg()
if (val) {
const params = getYearRange(val)
this.gitHovDiving({ ...params })
this.gitShipVoyage({ ...params })
} else {
this.gitHovDiving({})
this.gitShipVoyage({})
}
},
}
}
}
</script>
@ -737,7 +601,7 @@ export default {
}
.map-module {
padding: 20px 50px 50px;
padding: 50px 50px;
display: flex;
justify-content: space-between;
gap: 50px;