【Cesium】五、地图实现鹰眼效果(三维)

参考文章:cesium实现鹰眼地图(三维)效果

一、实现效果

在这里插入图片描述

二、实现方法

2.1 实现思路

在网上看了有关Cesium鹰眼地图实现的方法,发现分为两种,一种是使用leaflet,另一种是Cesium新建Viewer,这里使用cesium新建viewer的方式来实现鹰眼地图。

这里采用在鹰眼图中仅添加百度地图作为指引,并设置鹰眼地图的相机位置与主图完全一致。

参考官方API中的camera的percentageChanged方法和changed事件。

其中percentageChanged用于设置相机变化幅度才能发生事件监听。而changed则用于监听相机变化事件。

在这里插入图片描述
最近发现主图第一次刷新时鹰眼地图不会更新,这里是解决办法是使用scene的preRender事件监听:传送门
即在场景渲染前更新。

在这里插入图片描述

2.2 具体实现

核心代码,utils下新建HawkEyeMap.js,代码如下:

import * as Cesium from "cesium";
/*
 * @Description: 鹰眼地图效果
 * @Version: 1.0
 * @Author: Julian
 * @Date: 2022-02-25 16:23:36
 * @LastEditors: Julian
 * @LastEditTime: 2022-02-26 12:40:35
 */

export class HawkEyeMap {
    constructor(viewer) {
        this._viewer = viewer;
        this._hawkEyeMap = null;
    }

    // 初始化函数
    _init() {
        this._hawkEyeMap = new Cesium.Viewer('hawkEyeMap', {
            infoBox: false,
            geocoder: false,
            homeButton: false,
            sceneModePicker: false,
            baseLayerPicker: false,
            navigationHelpButton: false,
            animation: false,
            timeline: false,
            fullscreenButton: false,
        });
        this._hawkEyeMap.cesiumWidget.creditContainer.style.display = 'none';
        this._hawkEyeMap.scene.backgroundColor = Cesium.Color.TRANSPARENT;
        this._hawkEyeMap.imageryLayers.removeAll();

        // 鹰眼图中添加高德路网中文注记图
        this._hawkEyeMap.imageryLayers.addImageryProvider(
            new Cesium.UrlTemplateImageryProvider({
                url: "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}",
                minimumLevel: 3,
                maximumLevel: 18
            })
        );

        // 引起事件监听的相机变化幅度
        this._viewer.camera.percentageChanged = 0.01;

        this._bindEvent();
    }

    // 绑定事件
    _bindEvent() {
        // 监听主图相机变化
        this._viewer.camera.changed.addEventListener(this._syncMap, this);
        // 第一次刷新渲染时联动(否则第一次鹰眼地图不会联动)
        // this._viewer.scene.preRender.addEventListener(this._syncEyeMap, this);
    }

    // 同步主图与鹰眼地图
    _syncMap() {
        this._hawkEyeMap.camera.flyTo({
            destination: this._viewer.camera.position,
            orientation: {
                heading: this._viewer.camera.heading,
                pitch: this._viewer.camera.pitch,
                roll: this._viewer.camera.roll,
            },
            duration: 0.0,
        })
    }
}

2.3 样式设置

template 部分添加鹰眼html代码:

  <div id="hawkEyeMap"></div>

css部分添加鹰眼样式:

/* 鹰眼图样式 */
#hawkEyeMap {
  position: absolute;
  left: 70%;
  top: 2%;
  border-radius: 50%;
  height: 160px;
  width: 160px;
  overflow: hidden;
  border: 2px solid #002FA7;
}

2.4 js 部分

先引入刚刚创建的js文件

import { HawkEyeMap } from '@/utils/HawkEyeMap.js';

使用

let hawkEyeMap = new HawkEyeMap(viewer);
hawkEyeMap._init();

2.5 App.vue 全部代码

修改完后 App.vue 全部代码如下(供参考):

<template>
  <div id="cesiumContainer"></div>
  <div id="hawkEyeMap"></div>
</template>
<script setup>
import { onMounted, reactive, ref } from "vue";
import * as Cesium from "cesium";
import { HawkEyeMap } from '@/utils/HawkEyeMap.js';
const initFn = async () => {
  const viewer = new Cesium.Viewer("cesiumContainer", {
    infoBox: false,
    geocoder: false,
    homeButton: false,
    sceneModePicker: false,
    baseLayerPicker: true,
    navigationHelpButton: false,
    animation: false,
    timeline: false,
    fullscreenButton: false,
    vrButton: false,
  });
  viewer._cesiumWidget._creditContainer.style.display = "none"; //取消版权信息
  const imageLayers = viewer.scene.imageryLayers;
  imageLayers.remove(imageLayers.get(0)); //移除默认影像图层
  const TDTTK = "337bc7a038fe9d239af76ab013ff4594"; //填入你自己的天地图Key
  // 天地图影像
  const tdtLayer = new Cesium.WebMapTileServiceImageryProvider({
    url: `http://t0.tianditu.com/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={TileMatrix}&TILEROW={TileRow}&TILECOL={TileCol}&tk=${TDTTK}`,
    layer: "tdt",
    style: "default",
    format: "image/jpeg",
    tileMatrixSetID: "w",
    maximumLevel: 18,
    show: false,
  });
  viewer.imageryLayers.addImageryProvider(tdtLayer);
  // 天地图注记
  const tdtAnnotionLayer = new Cesium.WebMapTileServiceImageryProvider({
    url: `http://t0.tianditu.com/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={TileMatrix}&TILEROW={TileRow}&TILECOL={TileCol}&tk=${TDTTK}`,
    layer: "tdtAnno",
    style: "default",
    format: "image/jpeg",
    tileMatrixSetID: "w",
    maximumLevel: 18,
    show: false,
  });
  viewer.imageryLayers.addImageryProvider(tdtAnnotionLayer);


  let hawkEyeMap = new HawkEyeMap(viewer);
  hawkEyeMap._init();

};

onMounted(() => {
  // Cesium 初始化
  initFn();
});
</script>
<style>
#app {
  width: 100%;
  height: 100%;
  font-family: sans-serif;
  text-align: center;
}

html,
body,
#cesiumContainer {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

/* 鹰眼图样式 */
#hawkEyeMap {
  position: absolute;
  left: 70%;
  top: 2%;
  border-radius: 50%;
  height: 160px;
  width: 160px;
  overflow: hidden;
  border: 2px solid #002FA7;
}
</style>

后面我还会更新更多关于cesium知识,敬请关注。