Cesium 源码笔记[1] Viewer模块实例化的大致过程
我原本想写日记的,但是不太现实。
源码下载
源码可以从源码包和发行包中的Source目录中获取。
Cesium的模块化机制从1.63版本开始,由原来的RequireJs变为ES6。但有可能是原先设计耦合的问题,内部依旧是ES5实现。
入口:实例化Viewer时到底发生了什么
写Cesium程序时,都写过这一句:
let viewer = new Cesium.Viewer(dom)
或者这样
let viewer = new Cesium.Viewer(dom, {
terrainProvider: Cesium.createWorldTerrain()
})
那它究竟在后面发生了什么呢?
Viewer.js
定位到302行,Viewer的构造函数如下:
function Viewer(container, options) {
...
}
就从这个长达400多行的构造函数看起吧!
// 304~309行
if (!defined(container)) {
throw new DeveloperError('container is required.');
}
container = getElement(container);
这一步,是看看DOM元素是否存在,使用getElement模块判断是domID或者是DOM元素变量,并返回。
工具模块:defaultValue
// 310行
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
这一步是判断传进来的options对象是否为空,如果为空,那就使用空对象预设值(defaultValue.EMPTY_OBJECT))。其中,defaultValue是一个重要的模块,它判断第一个参数如果是undefined,就把第二个参数作为它的值返回,如果不是undefined,那就返回它本身。
工具模块:defined
// 312~313行
var createBaseLayerPicker = (!defined(options.globe) || options.globe !== false) &&
(!defined(options.baseLayerPicker) || options.baseLayerPicker !== false);
这一步通过defined模块判断构造参数options是否有globe属性、baseLayerPicker属性来决定是否创建底图选择器控件。defined模块的作用就是,判断传入值是否定义,定义了就返回true。
329行将Viewer实例的this变量赋予给that变量。
331~344行是Viewer视图底下的一堆空间的div DOM元素创建。
346~362行,利用defaultValue模块和defined模块
判断传入参数options中scene3DOnly参数是否赋值,如果没有则默认为false,即是否仅使用3d场景的意思;
判断传入参数options中的时钟模型属性clockViewModel是否存在,来决定是用传入的时钟模型,亦或者是用系统的时钟模型;
判断传入参数options中是否定义了shouldAnimate属性,如果定义了,则将时钟的同名属性设为同样的值。
最初的一步: CesiumWidget创建
// Cesium.js 364~388行
var cesiumWidget = new CesiumWidget(cesiumWidgetContainer, {
imageryProvider: createBaseLayerPicker || defined(options.imageryProvider) ? false : undefined,
clock : clock,
skyBox : options.skyBox,
skyAtmosphere : options.skyAtmosphere,
sceneMode : options.sceneMode,
mapProjection : options.mapProjection,
globe : options.globe,
// ... 太长了不贴了
});
这一步和创建Viewer很像,但是它却更接近数据承载体一步。
为了保证单元的完整性,CesiumWidget的实例化,后面再说。提前透露:高频API,Scene、imageryProvider、Globe等均在这一步继续创建。
其他的初始化
390~615行,是对Viewer的一些其他属性的初始化,分别是界面上的一众按钮、时间轴等控件的初始化,以及事件总管理者(EventHelper模块)的初始化、重要的DataSourceCollection/DataSourceDisplay的初始化。
在后面Viewer部分的笔记中,关于这些控件的初始化,还会继续详细展开。
DataSourceCollection/DataSourceDisplay属于数据范围,不列入Viewer部分的笔记中。
最后,将以上初始化的对象,全部注册注册为当前Viewer实例的属性,并将其中一些对象例如dataSourceCollection的一些事件一并注册到Viewer的原型上。
除了以上初始化之外,Cesium还默认为cesiumWidget注册了屏幕操作事件的点击、双击事件,方便初始化完成后能通过点击来拾取场景中的Entity(场景Scene、实体Entity是数据范围,不作详细介绍了),这两个事件使用cesiumWidget.screenSpaceEventHandler.setInputAction方法来注册。这两个事件位于构造函数的689~708行。
原型定义
工具方法:Object.defineProperties
这几乎是每一个Cesium模块都会做的一步,使用Object.defineProperties,为某个对象赋予某个属性。
据说这个Object.defineProperties是近几个版本才启用的,之前js没有这个方法时,是用Cesium.defineProperties的。
在Viewer.js模块中的711~1292行,官方为Viewer的原型定义了一大批属性,包括上文提及的初始化的多个对象、事件等,还包括上文创建的各个初始化的对象的一些属性快捷连接,以便能在Viewer实例上直接访问其他模块的属性。
例如你既能在Viewer上获取camera,也能在Scene模块获取camera,只不过Viewer上返回的camera也要先访问scene罢了。
随后,在12941523行和17241858行,为Viewer的原型定义了一堆API文档中能看到的公共方法;在15251703和18632056行为Viewer的原型定义了一堆私有方法。
导出Viewer模块
最后,在2066行,使用es6语法导出Viewer构造函数。
版权所有。转载请联系我,B站/知乎/小专栏/博客园/CSDN @秋意正寒
https://www.cnblogs.com/onsummer/p/12571971.html
Cesium 源码笔记[1] Viewer模块实例化的大致过程的更多相关文章
- redis源码笔记(一) —— 从redis的启动到command的分发
本作品采用知识共享署名 4.0 国际许可协议进行许可.转载联系作者并保留声明头部与原文链接https://luzeshu.com/blog/redis1 本博客同步在http://www.cnblog ...
- Tomcat8源码笔记(八)明白Tomcat怎么部署webapps下项目
以前没想过这么个问题:Tomcat怎么处理webapps下项目,并且我访问浏览器ip: port/项目名/请求路径,以SSM为例,Tomcat怎么就能将请求找到项目呢,项目还是个文件夹类型的? Tom ...
- Tomcat8源码笔记(七)组件启动Server Service Engine Host启动
一.Tomcat启动的入口 Tomcat初始化简单流程前面博客介绍了一遍,组件除了StandardHost都有博客,欢迎大家指文中错误.Tomcat启动类是Bootstrap,而启动容器启动入口位于 ...
- Tomcat8源码笔记(六)连接器Connector分析
根据 Tomcat8源码笔记(五)组件Container分析 前文分析,StandardService的初始化重心由 StandardEngine转移到了Connector的初始化,本篇记录下Conn ...
- Tomcat8源码笔记(五)组件Container分析
Tomcat8源码笔记(四)Server和Service初始化 介绍过Tomcat中Service的初始化 最先初始化就是Container,而Container初始化过程是咋样的? 说到Contai ...
- Tomcat8源码笔记(四)Server和Service初始化
上一章 简单说明下Tomcat各个组件: Server:服务器,Tomcat服务器,一个Tomcat只有一个Server组件; Service:业务层,是Server下最大的子容器,一个Server可 ...
- Tomcat8源码笔记(三)Catalina加载过程
之前介绍过 Catalina加载过程是Bootstrap的load调用的 Tomcat8源码笔记(二)Bootstrap启动 按照Catalina的load过程,大致如下: 接下来一步步分析加载过程 ...
- 【转】Spark源码分析之-deploy模块
原文地址:http://jerryshao.me/architecture/2013/04/30/Spark%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E4%B9%8B- ...
- Golang构建HTTP服务(一)--- net/http库源码笔记
搭建一个简单的Go Web服务器 Go语言标准库 - net/http 在学习Go语言有一个很好的起点,Go语言官方文档很详细,今天我们学习的Go Web服务器的搭建就需要用到Go语言官方提供的标准库 ...
随机推荐
- Android(四)-JVM与DVM区别
JVM与DVM区别 1.由来 Android是基于java的既然java已经有了java虚拟机,为什么android还要弄一个DVM了?最重要的就是版权问题,一开始就是用的 JVM,没过多久就被SUN ...
- C++扬帆远航——8(张三李四,等差数列)
/* * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:qiudengcha数列.cpp * 作者:常轩 * 完成日期: ...
- Docker深入浅出系列 | 单机Nginx+Springboot实战
目录 Nginx+Springboot实战 前期准备 实战目标 实战步骤 创建Docker网络 搭建Mysql容器 搭建额度服务集群 搭建Nginx服务 验证额度服务 附录 Nginx+Springb ...
- C#使用正则表达式获取HTML代码中a标签里包含指定后缀的href的值
//C#使用正则表达式获取HTML代码中a标签里包含指定后缀的href的值,表达式如下: Regex regImg = new Regex(@"(?is)<a[^>]*?href ...
- Python左手画条龙右手画个彩虹
左手画龙右手画彩虹听说很火,Python也可以画出很美的彩虹,准确的说像彩虹棒棒糖:) 效果如下图: # -*- coding: utf-8 -*- # @Time : 2019/12/16 23:2 ...
- 大厂面试官问你META-INF/spring.factories要怎么实现自动扫描、自动装配?
大厂面试官问你META-INF/spring.factories要怎么实现自动扫描.自动装配? 很多程序员想面试进互联网大厂,但是也有很多人不知道进入大厂需要具备哪些条件,以及面试官会问哪些问题, ...
- SpringBoot整合Swagger2案例,以及报错:java.lang.NumberFormatException: For input string: ""原因和解决办法
原文链接:https://blog.csdn.net/weixin_43724369/article/details/89341949 SpringBoot整合Swagger2案例 先说SpringB ...
- SQL Server 最小日志记录
SQL Server之所以记录事务日志,首要目的是为了把失败或取消的操作还原到最原始的状态,但是,并不是所有的操作都需要完全记录事务日志,比如,在一个空表上放置排他锁,把大量的数据插入到该空表中.即使 ...
- node--静态文件托管,路由,模板引擎
1.路由 路由是由一个URI和一个特定的HTTP方法(GET/POST)组成的 涉及到应用如何响应客户端对某个网站节点的访问 2.ejs 3.get/post 1)get获取数据 通过Url类中的qu ...
- 全差分运算放大器ADA4930的分析(1)
AD转换芯片的模拟信号输入端方式为:全差分.伪差分.单端输入,其中全差分输入的效果最佳,现阶段ADC转换器为了提高其性能,建议用户使用全差分的输入方式.(AD7982.ADS8317等都能实现信号的全 ...