参考文章: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知识,敬请关注。