四叶小天使!

上承

CesiumWidget实际上和Viewer差不多。以下两句代码用于初始化,效果是差不多的。

const widget = new Cesium.CesiumWidget('id选择器')
const viewer = new Cesium.Viewer('id选择器')

实例化Viewer必定会实例化一个CesiumWidget。CesiumWidget实际上代表的是三维数据可视区域,而Viewer除了包括可视区域,还包括各种控件(时间轴、右上角各种按钮、搜索框、时间拨盘等),更像是一个总体承载容器。Viewer能通过extend()方法扩充自定义的控件。

真正使用WebGL绘图的,还不是CesiumWidget模块,而是在CesiumWidget中实例化的Scene模块。
不过,CesiumWidget起了一个桥梁的作用,它将构造时传递的DOM元素(或ID选择器)再内嵌了一个canvas元素,再将此canvas元素传递给Scene,让Scene接着绘图。
比较Viewer和CesiumWidget和Scene分别作用的DOM元素,用一张图表示:

构造原理

DOM构造

// function CesiumWidget(container, options)构造函数内,第180~207行
if (!defined(container)) {throw new DeveloperError('container is required.');
}
container = getElement(container);
options = defaultValue(options, defaultValue.EMPTY_OBJECT);var element = document.createElement('div');
element.className = 'cesium-widget';
container.appendChild(element);
// ...
var canvas = document.createElement('canvas');
// ...
element.appendChild(canvas);

我忽略了一些内容。这不到30行代码,完成了上级Viewer的DOM元素判断,完成了本级DOM元素创建,并完成了下一级DOM元素——canvas的创建,判断了传递进来的options参数是否为空。

关于下一级DOM元素canvas,还配置了一些HTML相关的事件、配置等,不详细展开了。

这样,DOM的层级关系就制造完毕了。

接下来还有一些其他的小部件(例如商标版权等)以及分辨率等设置,位于209~219行。

221~238行,将CesiumWidget的私有变量赋值完毕,并调用configureCanvasSize()来调整canvas的尺寸。

场景及有关对象构造

在240~349行,是一个大大的try/catch块,CesiumWidget模块的构造函数这部分代码,完成了Scene、Globe、SkyBox、SkyAtmosphere模块的实例化。

而最终暴露到CesiumWidget的API中的,有camera、scene、imageryLayers、terrainProvider、screenSpaceEventHandler、clock这几个主要的对象。

这让我十分郁闷的事情来了,某个模块的属性(例如CesiumWidget的属性——camera)并不是它原型上的,而是这个模块的别的属性的原型上的(camera属性其实是属于Scene模块的)。不理解Js原型的同学可以理解为Java的类,原型是Js(ES5)实现面向对象的一个重要设计模式。

从以下代码可以看到:

// CesiumWidget.js模块
Object.defineProperties(CesiumWidget.prototype, {// ...camera : { // 449行get : function() {return this._scene.camera;}},// ...
}

这种设计在Cesium的API中非常常见,原理归原理,API归API。想要弄清楚谁是谁的崽儿(Scene.camera),而不是被谁抚养的(CesiumWidget.camera),只能通过源码来知晓。

回归正题。

// CesiumWidget.js,241~255行
var scene = new Scene({canvas : canvas,contextOptions : options.contextOptions,creditContainer : innerCreditContainer,creditViewport: creditViewport,mapProjection : options.mapProjection,// 太长了不贴了// ...
});
this._scene = scene;

实例化Scene对象,传递主要的构造参数,大部分来自CesiumWidget的构造参数options中。

// CesiumWidget.js,257~260行
scene.camera.constrainedAxis = Cartesian3.UNIT_Z;configurePixelRatio(this);
configureCameraFrustum(this);

指定摄像机的约束轴为Z轴,触发私有函数调整像素比例和摄像机视锥体。

// CesiumWidget.js,262~271行
var ellipsoid = defaultValue(scene.mapProjection.ellipsoid, Ellipsoid.WGS84);var globe = options.globe;
if (!defined(globe)) {globe = new Globe(ellipsoid);
}
if (globe !== false) {scene.globe = globe;scene.globe.shadows = defaultValue(options.terrainShadows, ShadowMode.RECEIVE_ONLY);
}

创建ellipsoid和globe,并传递给scene.

273~299行创建环境因素,主要是天空盒和太阳、月亮、大气环境。

302~314行创建影像数据源(若无,则调用createWorldImagery模块创建世界影像,和CesiumION的token有关)和地形数据源,并传递给scene。影像数据源和地形数据源均可以从options中获取,若options没有,则使用Cesium官方给的,需要注意token问题。

318~325行确定scene对象的视图模式是二维的、三维的还是哥伦布的(2.5D)。

316,333~341行给scene绑定了渲染错误事件处理函数。

327~331行,确定了是否使用默认的循环渲染机制(useDefaultRenderLoop属性),这个属性若为false,则需要手动调用CesiumWidget.render()渲染。还确定了在默认循环渲染机制时,目标帧速率(targetFrameRate属性)。

原型上的属性定义

// CesiumWidget.js,352~581行
Object.defineProperties(CesiumWidget.prototype, {container : {get : function() {return this._container;}},// ...// 太长不贴了
}

API文档中能看到的CesiumWidget的属性,均在此定义了,使用的是Object.defineProperties()方法。

原型上的方法定义

CesiumWidget.js中593~708行,是CesiumWidget的API中所有方法的定义。

  • CesiumWidget.prototype.showErrorPanel = function(title, message, error) {...}
  • CesiumWidget.prototype.isDestroyed = function() {...}
  • CesiumWidget.prototype.destroy = function() {...}
  • CesiumWidget.prototype.resize = function() {...}
  • CesiumWidget.prototype.render = function() {...}

当渲染错误时,调用showErrorPanel方法,弹出个对话框。

如果CesiumWidget被销毁了,调用isDestroyed方法返回的是true。

destroy()方法用于需要销毁整个视图时。

当窗口大小发生变化时,调用resize方法调整canvas和camera。

render方法是自动调用的,通常不需要开发者关心,除非设置CesiumWidget.useDefaultRenderLoop为false。这个方法是用来渲染场景的。

导出模块

最后在709行,导出此模块。

// CesiumWidget.js,709行
export default CesiumWidget;

版权所有。转载请联系我,B站/知乎/小专栏/博客园/CSDN @秋意正寒

cesium 知乎_Cesium 源码笔记[2] CesiumWidget模块的实例化过程 ver1.67相关推荐

  1. phpcms 指定id范围 调用_Dubbogo 源码笔记(二)客户端调用过程

    作者 | 李志信 导读:有了上一篇文章<Dubbo-go 源码笔记(一)Server 端开启服务过程>的铺垫,可以类比客户端启动于服务端的启动过程.其中最大的区别是服务端通过 zk 注册服 ...

  2. Dubbo-go 源码笔记(二)客户端调用过程

    作者 | 李志信 导读:有了上一篇文章<Dubbo-go 源码笔记(一)Server 端开启服务过程>的铺垫,可以类比客户端启动于服务端的启动过程.其中最大的区别是服务端通过 zk 注册服 ...

  3. vue如何让一句代码只执行一次_lt;Vue 源码笔记系列4gt;异步更新队列与$nextTick...

    1. 前言 原文发布在语雀: <Vue 源码笔记系列4>异步更新队列与$nextTick · 语雀​www.yuque.com 上一章我们讲到了修改数据是如何触发渲染函数的观察者,最终调用 ...

  4. 狂神Spring Boot 员工管理系统 【源码 + 笔记 + web素材】 超详细整理

    目录 员工管理系统 1.准备工作 1.1.导入资源 1.2.编写pojo层 1.3.编写dao层 2.首页实现 2.1.引入Thymeleaf 2.2.编写MyMvcConfig 2.3.测试首页 3 ...

  5. angularjs源码笔记(3)--injector

    2019独角兽企业重金招聘Python工程师标准>>> 简介 injector是用来做参数自动注入的,例如 function fn ($http, $scope, aService) ...

  6. spring aop原理_Spring知识点总结!已整理成142页离线文档(源码笔记+思维导图)...

    写在前面 由于Spring家族的东西很多,一次性写完也不太现实.所以这一次先更新Spring[最核心]的知识点:AOP和IOC 无论是入门还是面试,理解AOP和IOC都是非常重要的.在面试的时候,我没 ...

  7. 数据结构源码笔记(C语言描述)汇总

    数据结构源码笔记(C语言):英文单词按字典序排序的基数排序 数据结构源码笔记(C语言):直接插入排序 数据结构源码笔记(C语言):直接选择排序 数据结构源码笔记(C语言):置换-选择算法 数据结构源码 ...

  8. 数据结构源码笔记(C语言):英文单词按字典序排序的基数排序

    //实现英文单词按字典序排序的基数排序算法#include<stdio.h> #include<malloc.h> #include<string.h>#defin ...

  9. 数据结构源码笔记(C语言):索引文件建立和查找

    //实现索引文件建立和查找算法#include<stdio.h> #include<malloc.h> #include<string.h> #include< ...

最新文章

  1. 图论-无向图的连通性(POJ1144)(POJ3352)
  2. svn冲突的解决办法
  3. 本地Windows远程桌面连接阿里云Ubuntu 16.04服务器:
  4. GetProcAddress()用法
  5. python 爬虫框架_Python实战:爬虫框架(6)
  6. 程序-进程-线程 ( 多线程 )
  7. JAVA人脸识别(人脸对比)
  8. android root权限命令行,如何通过命令行取得安卓root权限
  9. java从键盘输入任意一组数据存入数组中统计非负数个数及非负数个数
  10. CSDN-markdown总结前辈经验
  11. 萌新记一次在openEuler下安装VMware-Tools的失败经历
  12. 计算机网络相关知识总结
  13. 大学生活质量指北,高考毕业生填报志愿参考必备
  14. E - Stripies
  15. 中国煤矿机械行业市场动态调研及未来发展方向分析报告2022-2028年
  16. js 中国标准时间,时间戳 ,yyyy-mm-dd格式之前相互转换
  17. 中国工业制造RFID市场竞争力排名分析与投资战略规划研究报告2022-2028年版
  18. nrf52832 学习笔记(七)蓝牙协议层级理解
  19. 解决在线视频(如b站等)中没有IDM下载浮动条问题
  20. AIX系统安装sqluldr2

热门文章

  1. 把javabean复制到另一个javabean 使用BeanUtils.copyProperties(a,b) 复制
  2. java框架----mybatis的使用(一)
  3. pc端实现 网页居中显示 且自适应
  4. js关闭当前页面窗口的问题
  5. solr返回的字段带有中括号问题
  6. 动态参数 maven_Spring Security 动态url权限控制(三)
  7. 通道注意力机制_即插即用,Triplet Attention机制让Channel和Spatial交互更加丰富(附开源代码)...
  8. sd卡和sdio sdhc_想买TF卡,那些标注卡上的参数看懂了么?
  9. 开多线程出现importerror_那些年让你迷惑的并行、并发、多线程、多进程、协程...
  10. C++ 你想要的C++面经都在这(附答案 | 持续更新)