<template>
<div id="cesium-container" class="cesium-container"></div>
</template>
<script>
import * as Cesium from 'cesium';
import 'cesium/Build/Cesium/Widgets/widgets.css';
import CircleRippleMaterialProperty from './CircleRippleMaterialProperty';
export default {
name: 'CesiumRippleEffect',
data() {
return {
viewer: null,
rippleEntity: null
};
},
mounted() {
this.initCesium();
},
beforeDestroy() {
if (this.viewer) {
// 安全销毁Viewer
this.viewer.destroy();
this.viewer = null;
}
},
methods: {
async initCesium() {
try {
// 安全初始化Cesium Viewer
this.viewer = new Cesium.Viewer('cesium-container', {
animation: false,
timeline: false,
baseLayerPicker: false,
geocoder: false,
homeButton: false,
sceneModePicker: false,
navigationHelpButton: false,
fullscreenButton: true,
// 添加安全沙箱配置
contextOptions: {
webgl: {
preserveDrawingBuffer: true
},
allowTextureFilterAnisotropic: true
}
});
// 添加波纹圆效果
this.addRippleEffect();
// 安全调整相机位置(使用??替代弃用的defaultValue)
const defaultPosition = Cesium.Cartesian3.fromDegrees(113.194006, 27.399411, 2000);
const destination = defaultPosition;
await this.viewer.camera.flyTo({
destination,
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-60),
roll: 0
},
duration: 2.0
});
// 添加安全的事件监听器
this.viewer.scene.postRender.addEventListener(this.handlePostRender, this);
} catch (error) {
console.error('Cesium初始化错误:', error);
}
},
addRippleEffect() {
try {
// 指定坐标 (113.194006, 27.399411)
const position = Cesium.Cartesian3.fromDegrees(113.194006, 27.399411);
// 创建波纹圆实体(使用??替代弃用的defaultValue)
const rippleOptions = {
color: Cesium.Color.fromCssColorString("#00FFFF").withAlpha(0.6),
speed: 3.0,
count: 6,
gradient: 0.1
};
this.rippleEntity = this.viewer.entities.add({
name: '动态波纹圆',
position: position,
ellipse: {
semiMinorAxis: 500.0,
semiMajorAxis: 500.0,
height: 0,
material: new CircleRippleMaterialProperty(rippleOptions)
}
});
// 添加参考点
this.viewer.entities.add({
position: position,
point: {
pixelSize: 10,
color: Cesium.Color.RED
}
});
} catch (error) {
console.error('添加波纹效果错误:', error);
}
},
// 安全的后渲染处理
handlePostRender() {
// 这里可以添加每帧执行的逻辑
},
// 可选:动态更新波纹参数
updateRippleParams() {
if (this.rippleEntity && this.rippleEntity.ellipse.material) {
// 使用安全访问
this.rippleEntity.ellipse.material.speed = 4.0;
this.rippleEntity.ellipse.material.count = 8;
}
}
}
};
// 加载株洲矢量数据
const loadZhuzhouVector = async (viewer) => {
try {
// 1. 加载株洲市整体边界(绿色填充)
const cityDataSource = await Cesium.GeoJsonDataSource.load(
"https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=430200",
{
clampToGround: true,
stroke: Cesium.Color.GREEN.withAlpha(0.8),
strokeWidth: 2,
fill: Cesium.Color.GREEN.withAlpha(0.3)
}
);
viewer.dataSources.add(cityDataSource);
// 2. 加载株洲各区县边界(白色边框)
const countyDataSource = await Cesium.GeoJsonDataSource.load(
"https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=430200_full",
{
clampToGround: true,
stroke: Cesium.Color.WHITE,
strokeWidth: 1,
fill: Cesium.Color.TRANSPARENT
}
);
viewer.dataSources.add(countyDataSource);
// 添加区县标签
countyDataSource.entities.values.forEach(entity => {
if (entity.polygon && entity.properties && entity.properties.name) {
const hierarchy = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now());
const center = Cesium.BoundingSphere.fromPoints(hierarchy.positions).center;
entity.label = {
text: entity.properties.name,
font: '18px 黑体',
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 3,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
verticalOrigin: Cesium.VerticalOrigin.CENTER,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
pixelOffset: new Cesium.Cartesian2(0, 0),
disableDepthTestDistance: Number.POSITIVE_INFINITY,
scaleByDistance: new Cesium.NearFarScalar(1e3, 1.0, 1e6, 0.5)
};
entity.position = center;
}
});
// 3. 定位到株洲范围
const rectangle = Cesium.Rectangle.fromDegrees(113.50, 24.94, 113.60, 26.84);
viewer.camera.flyTo({
destination: rectangle,
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-70),
roll: 0
},
duration: 2
});
} catch (error) {
console.error("加载株洲数据失败:", error);
const chinaRectangle = Cesium.Rectangle.fromDegrees(73.0, 3.0, 136.0, 59.0);
viewer.camera.flyTo({ destination: chinaRectangle });
}
};
</script>
<style scoped>
.cesium-container {
width: 100%;
height: 100vh;
position: relative;
/* 确保Cesium容器有正确的层级 */
z-index: 0;
}
/* 添加安全边界 */
#cesium-container ::v-deep .cesium-widget {
border: none;
overflow: hidden;
}
#cesium-container ::v-deep .cesium-widget canvas {
display: block;
}
</style>
修改完善,实现加载株洲地区影像并在指定区域加载动态波纹圆功能,将视野定位在株洲
最新发布