runtime-core.esm-bundler.js:51 [Vue warn]: Unhandled error during execution of setup function
at <CesiumViewer>
at <App>
warn$1 @ runtime-core.esm-bundler.js:51
CesiumViewer.vue:80 Uncaught ReferenceError: throttle is not defined
at setup (CesiumViewer.vue:80:24)
at callWithErrorHandling (runtime-core.esm-bundler.js:199:19)
at setupStatefulComponent (runtime-core.esm-bundler.js:7965:25)
at setupComponent (runtime-core.esm-bundler.js:7926:36)
at mountComponent (runtime-core.esm-bundler.js:5247:7)
at processComponent (runtime-core.esm-bundler.js:5213:9)
at patch (runtime-core.esm-bundler.js:4729:11)
at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js:5358:11)
at ReactiveEffect.run (reactivity.esm-bundler.js:237:19)
at setupRenderEffect (runtime-core.esm-bundler.js:5486:5) 如图所示报错修改以下代码:<template>
<div id="cesiumContainer" class="cesiumContainer"></div>
<div ref="miniMapContainer" class="mini-map" @click="handleMiniMapClick">
<div class="location-indicator" :style="indicatorStyle"></div>
<!-- 四个角折角 -->
<div class="corner corner-top-left"></div>
<div class="corner corner-top-right"></div>
<div class="corner corner-bottom-left"></div>
<div class="corner corner-bottom-right"></div>
<div class="focus-effect"></div>
<div class="pulse"></div>
</div>
</template>
<script setup lang="ts">
import { onUnmounted, onMounted, ref } from "vue";
import * as Cesium from 'cesium';
// import { throttle } from "lodash";
const miniMapContainer = ref<HTMLElement>();
let viewer: Cesium.Viewer | null = null;
let overviewViewer: Cesium.Viewer | null = null;
// 株洲市范围常量
const ZHUZHOU_EXTENT = {
west: 112.5, // 株洲市西边界
east: 114.5, // 株洲市东边界
south: 26.0, // 株洲市南边界
north: 28.0, // 株洲市北边界
};
// 视图指示器样式
const indicatorStyle = ref({
left: "50%",
top: "50%",
display: "block",
});
// 更新指示器位置
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;
// 更新CSS指示器
indicatorStyle.value = {
left: `${lonPercent}%`,
top: `${latPercent}%`,
display: "block",
};
};
// 更新鹰眼地图
const updateOverview = throttle(() => {
if (!viewer || !overviewViewer) return;
updateIndicatorPosition();
}, 200);
// 初始化主地图
const initMap = () => {
Cesium.Ion.defaultAccessToken = "YOUR_CESIUM_ACCESS_TOKEN";
viewer = new Cesium.Viewer("cesiumContainer", {
sceneMode: Cesium.SceneMode.SCENE3D,
baseLayerPicker: false,
geocoder: false,
homeButton: false,
timeline: false,
navigationHelpButton: false,
fullscreenButton: false,
animation: false,
infoBox: false,
selectionIndicator: false
});
// 加载株洲市影像图
const zhuzhouProvider = new Cesium.UrlTemplateImageryProvider({
url: "http://124.232.190.30:9000/proxy/pk1725866655224/map/zzzsyx_18/{z}/{x}/{y}.png",
minimumLevel: 1,
maximumLevel: 17,
tilingScheme: new Cesium.WebMercatorTilingScheme(),
});
viewer.imageryLayers.addImageryProvider(zhuzhouProvider);
// 设置初始视图
viewer.camera.flyTo({
destination: Cesium.Rectangle.fromDegrees(
ZHUZHOU_EXTENT.west,
ZHUZHOU_EXTENT.south,
ZHUZHOU_EXTENT.east,
ZHUZHOU_EXTENT.north
),
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-45),
roll: 0
}
});
};
// 初始化鹰眼地图
const initMiniMap = () => {
if (!miniMapContainer.value) return;
// 创建全球底图提供器
const worldProvider = new Cesium.UrlTemplateImageryProvider({
url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
minimumLevel: 0,
maximumLevel: 19,
tilingScheme: new Cesium.WebMercatorTilingScheme(),
});
// 鹰眼地图初始化
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,
imageryProvider: worldProvider,
terrainProvider: undefined,
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
),
});
// 隐藏控件
const toolbar = overviewViewer.container.querySelector(".cesium-viewer-toolbar");
if (toolbar) toolbar.style.display = "none";
// 隐藏版权信息
overviewViewer.cesiumWidget.creditContainer.style.display = "none";
};
// 鹰眼地图点击处理
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, 1000000),
});
};
onMounted(() => {
initMap();
setTimeout(() => {
initMiniMap();
// 监听主地图相机变化
if (viewer) {
viewer.camera.changed.addEventListener(updateOverview);
}
// 初始更新
updateOverview();
}, 1000);
});
onUnmounted(() => {
if (viewer) {
viewer.destroy();
}
if (overviewViewer) {
overviewViewer.destroy();
}
});
</script>
<style>
/* 全局样式 */
html, body {
margin: 0;
padding: 0;
overflow: hidden;
width: 100%;
height: 100%;
}
.cesiumContainer {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.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;
}
/* 相机聚焦样式 - 四个角折角 */
.corner {
position: absolute;
width: 25px;
height: 25px;
z-index: 100;
pointer-events: none;
}
.corner::before,
.corner::after {
content: "";
position: absolute;
background: #00f2fe;
box-shadow: 0 0 10px rgba(0, 242, 254, 0.8);
}
.corner-top-left {
top: -2px;
left: -2px;
}
.corner-top-left::before {
top: 0;
left: 0;
width: 15px;
height: 3px;
}
.corner-top-left::after {
top: 0;
left: 0;
width: 3px;
height: 15px;
}
.corner-top-right {
top: -2px;
right: -2px;
}
.corner-top-right::before {
top: 0;
right: 0;
width: 15px;
height: 3px;
}
.corner-top-right::after {
top: 0;
right: 0;
width: 3px;
height: 15px;
}
.corner-bottom-left {
bottom: -2px;
left: -2px;
}
.corner-bottom-left::before {
bottom: 0;
left: 0;
width: 15px;
height: 3px;
}
.corner-bottom-left::after {
bottom: 0;
left: 0;
width: 3px;
height: 15px;
}
.corner-bottom-right {
bottom: -2px;
right: -2px;
}
.corner-bottom-right::before {
bottom: 0;
right: 0;
width: 15px;
height: 3px;
}
.corner-bottom-right::after {
bottom: 0;
right: 0;
width: 3px;
height: 15px;
}
.focus-effect {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 98;
border: 2px solid rgba(0, 242, 254, 0.2);
border-radius: 5px;
box-shadow: inset 0 0 30px rgba(0, 242, 254, 0.1);
}
.pulse {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 10px;
height: 10px;
border-radius: 50%;
background: rgba(0, 242, 254, 0.7);
box-shadow: 0 0 0 0 rgba(0, 242, 254, 0.7);
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
transform: translate(-50%, -50%) scale(1);
opacity: 0.7;
}
70% {
transform: translate(-50%, -50%) scale(1.5);
opacity: 0;
}
100% {
transform: translate(-50%, -50%) scale(1);
opacity: 0;
}
}
/* 隐藏不需要的Cesium控件 */
.cesium-viewer-toolbar,
.cesium-viewer-animationContainer,
.cesium-viewer-timelineContainer,
.cesium-viewer-bottom {
display: none !important;
}
</style>
最新发布