cesium-模型室内漫游

这里漫游方法同样适用于室外漫游

漫游思路分析

  1. 先加载室内模型
  2. 初始化相机视角的位置
  3. 添加对应的控制点(相机漫游路径)
  4. 控制相机运动位置
    • 设置飞行的时间到viewer的时钟里
    • 相机原地定点转向
    • 计算两点间的偏航角
  5. 设置停止漫游方法

完整代码

以下代码有具体的注释和介绍

<!DOCTYPE html>
<html lang="en">
<head><!-- Use correct character set. --><meta charset="utf-8"/><!-- Tell IE to use the latest, best version. --><meta http-equiv="X-UA-Compatible" content="IE=edge"/><!-- Make the application on mobile take up the full browser screen and disable user scaling. --><meta name="viewport"content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/><title>模型室内漫游</title><script src="https://data.sunbt.ltd/lib/Cesium-1.89/Build/Cesium/Cesium.js"></script><script src="../../static/lib/vue.min.js"></script><style>@import url(https://data.sunbt.ltd/lib/Cesium-1.89/Build/Cesium/Widgets/widgets.css);html,body, #temp {width: 100%;height: 100%;margin: 0;padding: 0;overflow: hidden;}#cesiumContainer {width: 100%;height: 100%;margin: 0;padding: 0;overflow: hidden;}</style>
</head>
<body>
<div id="temp"><div style="display: -webkit-flex;display: flex;width: 100%;height: 100%"><div style="width: 90%;height: 100%"><div id="cesiumContainer"></div></div><div style="width: 10%;height: 100%;background-color: #d3d3d3;padding: 30px"><button class="btn" @click="modelLocate">模型定位</button><button class="btn" @click="roamIndoor">模型漫游</button><button class="btn" @click="cancelFlyEvent">停止漫游</button></div></div>
</div>
<script>let EarthComp = new Vue({el: "#temp",data: {_earth: undefined, // 注意:Earth和Cesium的相关变量放在vue中,必须使用下划线作为前缀!_viewer: undefined,model: null,//切片模型marks: [],marksIndex: 1,pitchValue: -10,remainTime: 0,usedTime: 0,},mounted: function () {let that = this;this.earthInit();},methods: {/*** 地球初始化*/earthInit() {//天地图tokenlet TDT_tk = "your token";//Cesium tokenlet cesium_tk = "your token";//标注let TDT_CIA_C = "http://{s}.tianditu.gov.cn/cia_c/wmts?service=wmts&request=GetTile&version=1.0.0" +"&LAYER=cia&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}" +"&style=default&format=tiles&tk=" + TDT_tk;// 添加mapbox自定义地图实例let layer = new Cesium.MapboxStyleImageryProvider({url: 'https://api.mapbox.com/styles/v1',username: 'sungang',styleId: 'styleId',accessToken: 'accessToken',scaleFactor: true});//初始页面加载Cesium.Ion.defaultAccessToken = cesium_tk;let viewer = new Cesium.Viewer('cesiumContainer', {geocoder: false,   // 位置查找工具baseLayerPicker: false,// 图层选择器(地形影像服务)timeline: false, // 底部时间线homeButton: false,// 视角返回初始位置fullscreenButton: false, // 全屏animation: false,   // 左下角仪表盘(动画器件)sceneModePicker: false,// 选择视角的模式(球体、平铺、斜视平铺)navigationHelpButton: false, //导航帮助按钮imageryProvider: layer});//调用影响中文注记服务viewer.imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({url: TDT_CIA_C,layer: "tdtImg_c",style: "default",format: "tiles",tileMatrixSetID: "c",subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],tilingScheme: new Cesium.GeographicTilingScheme(),tileMatrixLabels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"],maximumLevel: 50,show: false}))this._viewer = viewer;// 去除版权信息this._viewer._cesiumWidget._creditContainer.style.display = "none";// 初始化模型位置this.addModel();},/*** 添加模型*/addModel() {// 3Dtiles切片地址let tileset = this._viewer.scene.primitives.add(new Cesium.Cesium3DTileset({url: 'http://192.168.1.243:8088/data/3dtiles/tianjie/tileset.json',modelMatrix: Cesium.Matrix4.fromArray([0.9972458032561666, 0.04372029028528979, 0.05991113506964879, 0,-0.03623787897545647, 0.9920229449104262, -0.12073646051879428, 0,-0.06471185374661931, 0.11823287609043515, 0.9908750491338749, 0,-663.0794944260269, 1211.490494620055, 2974.1003134818748, 1]),}));this.model = tileset;this._viewer.flyTo(tileset, {offset: {heading: Cesium.Math.toRadians(20.0),//方向pitch: Cesium.Math.toRadians(-25),//倾斜角度range: 1000}});},/*** 模型定位*/modelLocate() {let that = this;this._viewer.flyTo(this.model, {offset: {heading: Cesium.Math.toRadians(120.0),//方向pitch: Cesium.Math.toRadians(-10),//倾斜角度range: 450}});},/*** 室内漫游* 初始化相机位置*/roamIndoor() {let that = this;/** 相机视角飞行 开始 **/this.marks = [// height:相机高度(单位米) flytime:相机两个标注点飞行时间(单位秒){lng: 118.69184532414744, lat: 32.16119279415843, height: 5, flytime: 5},{lng: 118.69192079776337, lat: 32.16112689859642, height: 5, flytime: 5},{lng: 118.69223881961578, lat: 32.16098664838045, height: 5, flytime: 5}];// 地标集合 根据地标顺序来进行漫游this.marksIndex = 1;this.pitchValue = -10;this._viewer.scene.camera.flyTo({//定位坐标点,建议使用谷歌地球坐标位置无偏差destination: Cesium.Cartesian3.fromDegrees(that.marks[0].lng, that.marks[0].lat, that.marks[0].height),duration: 2,   //定位的时间间隔orientation: {heading: Cesium.Math.toRadians(120.0),//方向pitch: Cesium.Math.toRadians(-10),//倾斜角度roll: 0}});setTimeout(function () {that.flyExtent();}, 2000);},//控制相机运动方法flyExtent() {let that = this;let marks = that.marks;// let marksIndex = that.marksIndex;let pitchValue = that.pitchValue;let viewer = that._viewer;// 相机看点的角度,如果大于0那么则是从地底往上看,所以要为负值let pitch = Cesium.Math.toRadians(pitchValue);// 时间间隔2秒钟that.setExtentTime(that.marks[that.marksIndex].flytime);let Exection = function TimeExecution() {let preIndex = that.marksIndex - 1;//当到达最后一个点时,继续漫游if (that.marksIndex === 0) {preIndex = marks.length - 1;}//计算偏航角let heading = that.bearing(marks[preIndex].lat, marks[preIndex].lng, marks[that.marksIndex].lat, marks[that.marksIndex].lng);heading = Cesium.Math.toRadians(heading);// 当前已经过去的时间,单位slet delTime = Cesium.JulianDate.secondsDifference(viewer.clock.currentTime, viewer.clock.startTime);let originLat = that.marksIndex === 0 ? marks[marks.length - 1].lat : marks[that.marksIndex - 1].lat;let originLng = that.marksIndex === 0 ? marks[marks.length - 1].lng : marks[that.marksIndex - 1].lng;//计算相机下一次的位置let endPosition = Cesium.Cartesian3.fromDegrees((originLng + (marks[that.marksIndex].lng - originLng) / marks[that.marksIndex].flytime * delTime),(originLat + (marks[that.marksIndex].lat - originLat) / marks[that.marksIndex].flytime * delTime),marks[that.marksIndex].height);viewer.scene.camera.setView({destination: endPosition,orientation: {heading: heading,pitch: pitch,}});//当到达下一个点的时候,重新设置相机偏航角if (Cesium.JulianDate.compare(viewer.clock.currentTime, viewer.clock.stopTime) >= 0) {viewer.clock.onTick.removeEventListener(Exection);that.changeCameraHeading();}};//让cesium的时钟方法来监听该方法viewer.clock.onTick.addEventListener(Exection);},// 设置飞行的时间到viewer的时钟里setExtentTime(time) {let that = this;let viewer = that._viewer;let startTime = Cesium.JulianDate.fromDate(new Date());let stopTime = Cesium.JulianDate.addSeconds(startTime, time, new Cesium.JulianDate());viewer.clock.startTime = startTime.clone();  // 开始时间viewer.clock.stopTime = stopTime.clone();     // 结速时间viewer.clock.currentTime = startTime.clone(); // 当前时间viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; // 行为方式viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; // 时钟设置为当前系统时间; 忽略所有其他设置。},// 相机原地定点转向changeCameraHeading() {let that = this;let marks = that.marks;let marksIndex = that.marksIndex;let pitchValue = that.pitchValue;let viewer = that._viewer;let nextIndex = that.marksIndex + 1;if (that.marksIndex === marks.length - 1) {nextIndex = 0;}// 计算两点之间的方向let heading = that.bearing(marks[marksIndex].lat, marks[marksIndex].lng, marks[nextIndex].lat, marks[nextIndex].lng);// 相机看点的角度,如果大于0那么则是从地底往上看,所以要为负值let pitch = Cesium.Math.toRadians(pitchValue);// 给定飞行一周所需时间,比如10s, 那么每秒转动度数let angle = (heading - Cesium.Math.toDegrees(viewer.camera.heading)) / 2;if (angle < -90)angle += 180;else if (angle > 90)angle -= 180;// 时间间隔2秒钟that.setExtentTime(2);// 相机的当前headinglet initialHeading = viewer.camera.heading;let exection = function TimeExecution() {// 当前已经过去的时间,单位slet delTime = Cesium.JulianDate.secondsDifference(viewer.clock.currentTime, viewer.clock.startTime);let heading = Cesium.Math.toRadians(delTime * angle) + initialHeading;viewer.scene.camera.setView({orientation: {heading: heading,pitch: pitch,}});if (Cesium.JulianDate.compare(viewer.clock.currentTime, viewer.clock.stopTime) >= 0) {viewer.clock.onTick.removeEventListener(exection);that.marksIndex = ++that.marksIndex >= marks.length ? 0 : that.marksIndex;that.flyExtent();}};//让cesium的时钟方法来监听该方法viewer.clock.onTick.addEventListener(exection);},//计算两点间的偏航角bearing(startLat, startLng, destLat, destLng) {startLat = this.toRadians(startLat);startLng = this.toRadians(startLng);destLat = this.toRadians(destLat);destLng = this.toRadians(destLng);let y = Math.sin(destLng - startLng) * Math.cos(destLat);let x = Math.cos(startLat) * Math.sin(destLat) - Math.sin(startLat) * Math.cos(destLat) * Math.cos(destLng - startLng);let brng = Math.atan2(y, x);let brngDgr = this.toDegrees(brng);return (brngDgr + 360) % 360;},/** 飞行时 camera的方向调整(heading) 开始 **/// Converts from degrees to radians.toRadians(degrees) {return degrees * Math.PI / 180;},// Converts from radians to degrees.toDegrees(radians) {return radians * 180 / Math.PI;},/** 停止漫游方法 **/cancelFlyEvent(eventType) {let that = this;//获取被clock监听的全部事件数量let len = that._viewer.clock.onTick.numberOfListeners;for (let i = 0; i < len; i++) {//将被监听的方法移除来停止方法that._viewer.clock.onTick.removeEventListener(that._viewer.clock.onTick._listeners[i]);}},},})
</script></body>
</html>

示例截图

cesium-模型室内漫游相关推荐

  1. 利用VRML设计简单的交互三维室内漫游场景

    利用VRML设计简单的三维室内漫游场景 利用3dmaxs建模 VRMLPad里编辑代码 利用3dmaxs建模 首先,利用3dmaxs或其他的建模工具建模.这里建的模很简单,因为小文件方便调试,示例中的 ...

  2. cesium 模型绕点飞行一周

    cesium 模型绕点飞行一周 // 加载glb模型原地旋转//获取锥体的坐标var position = Cesium.Cartesian3.fromDegrees(116.358504190185 ...

  3. Cesium模型制作服务

    Cesium模型制作服务 1..X..dae..obj.3dmax.sketchup等工具软件制作的模型,批量转换,需提供每个模型具体位置和转角(Cesium默认经纬度坐标系,提供的坐标可转换为经纬度 ...

  4. cesium实现自定义漫游路径

    cesium实现自定义漫游路径,实现cesium按照我们自己设置的路径漫游,也可以删除节点,添加节点,加速漫游,减速漫游.效果如下(记录) //公用时间czml,为后面的自定义路径提供模板 var c ...

  5. cesium模型不遮挡点线面_cesium点线面测试数据

    //初始化cesium var viewer = new Cesium.Viewer('cesiumContainer',{ imageryProvider:new Cesium.SingleTile ...

  6. cesium模型纹理替换

    一.概述 一个cesium管网项目中,默认情况下,用不同颜色表示不同的管网类型.当点击到对应的管网时,需要动态替换管网的纹理,以达到表达管网流向的目的. 二.替换步骤 1.添加需要替换的图片到Reso ...

  7. 基于unity+HTC VIVE的室内漫游交互(教你如何“无代码”VR交互)

    简单粗暴,一个插件让你无代码实现VR交互 开发环境steamVR2.0+unity2017.1.0f1 steamVR2.0下载地址 一.总体目标 Unity+HTC VIVE 开发: 1.场景漫游+ ...

  8. cesium实现飞行漫游

    <template><div><div class="container"><el-buttontype="primary&qu ...

  9. cesium模型加载-加载fbx格式模型

    整体思路: fbx格式→dae格式→gltf格式→cesium加载gltf格式模型 具体方法: 1. fbx格式→dae格式 工具:3dsMax, 3dsMax插件:OpenCOLLADA, 下载地址 ...

最新文章

  1. 互联网协议 — Ethernet — 冲突域、广播域
  2. vmware上给根分区增加空间以及创建逻辑卷
  3. Lesson 028 —— python 模块
  4. 如何在路由器的局域网下使用IIS发布网页
  5. 面试官:能说说Redis的持久化机制吗?
  6. == 和 equals方法的区别
  7. Docker加入白名单
  8. uniapp中qrcode生成二维码后传的参数不见了_二维码扫描登录,你必须知道的 3 件事...
  9. 【元胞自动机】基于matlab元胞自动机单车道交通流(时空图)【含Matlab源码 1681期】
  10. 15.计算几何: 坐标值的精度【eps、sgn()、dcmp()】+ 平面上的点用struct表示 + 向量的定义与加减乘除
  11. 俱乐部2006年的首次活动-ASP.NET Webpart 开发交流会暨2005回顾
  12. 【C语言 穷举法编程实例——韩信点兵问题(苏小红版C语言(第3版))】
  13. java的Serialization机制
  14. 计算机应用系特色活动,职教桥:用匠心打造计算机应用专业特色课程体系
  15. golang版本管理gvm
  16. 2月编程语言排行榜谁还没有看?
  17. 二维码解码器Zbar 的配置和基本使用
  18. 【Map】Echarts之iphone销量地图的使用以及详细配置
  19. 计算 1! + 2! + 3! + 4! +... + 10! 说明:4! 表示4的阶乘。4的阶乘是:1 * 2 * 3 * 4
  20. GUI,UGUI,NGUI三种编辑UI界面的插件

热门文章

  1. 穿梭在银河的火箭队——Alpha冲刺总结随笔
  2. GD32(7)程序烧录及运行
  3. 如何尽早发现潜在开发风险,降低项目风险?
  4. Fabric 1.0源代码分析(15)gossip(流言算法)
  5. 协同过滤算法之通过Jaccard相似度计算推荐结果原理及代码实现
  6. Android 插桩之美,全面掌握
  7. 行走的Offer收割机Java面经
  8. webpack打包优化之moment语言包优化moment-locales-webpack-plugin
  9. 在conda中安装pytorch
  10. matalb曲线图只有点没有线_老股民教你精准把握买卖点只需一个指标:分时图,学到就是赚到!...