Cesium 影像卷帘对比

一、概述

Cesium  影像卷帘对比,就是把上层影像卷起来,和下面一层影像做对比。

可左卷也可右卷,具体参考Cesium官网,有例子。

二、效果

三、代码

复制代码

  1 <!--
  2  * @Author: 苹果园dog
  3  * @Date: 2021-01-11 14:45:09
  4  * @LastEditTime: 2021-01-17 18:52:14
  5  * @LastEditors: Please set LastEditors
  6  * @Description: 影像卷帘对比
  7  * @FilePath: \code\bayannaoer.web.vue\src\views\visualiPage\imageSplitAnalysis.vue
  8 -->
  9 <!--  -->
 10 <template>
 11   <div style="width: 100%; height: 100%" class="main">
 12     <div class="container">
 13       <el-form :inline="true" class="demo-form-inline">
 14         <img
 15           src="../../assets/img/left.png"
 16           :class="{ selected: tool == 'left' }"
 17           @click="set(true)"
 18           title="左卷"
 19         />
 20         <img
 21           src="../../assets/img/right.png"
 22           :class="{ selected: tool == 'right' }"
 23           @click="set(false)"
 24           title="右卷"
 25         />
 26       </el-form>
 27     </div>
 28   </div>
 29 </template>
 30 
 31 <script>
 32 //这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
 33 //例如:import 《组件名称》 from '《组件路径》';
 34 import bus from "../../commonUtil/bus";
 35 export default {
 36   //import引入的组件需要注入到对象中才能使用
 37   components: {},
 38   data() {
 39     //这里存放数据
 40     return {
 41       left: true,
 42       imageLayer: undefined,
 43       slider: undefined,
 44       tool: "left",
 45     };
 46   },
 47   //监听属性 类似于data概念
 48   computed: {},
 49   //监控data中的数据变化
 50   watch: {},
 51   //方法集合
 52   methods: {
 53     init() {
 54       let that = this;
 55       this.initSplit();
 56       bus.$on("imageSplitAnalysis", (visible) => {
 57         if (visible) {
 58           that.show();
 59         } else {
 60           that.close();
 61         }
 62       });
 63     },
 64 
 65     initSplit() {
 66       let that = this;
 67       this.slider = this.$parent.$parent.$refs.splitslider.$el;
 68       //this.slider = document.getElementById("image_slider");
 69       var handler = new Cesium.ScreenSpaceEventHandler(this.slider);
 70       var moveActive = false;
 71       function move(movement) {
 72         if (!moveActive) {
 73           return;
 74         }
 75         var relativeOffset = movement.endPosition.x;
 76         var splitPosition =
 77           (that.slider.offsetLeft + relativeOffset) /
 78           that.slider.parentElement.offsetWidth;
 79         that.slider.style.left = 100.0 * splitPosition + "%";
 80         viewer.scene.imagerySplitPosition = splitPosition;
 81       }
 82       handler.setInputAction(function () {
 83         moveActive = true;
 84       }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
 85       handler.setInputAction(function () {
 86         moveActive = true;
 87       }, Cesium.ScreenSpaceEventType.PINCH_START);
 88       handler.setInputAction(move, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
 89       handler.setInputAction(move, Cesium.ScreenSpaceEventType.PINCH_MOVE);
 90       handler.setInputAction(function () {
 91         moveActive = false;
 92       }, Cesium.ScreenSpaceEventType.LEFT_UP);
 93       handler.setInputAction(function () {
 94         moveActive = false;
 95       }, Cesium.ScreenSpaceEventType.PINCH_END);
 96     },
 97     show: function () {
 98       let winSplit = this.$parent.$parent.$refs.imageSplitAnalysis;
 99       if (!winSplit) {
100         alert("功能初始化失败!");
101         bus.$emit("imageSplitAnalysis", false);
102         return;
103       }
104       var layercontrol = this.$parent.$parent.$refs.leftTreeWin;
105       if (!layercontrol) {
106         bus.$emit("imageSplitAnalysis", false);
107         return;
108       }
109       var selected = layercontrol.$children[0].selected;
110       if (!selected || selected.type != "image") {
111         bus.$emit("imageSplitAnalysis", false);
112         return;
113       }
115       if (!selected.layer) {
116         return;
117       }
118       selected.image = selected.layer;
119       viewer.flyTo(selected.image);
121       viewer.imageryLayers.raiseToTop(selected.image);
122       this.visible = true;
123       this.imageryLayer = selected.image;
124       this.set(true);
125       winSplit.open();
126     },
127     close: function () {
128       this.visible = false;
129       this.imageryLayer.splitDirection = Cesium.ImagerySplitDirection.NONE;
130     },
131     toggle: function () {
132       if (this.visible) {
133         this.close();
134       } else {
135         this.show();
136       }
137     },
138     set: function (v) {
139       this.left = v;
140       if (this.left) {
141         this.tool = "left";
142         if (this.imageryLayer) {
143           this.imageryLayer.splitDirection = Cesium.ImagerySplitDirection.LEFT;
144         }
145       } else {
146         this.tool = "right";
147         if (this.imageryLayer) {
148           this.imageryLayer.splitDirection = Cesium.ImagerySplitDirection.RIGHT;
149         }
150       }
151       viewer.scene.imagerySplitPosition = 0.5;
152       this.slider.style.left = "50%";
153     },
154   },
155   //生命周期 - 创建完成(可以访问当前this实例)
156   created() {},
157   //生命周期 - 挂载完成(可以访问DOM元素)
158   mounted() {
159     this.init();
160   },
161   beforeCreate() {}, //生命周期 - 创建之前
162   beforeMount() {}, //生命周期 - 挂载之前
163   beforeUpdate() {}, //生命周期 - 更新之前
164   updated() {}, //生命周期 - 更新之后
165   beforeDestroy() {}, //生命周期 - 销毁之前
166   destroyed() {}, //生命周期 - 销毁完成
167   activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
168 };

复制代码

<think>好的,我现在需要回答用户关于Cesium中Polygon的SplitDirection属性和实现卷帘效果的问题。首先,我要确认自己对这两个概念的理解是否正确。 SplitDirection属性是Cesium中用来控制多边形分割方向的,可能用于动态显示或隐藏部分区域。卷帘效果通常是指在地图上通过拖动分割线来对比不同图层或同一图层不同部分的效果。用户想结合这两个功能来实现动画效果。 接下来,我需要查阅相关资料。用户提供的引用中有关于Cesium工具应用、缓冲区分析、三维模型加载和剖面分析的内容,可能涉及相关属性的使用。例如,剖面分析可能用到了动态分割技术,可以参考其实现方法。 然后,思考SplitDirection的具体用法。Cesium的Polygon实体可能有一个splitDirection属性,接受如SplitDirection.LEFT或RIGHT等值,控制哪一侧可见。可能需要结合其他属性如material来设置透明度,实现动态分割效果。 关于卷帘动画,可能需要使用Cesium的CallbackProperty动态更新splitDirection的值,或者调整分割位置。例如,通过时间函数改变分割线的位置,形成动画效果。引用中的剖面分析可能使用了类似的技术,通过回调函数动态更新几何形状。 然后,整理步骤:创建带有splitDirection的Polygon,设置材质,使用CallbackProperty动态更新splitDirection的值,可能结合时间函数或用户交互事件来触发更新。需要编写示例代码,演示如何实现动画。 还需要考虑可能的注意事项,比如性能优化,或者不同版本Cesium的兼容性。引用中的资料可能提供了最佳实践,比如使用WebGL优化技巧或者如何有效管理实体更新。 最后,生成相关问题,帮助用户深入理解。例如,如何优化卷帘动画的性能,或者如何结合其他Cesium功能增强效果。 总结回答结构:先解释SplitDirection的作用,然后分步骤说明实现卷帘动画的方法,提供代码示例,最后给出注意事项和相关问题。</think>在Cesium中,`SplitDirection`属性用于控制多边形在特定方向的动态分割效果,结合时间轴可实现卷帘动画。以下是实现步骤与技术细节: ### 一、SplitDirection属性解析 1. **作用机制** `SplitDirection`属于Cesium.PolygonGraphics属性,支持设置`LEFT`、`RIGHT`或`NONE`,控制多边形的可见区域分割方向。例如: ```javascript polygon.splitDirection = new Cesium.ConstantProperty(Cesium.SplitDirection.LEFT); ``` 此时多边形仅左侧可见,右侧透明化[^1]。 2. **动态控制** 通过`CallbackProperty`实现实时更新分割线位置: ```javascript const splitPosition = viewer.clock.currentTime; // 基于时间轴驱动 polygon.splitDirection = new Cesium.CallbackProperty(() => { return splitPosition > threshold ? Cesium.SplitDirection.LEFT : Cesium.SplitDirection.RIGHT; }, false); ``` ### 二、卷帘动画实现步骤 1. **基础场景配置** 初始化Viewer并添加底图与时间轴控件: ```javascript const viewer = new Cesium.Viewer('cesiumContainer', { timeline: true, animation: true }); ``` 2. **创建带分割的多边形** 定义多边形实体并配置材质与分割属性: ```javascript const polygonEntity = viewer.entities.add({ polygon: { hierarchy: Cesium.Cartesian3.fromDegreesArray([/*坐标数组*/]), material: new Cesium.ImageMaterialProperty({ image: 'texture.png', transparent: true }), splitDirection: new Cesium.CallbackProperty(updateSplitDirection, false) } }); ``` 3. **动态回调函数** 编写`updateSplitDirection`函数控制分割位置: ```javascript function updateSplitDirection() { const currentTime = viewer.clock.currentTime.secondsOfDay; const progress = (currentTime % 10) / 10; // 10秒循环周期 return progress > 0.5 ? Cesium.SplitDirection.LEFT : Cesium.SplitDirection.RIGHT; } ``` 4. **添加交互控制(可选)** 绑定滑块控件手动调整分割位置: ```html <input type="range" id="slider" min="0" max="1" step="0.01"> ``` ```javascript document.getElementById('slider').addEventListener('input', e => { splitPosition = parseFloat(e.target.value); }); ``` ### 三、性能优化建议 - 使用`ClassificationType.TERRAIN`避免多边形与地形叠加时的渲染冲突[^2] - 对静态数据启用`allowGeometryUpdating: false`减少计算开销 - 采用Web Worker处理复杂分割逻辑,避免主线程阻塞 ### 四、扩展应用场景 1. **时空数据对比** 通过双向卷帘对比历史影像与现状数据,常用于土地利用变化分析[^3] 2. **剖面分析增强** 结合`Cesium.ClippingPlane`实现三维地质模型的动态切割,与平面卷帘形成立体对比效果[^4] ```javascript // 完整示例代码 const viewer = new Cesium.Viewer('cesiumContainer', { timeline: true }); const positions = Cesium.Cartesian3.fromDegreesArray([-100, 40, -90, 40, -95, 35]); const polygonEntity = viewer.entities.add({ polygon: { hierarchy: positions, material: Cesium.Color.BLUE.withAlpha(0.5), splitDirection: new Cesium.CallbackProperty(time => { const x = Cesium.JulianDate.toDate(time).getSeconds() % 10 / 10; return x > 0.5 ? Cesium.SplitDirection.LEFT : Cesium.SplitDirection.RIGHT; }, false) } }); viewer.clock.shouldAnimate = true; ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苹果园dog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值