地图调整为Cesium

This commit is contained in:
zhangqi 2025-09-10 16:04:17 +08:00
parent 9bd4268200
commit 8f61f94543
8 changed files with 1793 additions and 226 deletions

786
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,11 +11,11 @@
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"axios": "^1.6.7",
"cesium": "^1.133.1",
"element-plus": "^2.5.6",
"md5": "^2.3.0",
"pinia": "^3.0.3",
"vue": "^3.4.38",
"vue-baidu-map-3x": "^1.0.40",
"vue-router": "^4.3.0"
},
"devDependencies": {
@ -23,6 +23,7 @@
"sass": "^1.71.1",
"typescript": "^5.5.3",
"vite": "^5.4.2",
"vite-plugin-cesium": "^1.2.23",
"vue-tsc": "^2.1.4"
}
}

View File

@ -6,7 +6,6 @@ import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import zhCn from 'element-plus/es/locale/lang/zh-cn'; // 引入中文语言包
import router from './router'
import App from './App.vue'
import BaiduMap from 'vue-baidu-map-3x'
import './style.css'
const app = createApp(App)
@ -19,9 +18,6 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.use(pinia)
app.use(BaiduMap, {
ak: 'uu7pXHZLZOejrWXyTK2lVMHASObAg8Fz'
})
app.use(ElementPlus, {
locale: zhCn
})

83
src/utils/common.js Normal file
View File

@ -0,0 +1,83 @@
import * as Cesium from "cesium";
export function modifyCesiumMouseWheel(viewer) {
// 地图缩放改为按下 Ctrl + 鼠标滚轮
viewer.scene.screenSpaceCameraController.zoomEventTypes = [{ eventType: Cesium.CameraEventType.WHEEL, modifier: Cesium.KeyboardEventModifier.CTRL }];
// 改写 Cesium 原生鼠标滚轮事件
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction((event) => {
if (event < 0) {
window.scrollBy({ left: 0, top: 15, behavior: 'auto' });
} else {
window.scrollBy({ left: 0, top: -15, behavior: 'auto' });
}
}, Cesium.ScreenSpaceEventType.WHEEL);
// 鼠标移动时显示提示信息
handler.setInputAction((event) => {
document.getElementById('mouseWheelTip').style.display = '';
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
let imageryViewModels = [];
export function setImageryViewModels(cesiumHostAddr) {
if (imageryViewModels.length == 0) {
// 世界影像地图
const world_imagery = new Cesium.WebMapTileServiceImageryProvider(
{
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
// url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
// url: 'https://services.arcgisonline.com/ArcGIS/rest/services/Ocean/World_Ocean_Base/MapServer'
}
);
// 彩色地形底图
const colorMap = new Cesium.WebMapTileServiceImageryProvider(
{
url: cesiumHostAddr + 'geoserver/gwc/service/wmts/rest/ougp:world/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/jpeg',
layer: 'ougp:world',
style: 'default',
format: 'image/jpeg',
tileMatrixSetID: 'EPSG:4326',
tilingScheme: new Cesium.GeographicTilingScheme()
}
);
// 灰度地形底图
const grayMap = new Cesium.WebMapTileServiceImageryProvider(
{
url: cesiumHostAddr + 'geoserver/gwc/service/wmts/rest/ougp:world_gray/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/jpeg',
layer: 'ougp:world_gray',
style: 'default',
format: 'image/jpeg',
tileMatrixSetID: 'EPSG:4326',
tilingScheme: new Cesium.GeographicTilingScheme()
}
);
// 自定义底图
imageryViewModels.push(new Cesium.ProviderViewModel({
name: "世界影像地图",
iconUrl: "static/images/world_imagery.png",
tooltip: "世界影像地图",
creationFunction: function () {
return world_imagery;
}
}));
imageryViewModels.push(new Cesium.ProviderViewModel({
name: "地形地图",
iconUrl: "static/images/world_color.png",
tooltip: "彩色地形底图",
creationFunction: function () {
return colorMap;
}
}));
imageryViewModels.push(new Cesium.ProviderViewModel({
name: "灰度地图",
iconUrl: "static/images/world_gray.png",
tooltip: "灰度地形底图",
creationFunction: function () {
return grayMap;
}
}));
}
return imageryViewModels;
}

View File

@ -45,18 +45,7 @@
</div>
</div>
<div class="module-title">搜寻处置任务</div>
<baidu-map class="map" :center="center" :zoom="zoom" @ready="handler">
<bm-view class="map-view"></bm-view>
<bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-navigation>
<bm-marker
v-for="(item, index) in markers"
:key="index"
:position="item.position"
:icon="{url: item.icon, size: {width: 16, height: 16}}"
@click="markerClick(item.id)"
>
</bm-marker>
</baidu-map>
<div class="map" id="cesiumContainer"></div>
<div class="module-title">任务更新动态</div>
<div class="task">
<div class="item" v-for="(item, index) in dataList" :key="index">
@ -81,33 +70,14 @@
</div>
</div>
</div>
<el-dialog
v-model="dialogVisible"
title="任务详情"
width="500"
>
<div class="item">
<div class="name">{{ currentMarker.rescue_code }}</div>
<div class="time">{{ currentMarker.fill_time }}</div>
<div class="row">
<div class="col">航次<span>{{ currentMarker.voyage_name }}</span></div>
<div class="col">任务状态<span>{{ currentMarker.rescue_status }}</span></div>
</div>
<div class="row">
<div class="col">快速响应等级<span>{{ currentMarker.rescue_response_level }}</span></div>
<div class="col">目标名称<span>{{ currentMarker.rescue_target_name }}</span></div>
</div>
<div class="row">
<div class="col">任务类型<span>{{ currentMarker.rescue_type === 'SAR' ? '应急搜捞' : '专项调查' }}</span></div>
</div>
</div>
</el-dialog>
</div>
</template>
<script setup lang="ts">
<script setup>
import * as Cesium from "cesium";
import { ref, onMounted } from 'vue'
import { getParam } from '@/api/task.js'
import { modifyCesiumMouseWheel, setImageryViewModels } from '@/utils/common'
// icon
import waring1 from "@/assets/icons/告警级别1.png";
@ -119,34 +89,6 @@ import markerIcon2 from "@/assets/icons/标注点2.png";
import markerIcon3 from "@/assets/icons/标注点3.png";
import { regPage } from '@/api/task.js'
//
const center = ref({ lng: 116.443, lat: 20.422 })
const zoom = ref(7)
const handler = ({ BMap, map }) => {
}
const dialogVisible = ref(false)
const currentMarker = ref(null)
const markerClick = (id) => {
currentMarker.value = dataList.value.find(item => item.tsy_id === id)
dialogVisible.value = true
console.log('标记被点击', currentMarker.value)
}
//
const hideWatermark = () => {
const originShadow = Element.prototype.attachShadow;
Element.prototype.attachShadow = (...args) => {
const shadowRoot = originShadow.call(this, ...args)
const style = document.createElement("style")
style.innerHTML = "div { display: none !important; }"
shadowRoot.appendChild(style)
return shadowRoot
};
}
// icon
const formatIcon = (type, level) => {
let img = null
@ -215,9 +157,108 @@ const getDataList = () => {
})
}
const CesiumHostAddr = ref('')
//
const getParamsList = () => {
getParam().then(res => {
const data = res.array.find(item => item.param_name === 'CesiumHostAddr')
if (data?.param_value) {
CesiumHostAddr.value = data.param_value
} else {
CesiumHostAddr.value = `${window.location.protocol}//${window.location.hostname}:${window.location.port}/tiles/`
}
initMap();
})
}
let viewer;
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkY2Y5NWY2Ni1mODQ1LTQ3YTUtYjc4Zi1jYzhjMGI2YzcxMWYiLCJpZCI6MTI5ODMwLCJpYXQiOjE2Nzk0Njk5NTd9.DTH54ioOH-HLqeNIetBe9hFyrPOX2Vp1AQmZzw8TIZ4';
const cesiumConfig = {
sceneMode: Cesium.SceneMode.SCENE2D,
//
homeButton: false,
//
sceneModePicker: false,
//
fullscreenButton: false,
//
infoBox: false,
//
selectionIndicator: false,
//
baseLayerPicker: false,
//
shadows: true,
//
shouldAnimate: true,
//
animation: false,
// 线
timeline: false,
//
geocoder: false,
//
navigationHelpButton: false,
contextOptions: {
contextType: 2, // Webgl2:2 ; WebGPU:3
},
//
creditContainer: document.createElement('div')
}
const initMap = () => {
viewer = new Cesium.Viewer('cesiumContainer',cesiumConfig)
viewer._cesiumWidget._creditContainer.style.display = 'none'
viewer.scene.sun.show = false
viewer.scene.moon.show = false
viewer.scene.fog.enabled = false
viewer.scene.skyAtmosphere.show = false
viewer.scene.sun.show = false
viewer.scene.skyBox.show = false
viewer.scene.globe.enableLighting = false
viewer.shadowMap.darkness = 0.8
viewer.scene._sunBloom = false
viewer.scene.globe.showGroundAtmosphere = false
viewer.scene.postProcessStages.fxaa.enabled = true
viewer.camera.setView({
//
destination: Cesium.Cartesian3.fromDegrees(112, 18, 4000000)
});
// Cesium Ctrl +
modifyCesiumMouseWheel(viewer);
//
const shipline = new Cesium.WebMapTileServiceImageryProvider(
{
url: CesiumHostAddr.value + 'geoserver/gwc/service/wmts/rest/ougp:正射影像图_GM输出_20240516/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png',
layer: 'ougp:正射影像图_GM输出_20240516',
style: 'default',
format: 'image/png',
tileMatrixSetID: 'EPSG:4326',
tilingScheme: new Cesium.GeographicTilingScheme()
}
)
viewer.imageryLayers.addImageryProvider(shipline)
// 6000线
const contour6000 = new Cesium.WebMapTileServiceImageryProvider(
{
url: CesiumHostAddr.value + 'geoserver/gwc/service/wmts/rest/ougp:contour6000/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png',
layer: 'ougp:contour6000',
style: 'default',
format: 'image/png',
tileMatrixSetID: 'EPSG:4326',
tilingScheme: new Cesium.GeographicTilingScheme()
}
)
viewer.imageryLayers.addImageryProvider(contour6000)
}
onMounted(() => {
getDataList()
hideWatermark()
getParamsList()
})
</script>

View File

@ -64,20 +64,10 @@
</div>
</div>
<baidu-map class="map" :center="center" :zoom="zoom" @ready="handler">
<img class="unfold" v-show="!isShow" src="@/assets/icons/展开.png" @click="handleUnfold">
<bm-view class="map-view"></bm-view>
<bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-navigation>
<bm-marker
v-for="(item, index) in markers"
:key="index"
:position="item.position"
:icon="{url: item.icon, size: {width: 16, height: 16}}"
@click="markerClick(item.id)"
>
</bm-marker>
</baidu-map>
<div class="map">
<div id="cesiumContainer" style="width: 100%; height: 100%;"></div>
<img class="unfold" v-show="!isShow" src="@/assets/icons/展开.png" alt="" @click="handleUnfold">
</div>
<el-dialog
v-model="dialogVisible"
@ -104,9 +94,11 @@
</template>
<script setup>
import * as Cesium from "cesium";
import {ref, onMounted} from 'vue'
import { Search, RefreshRight } from '@element-plus/icons-vue'
import { regPage } from '@/api/task.js'
import { regPage, getParam } from '@/api/task.js'
import { modifyCesiumMouseWheel, setImageryViewModels } from '@/utils/common'
// icon
import markerIcon1 from "@/assets/icons/标注点1.png";
@ -203,37 +195,122 @@ const onSearch = () => {
getDataList()
}
//
const center = ref({ lng: 116.443, lat: 20.422 })
const zoom = ref(7)
const handler = ({ BMap, map }) => {
//
const CesiumHostAddr = ref('')
//
const getParamsList = () => {
getParam().then(res => {
const data = res.array.find(item => item.param_name === 'CesiumHostAddr')
if (data?.param_value) {
CesiumHostAddr.value = data.param_value
} else {
CesiumHostAddr.value = `${window.location.protocol}//${window.location.hostname}:${window.location.port}/tiles/`
}
const dialogVisible = ref(false)
const currentMarker = ref(null)
const markerClick = (id) => {
currentMarker.value = dataList.value.find(item => item.tsy_id === id)
dialogVisible.value = true
console.log('标记被点击', currentMarker.value)
initMap();
})
}
//
const hideWatermark = () => {
const originShadow = Element.prototype.attachShadow;
Element.prototype.attachShadow = (...args) => {
const shadowRoot = originShadow.call(this, ...args)
const style = document.createElement("style")
style.innerHTML = "div { display: none !important; }"
shadowRoot.appendChild(style)
return shadowRoot
let viewer;
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkY2Y5NWY2Ni1mODQ1LTQ3YTUtYjc4Zi1jYzhjMGI2YzcxMWYiLCJpZCI6MTI5ODMwLCJpYXQiOjE2Nzk0Njk5NTd9.DTH54ioOH-HLqeNIetBe9hFyrPOX2Vp1AQmZzw8TIZ4';
const cesiumConfig = {
sceneMode: Cesium.SceneMode.SCENE2D,
//
homeButton: false,
//
sceneModePicker: false,
//
fullscreenButton: false,
//
infoBox: false,
//
selectionIndicator: false,
//
baseLayerPicker: false,
//
shadows: true,
//
shouldAnimate: true,
//
animation: false,
// 线
timeline: false,
//
geocoder: false,
//
navigationHelpButton: false,
contextOptions: {
contextType: 2, // Webgl2:2 ; WebGPU:3
},
//
creditContainer: document.createElement('div')
}
const initMap = () => {
viewer = new Cesium.Viewer('cesiumContainer',cesiumConfig)
viewer._cesiumWidget._creditContainer.style.display = 'none'
viewer.scene.sun.show = false
viewer.scene.moon.show = false
viewer.scene.fog.enabled = false
viewer.scene.skyAtmosphere.show = false
viewer.scene.sun.show = false
viewer.scene.skyBox.show = false
viewer.scene.globe.enableLighting = false
viewer.shadowMap.darkness = 0.8
viewer.scene._sunBloom = false
viewer.scene.globe.showGroundAtmosphere = false
viewer.scene.postProcessStages.fxaa.enabled = true
viewer.camera.setView({
//
destination: Cesium.Cartesian3.fromDegrees(112, 18, 4000000)
});
// Cesium Ctrl +
modifyCesiumMouseWheel(viewer);
//
const shipline = new Cesium.WebMapTileServiceImageryProvider(
{
url: CesiumHostAddr.value + 'geoserver/gwc/service/wmts/rest/ougp:正射影像图_GM输出_20240516/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png',
layer: 'ougp:正射影像图_GM输出_20240516',
style: 'default',
format: 'image/png',
tileMatrixSetID: 'EPSG:4326',
tilingScheme: new Cesium.GeographicTilingScheme()
}
)
viewer.imageryLayers.addImageryProvider(shipline)
// 6000线
const contour6000 = new Cesium.WebMapTileServiceImageryProvider(
{
url: CesiumHostAddr.value + 'geoserver/gwc/service/wmts/rest/ougp:contour6000/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png',
layer: 'ougp:contour6000',
style: 'default',
format: 'image/png',
tileMatrixSetID: 'EPSG:4326',
tilingScheme: new Cesium.GeographicTilingScheme()
}
)
viewer.imageryLayers.addImageryProvider(contour6000)
const point_options = {
show: true, //
pixelSize: 10, //
color: Cesium.Color.RED, //
outlineColor: Cesium.Color.SKYBLUE, //
outlineWidth: 2 //
};
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(113.27, 18.13),
point: point_options
});
}
onMounted(() => {
getParamsList()
getDataList()
hideWatermark()
})
</script>
@ -331,18 +408,6 @@ onMounted(() => {
top: 350px;
left: 0;
}
.map-view {
width: 100%;
height: 100%;
}
&:deep(.BMap_cpyCtrl) {
display: none;
}
&:deep(.anchorBL) {
display: none;
}
}
}

View File

@ -1,11 +1,12 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path';
import cesium from 'vite-plugin-cesium';
// https://vitejs.dev/config/
export default defineConfig({
base: './',
plugins: [vue()],
plugins: [vue(),cesium()],
resolve: {
alias: {
'@': resolve(__dirname, 'src'),

812
yarn.lock

File diff suppressed because it is too large Load Diff