cesium实现卷帘分屏效果【Cesium 影像卷帘对比】

1,465 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情

“金秋十月,我要连续30天更文,做劳模,拿手机摄影神器!点击查看活动详情 “即可成功参与

碰这个东西主要是昨天领导突然给我分配了这个任务(cesium我可是小白中的小白啊),对于从来没接触过cesium的我来说,我只能借助百度来帮助我,终于功夫不负有心人,今天下午搞出来了,话不多说直接上代码:

  //分割线
  <div  id="slider" @mousedown="move"></div>   
    
    //分割线样式
    #slider {
    position: absolute;
    left: 50%;
    top: 0px;
    background-color: #d3d3d3;
    width: 5px;
    height: 845px;
    z-index: 999;
  }

  #slider:hover {
    cursor: ew-resize;
  }

js代码:

<script setup lang="ts">
  import { ref } from 'vue';
  import * as Cesium from 'cesium';
  let viewer: any = null;//图层名
  // 分割线移动
  const move = (e) => {
    //获取到分割线
    const oLine = e.target;
    // 算出鼠标相对元素的位置
    const disX = e.clientX - oLine.offsetLeft;
    // 鼠标按下并移动的事件
    document.onmousemove = (e) => {
      // 用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
      const left = e.clientX - disX;
      // 移动当前元素
      oLine.style.left = left + 'px';
      // 根据分割线设置分屏位置
      viewer.scene.splitPosition = oLine.offsetLeft / oLine.parentElement.offsetWidth;
    };
    // 鼠标离开清除事件
    document.onmouseup = () => {
      document.onmousemove = null;
      document.onmouseup = null;
    };
  };
  // 添加图层
  const initMap = () => {
    viewer = new Cesium.Viewer('rollerBtn', {
      baseLayerPicker: false, // 地图选择器,用于展示不同图层样式
      sceneModePicker: false, // 模式切换按钮
      timeline: false, // 时间轴
      animation: false, // 时钟
      fullscreenButton: false, // 全屏
      geocoder: false, // 自定义地理编码
      homeButton: false, // 主页按钮
      navigationHelpButton: false // 右上角的帮助按钮,
    });
    const layers = viewer.imageryLayers;
    viewer._cesiumWidget._creditContainer.style.display = 'none'; // 隐藏logo版权
    const td = '02ed99e199228a5d47960a0324894605'; // 一天只能请求一万次啊
    //  相机聚焦 将三维球定位到中国
    viewer.camera.flyTo({
      destination: Cesium.Cartesian3.fromDegrees(116.24840246582028, 29.732265252147997, 20000), // 经纬度 高度
      orientation: {
        heading: Cesium.Math.toRadians(348.4202942851978),
        pitch: Cesium.Math.toRadians(-89.74026687972041),
        roll: Cesium.Math.toRadians(0)
      },
      complete: function callback() {
        // 定位完成之后的回调函数
        console.log(' 定位完成之后的回调函数');
      }
    });
    // 图层显示
    viewer.imageryLayers.addImageryProvider(
      new Cesium.UrlTemplateImageryProvider({
        url: 'https://nanchang.3zyun.com/image/wmts/m/{z}/{x}/{y}' // 服务地址
      })
    );
    // 天地图加载
    const TDTImgProvider = new Cesium.WebMapTileServiceImageryProvider({
      url:
        'http://t{s}.tianditu.com/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=' +
        td,
      layer: '天地图影像',
      style: 'default',
      format: 'image/jpeg',
      subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
      tileMatrixSetID: 'GoogleMapsCompatible'
    });
    const TDTZJProvider = new Cesium.WebMapTileServiceImageryProvider({
      url:
        'http://t{s}.tianditu.com/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default.jpg&tk=' +
        td,
      layer: '天地图中文注记',
      style: 'default',
      format: 'image/jpeg',
      subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
      tileMatrixSetID: 'GoogleMapsCompatible'
    });
    layers.addImageryProvider(TDTImgProvider);
    layers.addImageryProvider(TDTZJProvider);
    // 设置左右图层
    const layer1 = new Cesium.WebMapServiceImageryProvider({
      url: 'http://47.101.148.107:8085/geoserver/ows',
       layers: 'fw:zjdzrz_zzgh',
      parameters: {
        service: 'WMS',
        format: 'image/png',
        transparent: true
      }
    });
    const layer2 = new Cesium.WebMapServiceImageryProvider({
      url: 'http://47.101.148.107:8085/geoserver/ows',
      layers: 'fw:' + changeNameArr[1],
      parameters: {
        service: 'WMS',
        format: 'image/png',
        transparent: true
      }
    });
     // 将影像添加到cesium图层中
    const earthAtRight = layers.addImageryProvider(layer1);
    const earthAtLeft = layers.addImageryProvider(layer2);
     // 设置影像位于左边 或者右边
    earthAtLeft.splitDirection = Cesium.SplitDirection.LEFT;//添加到左侧
    earthAtRight.splitDirection = Cesium.SplitDirection.RIGHT;//添加到右侧
    //核心代码
    const slider: any = document.getElementById('slider');
    let handler: any = new Cesium.ScreenSpaceEventHandler(slider);
    if (handler) {
      handler.destroy();
      handler = null;
    }
    if (slider) {
      viewer.scene.splitPosition = slider.offsetLeft / slider.parentElement.offsetWidth; // 设置分屏的位置,分割线移动动态设置分屏位置就是依靠这句代码
      let moveActive = false;
      function move(movement: any) {
        if (!moveActive) {
          return;
        }
        const relativeOffset = movement.endPosition.x;
        if (slider.parentElement) {
          const splitPosition = (slider.offsetLeft + relativeOffset) / slider.parentElement?.offsetWidth;
          slider.style.left = `${100.0 * splitPosition}%`;
          viewer.scene.splitPosition = splitPosition; // 设置卷帘左右分区范围(0-1)之间
          viewer.scene.imagerySplitPosition = splitPosition;
        }
      }
      handler.setInputAction(function () {
        moveActive = true;
      }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
      handler.setInputAction(function () {
        moveActive = true;
      }, Cesium.ScreenSpaceEventType.PINCH_START);

      handler.setInputAction(move, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
      handler.setInputAction(move, Cesium.ScreenSpaceEventType.PINCH_MOVE);

      handler.setInputAction(function () {
        moveActive = false;
      }, Cesium.ScreenSpaceEventType.LEFT_UP);
      handler.setInputAction(function () {
        moveActive = false;
      }, Cesium.ScreenSpaceEventType.PINCH_END);
    }
  };
</script>

效果:

image.png

image.png

分割线在哪就从哪里开始分屏

可移动地图查看影像对比效果,可移动分割线查看影像对比效果