<template>
<!-- 主地图容器 -->
<div id="cesium-container" ref="cesiumContainer"></div>
<!-- 鹰眼地图容器 -->
<div ref="miniMapContainer" class="mini-map" @click="handleMiniMapClick">
<div class="location-indicator" :style="indicatorStyle"></div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import * as Cesium from 'cesium';
import 'cesium/Build/Cesium/Widgets/widgets.css';
// 株洲市范围定义
const ZHUZHOU_EXTENT = {
west: 112.5,
east: 114.5,
south: 26.0,
north: 28.0
};
// 地图容器引用
const cesiumContainer = ref<HTMLDivElement | null>(null);
const miniMapContainer = ref<HTMLElement | null>(null);
// 地图实例
let viewer: Cesium.Viewer | null = null;
let overviewViewer: Cesium.Viewer | null = null;
// 位置指示器样式
const indicatorStyle = ref({
left: '50%',
top: '50%',
display: 'block'
});
// 创建主地图
const initMainMap = () => {
if (!cesiumContainer.value) return;
try {
// 使用ArcGIS世界影像服务
const imageryProvider = new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
});
// 初始化主地图
viewer = new Cesium.Viewer(cesiumContainer.value, {
baseLayerPicker: false,
animation: false,
timeline: false,
navigationHelpButton: false,
fullscreenButton: false,
geocoder: false,
homeButton: false,
sceneModePicker: false,
skyBox: false,
skyAtmosphere: false,
infoBox: false,
selectionIndicator: false,
terrainProvider: new Cesium.EllipsoidTerrainProvider(),
sceneMode: Cesium.SceneMode.SCENE3D,
});
// 隐藏版权信息
viewer.cesiumWidget.creditContainer.style.display = "none";
// 设置初始视角到株洲市
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(113.13, 27.83, 5000),
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-90),
roll: 0.0
}
});
console.log("主地图初始化完成");
} catch (error) {
console.error("主地图初始化失败:", error);
}
};
// 初始化鹰眼地图
const initMiniMap = () => {
if (!miniMapContainer.value) return;
try {
// 鹰眼地图使用相同的影像源
const imageryProvider = new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
});
// 初始化鹰眼地图
overviewViewer = new Cesium.Viewer(miniMapContainer.value, {
sceneMode: Cesium.SceneMode.SCENE2D,
baseLayerPicker: false,
homeButton: false,
timeline: false,
navigationHelpButton: false,
animation: false,
scene3DOnly: true,
selectionIndicator: false,
infoBox: false,
mapProjection: new Cesium.WebMercatorProjection(),
skyBox: false,
skyAtmosphere: false
});
// 设置鹰眼地图视图为株洲范围
overviewViewer.camera.setView({
destination: Cesium.Rectangle.fromDegrees(
ZHUZHOU_EXTENT.west,
ZHUZHOU_EXTENT.south,
ZHUZHOU_EXTENT.east,
ZHUZHOU_EXTENT.north
)
});
// 隐藏UI元素
const toolbar = overviewViewer.container.getElementsByClassName(
"cesium-viewer-toolbar"
)[0];
if (toolbar) toolbar.style.display = "none";
overviewViewer.cesiumWidget.creditContainer.style.display = "none";
console.log("鹰眼地图初始化完成");
} catch (error) {
console.error("鹰眼地图初始化失败:", error);
}
};
// 更新位置指示器
const updateIndicatorPosition = () => {
if (!viewer) return;
const camera = viewer.camera;
const rect = camera.computeViewRectangle();
if (!rect) return;
const center = Cesium.Rectangle.center(rect);
const lon = Cesium.Math.toDegrees(center.longitude);
const lat = Cesium.Math.toDegrees(center.latitude);
// 确保在株洲范围内
const constrainedLon = Math.max(
ZHUZHOU_EXTENT.west,
Math.min(ZHUZHOU_EXTENT.east, lon)
);
const constrainedLat = Math.max(
ZHUZHOU_EXTENT.south,
Math.min(ZHUZHOU_EXTENT.north, lat)
);
// 计算位置百分比
const lonPercent =
((constrainedLon - ZHUZHOU_EXTENT.west) /
(ZHUZHOU_EXTENT.east - ZHUZHOU_EXTENT.west)) *
100;
const latPercent =
100 -
((constrainedLat - ZHUZHOU_EXTENT.south) /
(ZHUZHOU_EXTENT.north - ZHUZHOU_EXTENT.south)) *
100;
indicatorStyle.value = {
left: `${lonPercent}%`,
top: `${latPercent}%`,
display: "block"
};
};
// 监听主地图相机变化
const setupCameraListener = () => {
if (!viewer) return;
viewer.camera.changed.addEventListener(updateIndicatorPosition);
};
// 鹰眼地图点击处理
const handleMiniMapClick = (event: MouseEvent) => {
if (!miniMapContainer.value || !overviewViewer || !viewer) return;
const rect = miniMapContainer.value.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
const xPercent = (x / rect.width) * 100;
const yPercent = (y / rect.height) * 100;
// 计算点击位置对应的经纬度
const lon = ZHUZHOU_EXTENT.west +
(xPercent / 100) * (ZHUZHOU_EXTENT.east - ZHUZHOU_EXTENT.west);
const lat = ZHUZHOU_EXTENT.north -
(yPercent / 100) * (ZHUZHOU_EXTENT.north - ZHUZHOU_EXTENT.south);
// 飞向点击位置
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(lon, lat, 5000),
duration: 1
});
};
// 组件挂载时初始化
onMounted(() => {
initMainMap();
setTimeout(() => {
initMiniMap();
setupCameraListener();
updateIndicatorPosition();
}, 1000);
});
// 组件卸载时清理
onUnmounted(() => {
if (viewer && !viewer.isDestroyed()) {
viewer.destroy();
}
if (overviewViewer && !overviewViewer.isDestroyed()) {
overviewViewer.destroy();
}
});
</script>
<style scoped>
/* 主地图容器样式 */
#cesium-container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
background: #000;
}
/* 鹰眼地图样式 */
.mini-map {
position: absolute;
right: 20px;
bottom: 20px;
width: 200px;
height: 150px;
border: 2px solid #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
z-index: 999;
cursor: pointer;
overflow: hidden;
}
/* 位置指示器样式 */
.location-indicator {
position: absolute;
width: 14px;
height: 14px;
background: #ff3e3e;
border: 2px solid white;
border-radius: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 0 15px rgba(255, 62, 62, 1);
z-index: 100;
}
/* 隐藏版权信息 */
:deep(.cesium-widget) {
background-color: #000 !important;
}
:deep(.cesium-widget-credits),
:deep(.cesium-credit-textContainer),
:deep(.cesium-credit-expand-link) {
display: none !important;
visibility: hidden !important;
}
</style>
好的现在初始功能有了,现在借鉴他的株洲市影像瓦片,再主地图与鹰眼地图都加载,基于此修改上述代码发我
最新发布