Zzc b432d8d6b7 feat(map): 集成Cesium 3D地图系统与控件和服务
使用Cesium添加全面的3D地图功能,包括:
- 地图视口和控件组件
- 图层管理,含底图切换器和目录控制
- 相机、实体和查询服务
- 罗盘和场景模式切换UI组件
- 支持工具、存储和数据配置

更新构建配置以支持Cesium集成和SVG图标。
2025-11-07 15:04:37 +08:00

307 lines
6.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="map-center">
<div class="map-container">
<MapViewport />
<MapControls />
</div>
<!-- 顶部功能按钮 -->
<div class="top-buttons">
<button
v-for="button in topButtons"
:key="button.id"
class="func-button"
:class="button.class"
>
<img :src="button.icon" :alt="button.label" class="button-icon" />
<span>{{ button.label }}</span>
</button>
</div>
<!-- 地图标记点 (这里应该集成实际地图现在用占位符) -->
<!-- <div class="map-markers">
<div
v-for="marker in markers"
:key="marker.id"
class="marker"
:style="{ left: marker.x + 'px', top: marker.y + 'px' }"
>
<img :src="marker.icon" :alt="marker.type" />
</div>
</div> -->
<!-- 底部菜单 -->
<!--
<div class="bottom-menu">
<div class="menu-left">
<div class="menu-text">
应急体系<br />
重大事件处置<br />
冰雪灾害专题<br />
水毁专题<br />
节假日专题
</div>
</div>
<div class="menu-center">
<img src="../assets/img/map-center-menu-bg.png" alt="center menu" class="center-menu-bg" />
<div class="center-menu-content">
<div class="menu-tabs">
<span>总体概览</span>
<span>综合评价</span>
</div>
<div class="menu-icons">
<div class="menu-icon-item">
<img src="../assets/img/map-menu-icon-road-network.png" alt="icon" />
<span>路网结构<br />优化</span>
</div>
<div class="menu-icon-item">
<img src="../assets/img/map-menu-icon-construction.png" alt="icon" />
<span>建设工程<br />智监</span>
</div>
<div class="menu-icon-item highlighted">
<img src="../assets/img/map-menu-icon-safety.png" alt="icon" />
<span>安全保通<br />服务</span>
</div>
<div class="menu-icon-item">
<img src="../assets/img/map-menu-icon-maintenance.png" alt="icon" />
<span>养护作业<br />智管</span>
</div>
</div>
</div>
</div>
</div>
-->
</div>
</template>
<script setup>
import { ref } from 'vue'
import { MapViewport, MapControls } from '@/map'
// 导入图片
import btnServiceIcon from '../assets/img/map-btn-service.png'
import btnWarningRoadIcon from '../assets/img/map-btn-warning-road.png'
import btnWeatherIcon from '../assets/img/map-btn-weather.png'
import markerServiceIcon from '../assets/img/map-marker-service.png'
import markerWarningIcon from '../assets/img/map-marker-warning.png'
import markerAlertIcon from '../assets/img/map-marker-alert.png'
const topButtons = ref([
{
id: 1,
label: '服务站点',
class: 'button-primary',
icon: btnServiceIcon
},
{
id: 2,
label: '预警路段',
class: 'button-default',
icon: btnWarningRoadIcon
},
{
id: 3,
label: '气象预警',
class: 'button-default',
icon: btnWeatherIcon
}
])
const markers = ref([
{ id: 1, type: 'service', x: 200, y: 150, icon: markerServiceIcon },
{ id: 2, type: 'warning', x: 350, y: 200, icon: markerWarningIcon },
{ id: 3, type: 'alert', x: 450, y: 300, icon: markerAlertIcon }
])
</script>
<style scoped lang="scss">
@use '@/styles/mixins.scss' as *;
.map-center {
width: 100%;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
}
.map-container {
position: absolute;
inset: 0;
z-index: 0;
}
.top-buttons,
.map-markers,
.bottom-menu {
position: relative;
z-index: 1;
}
.top-buttons {
position: absolute;
top: vh(20);
left: 50%;
transform: translateX(-50%);
display: flex;
gap: vw(10);
z-index: 10;
}
.func-button {
width: vw(60);
height: vh(60);
border: vw(0.5) solid rgba(60, 174, 255, 1);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: vh(5);
cursor: pointer;
transition: all 0.3s;
&.button-default {
background-color: rgba(35, 74, 117, 1);
}
&.button-primary {
background-color: rgba(33, 73, 118, 1);
}
&:hover {
background-color: rgba(60, 174, 255, 0.3);
}
.button-icon {
width: vw(28);
height: vh(23);
}
span {
color: rgba(255, 255, 255, 1);
font-size: fs(12);
font-family: SourceHanSansCN-Regular, sans-serif;
}
}
.map-markers {
flex: 1;
position: relative;
.marker {
position: absolute;
width: vw(44);
height: vh(44);
cursor: pointer;
transition: transform 0.3s;
&:hover {
transform: scale(1.2);
}
img {
width: 100%;
height: 100%;
}
}
}
.bottom-menu {
position: absolute;
bottom: vh(20);
left: 50%;
transform: translateX(-50%);
display: flex;
gap: vw(30);
align-items: flex-end;
}
.menu-left {
.menu-text {
color: rgba(255, 255, 255, 1);
font-size: fs(14);
line-height: vh(39);
white-space: nowrap;
}
}
.menu-center {
position: relative;
width: vw(350);
height: vh(156);
.center-menu-bg {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.center-menu-content {
position: relative;
z-index: 1;
padding: vw(15) vw(34);
height: 100%;
display: flex;
flex-direction: column;
.menu-tabs {
display: flex;
justify-content: space-between;
margin-top: auto;
margin-bottom: vh(5);
span {
color: rgba(255, 255, 255, 1);
font-size: fs(12);
font-family: Helvetica, "Microsoft YaHei", Arial, sans-serif;
cursor: pointer;
&:hover {
opacity: 0.8;
}
}
}
.menu-icons {
display: flex;
justify-content: space-between;
align-items: flex-end;
.menu-icon-item {
display: flex;
flex-direction: column;
align-items: center;
gap: vh(5);
cursor: pointer;
transition: transform 0.3s;
&:hover {
transform: translateY(vh(-5));
}
&.highlighted {
background: url(../assets/img/map-menu-item-highlight-bg.png) no-repeat;
background-size: contain;
padding: vw(10);
}
img {
width: vw(32);
height: vh(32);
}
span {
color: rgba(255, 255, 255, 1);
font-size: fs(12);
font-family: Helvetica, "Microsoft YaHei", Arial, sans-serif;
text-align: center;
line-height: vh(14);
}
}
}
}
}
</style>