700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Cesium鹰眼<利用Cesium本身你的二维地图和三维地图构成>

Cesium鹰眼<利用Cesium本身你的二维地图和三维地图构成>

时间:2019-03-05 23:54:31

相关推荐

Cesium鹰眼<利用Cesium本身你的二维地图和三维地图构成>

首先加载Cesium,3D地图和2D哥伦布视图

效果图放前面,是不是你想要的效果。免得浪费宝贵的几分钟3D地图加载

<template><div id="CesiumViewer"><slot></slot></div></template><script lang="ts" setup>import * as Cesium from "cesium";import CesiumNavigation from "cesium-navigation-es6";import {ref } from "vue";import {onMounted, onBeforeUnmount } from "vue";const options = defineProps({options: Object,navigatorOptions: {type: Object,default() {return {show: true,};},},});let latLonBounds = {"east": 180.0, "north": 90.0, "south": -90.0, "west": -180.0 };let rectangle = new Cesium.Rectangle(Cesium.Math.toRadians(latLonBounds.west), Cesium.Math.toRadians(latLonBounds.south),Cesium.Math.toRadians(latLonBounds.east), Cesium.Math.toRadians(latLonBounds.north));const MapConfig = {// ION: "",global: {enableLighting: false, //光照开关depthTestAgainstTerrain: true, //高度检测highDynamicRange: false, //是否使用高动态范围渲染。物体需要阳光照射出阴影开启maximumScreenSpaceError: 4 / 3 //用于驱动细节层次细化的最大屏幕空间误差。较高的值将提供更好的性能,但会降低视觉质量 默认2},MAPOPTIONS: {imageryProvider: new Cesium.UrlTemplateImageryProvider({url: 'http://webrd02./appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',minimumLevel: 0,maximumLevel: 18}), //设置影像图列表requestVertexNormals: true,shouldAnimate: true,geocoder: false, //右上角查询按钮shadows: false,terrainProviderViewModels: [], //设置地形图列表animation: false, //动画小窗口baseLayerPicker: false, //图层选择器fullscreenButton: false, //全屏vrButton: false, //vr按钮homeButton: false, //home按钮infoBox: false,sceneModePicker: false, //2D,2.5D,3D切换selectionIndicator: false,timeline: false, //时间轴navigationHelpButton: false, //帮助按钮terrainShadows: Cesium.ShadowMode.DISABLED},};// Cesium.Ion.defaultAccessToken = MapConfig.ION;window.Cesium = Cesium;const $emit = defineEmits(["onViewerLoaded"]);let beActive = ref<Boolean>(false);let viewer: Cesium.Viewer | null;let beforeDestroy = new Cesium.Event();const destroy = (): void => {beforeDestroy.raiseEvent();console.warn("cesium destroy!!");viewer?.destroy();viewer = null;};onMounted(() => {start()});const start = (flag: boolean = false) => {viewer = new Cesium.Viewer("CesiumViewer", {...MapConfig.MAPOPTIONS,...options.options,});(viewer.cesiumWidget.creditContainer as HTMLElement).style.display = "none"; //去除版权信息viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); //移除双击选中let terrainProvider;if (options.options?.terrainProvider) {terrainProvider = options.options.terrainProvider;viewer.terrainProvider = terrainProvider;} else {// terrainProvider = new Cesium.CesiumTerrainProvider({// url: "/public/Terran"// }); }//图像显示效果设置viewer.scene.highDynamicRange = MapConfig.global.highDynamicRangeviewer.scene.globe.maximumScreenSpaceError = MapConfig.global.maximumScreenSpaceErrorviewer.scene.globe.enableLighting = MapConfig.global.enableLighting;viewer.scene.globe.depthTestAgainstTerrain = MapConfig.global.depthTestAgainstTerrain;// 获取要改变的的图层// let layer = viewer.scene.imageryLayers.get(1);//调整伽马值// layer.gamma = 0.66; //改变当前地图的组织结构// layer.magnificationFilter = Cesium.TextureMagnificationFilter.NEAREST;(viewer as any).frameUpdate = new Cesium.Event();let lasTime: null | number;viewer.scene.preUpdate.addEventListener((time) => {let dateNow = Date.now();let deltaTime = lasTime != null ? dateNow - lasTime : 0;lasTime = dateNow;(viewer as any).frameUpdate.raiseEvent(deltaTime);});const {navigatorOptions } = options;if (navigatorOptions?.show === true) {//指南针比例尺let CesiumNavigationOptions = {// 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和Cesium.Rectangle.defaultResetView:navigatorOptions.defaultResetView ||Cesium.Cartographic.fromDegrees(115, 30, 2000000),// 用于启用或禁用罗盘。true是启用罗盘,false是禁用罗盘。默认值为true。如果将选项设置为false,则罗盘将不会添加到地图中。enableCompass: true,// 用于启用或禁用缩放控件。true是启用,false是禁用。默认值为true。如果将选项设置为false,则缩放控件 将不会添加到地图中。enableZoomControls: true,// 用于启用或禁用距离图例。true是启用,false是禁用。默认值为true。如果将选项设置为false,距离图例将不会添加到地图中。enableDistanceLegend: true,// 用于启用或禁用指南针外环。true是启用,false是禁用。默认值为true。如果将选项设置为false,则该环将可见但无效。enableCompassOuterRing: true,};new CesiumNavigation(viewer, CesiumNavigationOptions);}window.Viewer = viewer;beActive.value = true;console.warn("cesium 启动!!");if (!flag) $emit("onViewerLoaded", viewer);}onBeforeUnmount(() => {destroy();});defineExpose({start })</script><style lang="less" scoped>#CesiumViewer {width: 100%;height: 100%;margin: 0;padding: 0;overflow: hidden;}</style>

2D地图加载

<template><div class="eye" id="eagleEye"></div></template><script lang="ts" setup>import {onMounted, onUnmounted } from 'vue'import * as Cesium from "cesium";import {getCurrentExtent, getZoomLevel, getCenterPosition, zoomToAltitude } from '@/components/Cesium/utils/tool'onMounted(() => {initMap()})const props = defineProps({viewer: {type: Cesium.Viewer}})let eyeViewer: Cesium.Viewer | nullconst initMap = () => {eyeViewer = new Cesium.Viewer("eagleEye", {animation: false,baseLayerPicker: false,fullscreenButton: false,imageryProvider: new Cesium.UrlTemplateImageryProvider({url: 'http://webrd02./appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',minimumLevel: 0,maximumLevel: 18}),geocoder: false,homeButton: false,infoBox: false,sceneModePicker: false,selectionIndicator: false,timeline: false,navigationHelpButton: false,scene3DOnly: false,navigationInstructionsInitiallyVisible: false,showRenderLoopErrors: false,sceneMode: Cesium.SceneMode.SCENE2D,});(eyeViewer.cesiumWidget.creditContainer as HTMLElement).style.display = "none"; //去除版权信息//限制相机高度范围eyeViewer.scene.screenSpaceCameraController.minimumZoomDistance = 500.0addListenerEvent()syncViewer()}let rectangleArr: number[] = []let entity: Cesium.Entity | undefinedconst drawRegionalScope = () => {//绘制区域范围轮廓 const extent = getCurrentExtent((props.viewer as Cesium.Viewer)) //相机当前视野范围const {xmin, ymax, xmax, ymin } = extentrectangleArr = [xmin, ymin,xmin,ymax, xmax, ymax, xmax, ymin, xmin, ymin]if (!entity) {entity = eyeViewer?.entities.add({polyline: {positions: new Cesium.CallbackProperty(() => {return Cesium.Cartesian3.fromDegreesArray(rectangleArr);}, false),show: true,material: Cesium.Color.RED,width: 3,clampToGround: true //是否贴地}});}}let isMapTrigger: boolean = truelet isEyeMapTrigger: boolean = falseconst addListenerEvent = () => {const viewer: Cesium.Viewer = (props.viewer as Cesium.Viewer);const scene = viewer.scene;const sceneEye = eyeViewer?.scene;const handlerL = new Cesium.ScreenSpaceEventHandler(scene.canvas);const handlerR = new Cesium.ScreenSpaceEventHandler(sceneEye?.canvas);handlerL.setInputAction(() => {isMapTrigger = true;isEyeMapTrigger = false;}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);handlerR.setInputAction(() => {isMapTrigger = false;isEyeMapTrigger = true;}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);viewer.scene.camera.moveEnd.addEventListener(syncViewer); //主地图更新后触发eyeViewer?.scene.camera.moveEnd.addEventListener(syncViewerR);//小地图更新后触发}const syncViewer = () => {if (isMapTrigger) {const level = getZoomLevel((props.viewer as Cesium.Viewer).camera) //获取当前层级const {lon, lat } = getCenterPosition((props.viewer as Cesium.Viewer)) //获取中心点eyeViewer?.camera.setView({destination: Cesium.Cartesian3.fromDegrees(lon, lat, zoomToAltitude(level - 1))});drawRegionalScope()}};const syncViewerR = () => {if (isEyeMapTrigger && eyeViewer) {const level = getZoomLevel(eyeViewer.camera)const {lon, lat } = getCenterPosition(eyeViewer);(props.viewer as Cesium.Viewer).camera.setView({destination: Cesium.Cartesian3.fromDegrees(lon, lat, zoomToAltitude(level + 1)),orientation: {heading: (props.viewer as Cesium.Viewer).camera.heading,pitch: (props.viewer as Cesium.Viewer).camera.pitch,roll: (props.viewer as Cesium.Viewer).camera.roll,}});drawRegionalScope()}};onUnmounted(() => {(props.viewer as Cesium.Viewer).scene.camera.moveEnd.removeEventListener(syncViewer);eyeViewer?.scene.camera.moveEnd.removeEventListener(syncViewerR);eyeViewer?.entities.removeAll()eyeViewer = nullentity = undefined})</script><style lang="less" scoped>.eye {position: absolute;right: 25px;bottom: 30px;border-radius: 50%;width: 200px;height: 200px;overflow: hidden;border: 2px solid orange;box-shadow: 2px 2px 3px #2b2b2b;z-index: 10;}</style>

tip:重点就是在两个地图容器更新后同步到另一个地图中,因为鹰眼地图容器小很多,所以鹰眼地图的层级总是比地图容器大一级。

文中用到的函数

/*@ 相机当前视野范围*/export function getCurrentExtent(viewer: Cesium.Viewer) {//范围对象let extent = {xmin: 0,ymax: 0,xmax: 0,ymin: 0,height: 0,xminRadian: 0,ymaxRadian: 0,xmaxRadian: 0,yminRadian: 0,};// 得到当前三维场景const scene = viewer.scene;// 得到当前三维场景的椭球体const ellipsoid = scene.globe.ellipsoid;const canvas = scene.canvas;// canvas左上角const car3_lt = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, 0), ellipsoid);// canvas右下角const car3_rb = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(canvas.width, canvas.height), ellipsoid);// 当canvas左上角和右下角全部在椭球体上if (car3_lt && car3_rb) {const carto_lt = ellipsoid.cartesianToCartographic(car3_lt);const carto_rb = ellipsoid.cartesianToCartographic(car3_rb);extent.xmin = Cesium.Math.toDegrees(carto_lt.longitude);extent.ymax = Cesium.Math.toDegrees(carto_lt.latitude);extent.xmax = Cesium.Math.toDegrees(carto_rb.longitude);extent.ymin = Cesium.Math.toDegrees(carto_rb.latitude);extent.xminRadian = Cesium.Math.toDegrees(carto_lt.longitude);extent.ymaxRadian = Cesium.Math.toDegrees(carto_lt.latitude);extent.xmaxRadian = Cesium.Math.toDegrees(carto_rb.longitude);extent.yminRadian = Cesium.Math.toDegrees(carto_rb.latitude);}// 当canvas左上角不在但右下角在椭球体上else if (!car3_lt && car3_rb) {let car3_lt2 = null;let yIndex = 0;do {// 这里每次10像素递加,一是10像素相差不大,二是为了提高程序运行效率yIndex <= canvas.height ? yIndex += 10 : canvas.height;car3_lt2 = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0,yIndex), ellipsoid);} while (!car3_lt2);let carto_lt2 = ellipsoid.cartesianToCartographic(car3_lt2);let carto_rb2 = ellipsoid.cartesianToCartographic(car3_rb);extent.xmin = Cesium.Math.toDegrees(carto_lt2.longitude);extent.ymax = Cesium.Math.toDegrees(carto_lt2.latitude);extent.xmax = Cesium.Math.toDegrees(carto_rb2.longitude);extent.ymin = Cesium.Math.toDegrees(carto_rb2.latitude);extent.xminRadian = Cesium.Math.toDegrees(carto_lt2.longitude);extent.ymaxRadian = Cesium.Math.toDegrees(carto_lt2.latitude);extent.xmaxRadian = Cesium.Math.toDegrees(carto_rb2.longitude);extent.yminRadian = Cesium.Math.toDegrees(carto_rb2.latitude);} // 获取高度extent.height = Math.ceil(viewer.camera.positionCartographic.height);return extent;}export function getCenterPosition(viewer: Cesium.Viewer) {let centerResult = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(viewer.canvas.clientWidth / 2,viewer.canvas.clientHeight / 2,),)let curLongitude = 0let curLatitude = 0let height = 0if(centerResult) {let curPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(centerResult);curLongitude = (curPosition.longitude * 180) / Math.PI;curLatitude = (curPosition.latitude * 180) / Math.PI;height = Math.ceil(viewer.camera.positionCartographic.height);}return {lon: curLongitude,lat: curLatitude,height}}export function getZoomLevel(camera: Cesium.Camera) {let height = camera.positionCartographic.height;const A = 40487.57;const B = 0.00007096758;const C = 91610.74;const D = -40467.74;return Math.round(D+(A-D)/(1+Math.pow(height/C, B)));}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。