目录

  • 1.前言
  • 2.layer.json中available参数意义
  • 3.EPSG:4626切片及terrain分块原理
  • 4.Cesium的terrain分块规则
  • 5.自定义terrain分块规则
  • 6.实验
  • 7.总结

1.前言

  上一篇我们讲到了 metadataAvailability 的含义,它的值是10,意味着每10级会进行一次四叉树的构建,因此第0级和第10级中才包含有元数据的信息。但是我们并没有讲元数据中行列号的分块规则是什么,这一篇,我们就来详细讲一讲。

2.layer.json中available参数意义

  我们先来看下 Cesium ion 官方提供的 layer.json 的结构:

  相信只要是用过 Cesium 的同学对这个结构应该都不陌生吧。那 available 参数什么意思呢?它自然是代表了每一级全部 terrain 瓦片的行列号。我们再来看看available 的结构:

  可以发现,其中包含了15个数组,也就是说 terrain 可以分为15级,每个数组中有一个或多个对象描述了行列号起始和结束号码。那我们的第一个问题就来了:为什么要分块? 要讲清楚这个问题,我们就有必要先来讲下切片的原理了。

3.EPSG:4626切片及terrain分块原理

  我们以 EPSG:4326 为例来讲下切片的规则,直接上图

  通过上图可以明显看出,每一级中列数都是行数的2倍。当我们把第0级,1行2列,画在图上,就变成了这样:

  那么我们怎么用 json 对象来描述它呢?自然是

{startX:0,endX:1,startY:0,endY:0}

  同理,当我们把第1级,2行4列,画在图上,就变成了这样:

  同样的,我们也拿一个 json 来描述它

{startX:0,endX:3,startY:0,endY:1}

  那么,第2级,4行8列,也就顺理成章了:

{startX:0,endX:7,startY:0,endY:3}

  第3级,8行16列:

{startX:0,endX:15,startY:0,endY:7}

  第4级,16行32列,由于网格太多,我们直接给出范围:

{startX:0,endX:31,startY:0,endY:15}

  第5级,32行64列,我们也同样给出范围:

{startX:0,endX:63,startY:0,endY:31}

  注意这里出现了不同,当们观察 Cesium 的数据时,发现并不是这样的,它是分块了,我们来看下:
  很明显,这里分了6块,当我们把它表示成图时,变成了这样:

  细心的读者可能会问,明明分了6块,为什么这里只有5块?仔细看 Cesium 的分块规则,就会发现,第4块类似于一条线,紧挨着第五块。
  至此,我们就可以回答第一个问题了,肯定是由于性能问题,才将较大的块分为较小的块。但是我们又产生了第二个问题:Cesium的分块规则是什么?

4.Cesium的terrain分块规则

  说实话,这个规则 Cesium 并没有公布出来,在官方论坛上搜索相关内容,也只能拿到 The availability structure is not well documented 这样的答案。于是我产生了一个想法,我们能不能按自己的规则来分块呢?
  有了这个想法以后,我们就产生了第三个问题:按多少块来划分呢?

5.自定义terrain分块规则

  还是要回到我们切片规则那里,让我们仔细的回忆一下,跟我一起念,观自在菩萨,行深波若波罗密多时,照见五蕴皆空,度一切苦恶,是玄奘翻译的,咳咳咳,跑题了,赶紧回来:
第0级 1行2列 共2块
第1级 2行4列 共8块
第2级 4行8列 共32块
第3级 8行16列 共512块
第4级 16行32列 共2048块

512!!!这绝对是一个吉利的数字!!!,就它了,从第3级开始刚好是512块,以后每一级都是512的倍数,非常合适。
  那么 Cesium 是多少个网格分一块的呢?仔细看上面第5级的划分,有的是600块,有的是200块,很迷,难怪 Cesium 官网没给出文档。我们就按512来。
  因为第0是两个切片,当层级放大时,由这两个切片继续往下分,所以我们可以将所有切片分为两棵树,即左边的0/0/0.terrain所代表的左树和0/1/0.terrain所代表的右树。其实 Cesium 里也是两棵树,这一点我们是一样的。

6.实验

  既然思路有了,那我们就开始撸代码了,直接上源码。因为 DEM 数据精度不是很高,只算到了11级。

public void GetAvailable()throws IOException {long startx,endx,starty,endy;String json="C:\\Users\\zhangiser\\Desktop\\available.json";File file=new File(json);if(file.exists()){file.delete();file.createNewFile();}else {file.createNewFile();}FileWriter fw=new FileWriter(file);BufferedWriter bw=new BufferedWriter(fw);fw.write("[");//计算每一级的瓦片个数int max=11;for(int i=1;i<max;i++){long row = (long) Math.pow(2, i);long col=row*2;long total=row*col;fw.write("[");if(total<512){//如果瓦片个数没超过512,记录start和end信息startx=starty=0;endx=col-1;endy=row-1;fw.write(String.format("{\"startX\":%s,\"endX\":%s,\"startY\":%s,\"endY\":%s}",startx,endx,starty,endy));}else {//如果大于等于512,那么循环取512个网格为一个块//第4级 16行32列  共512个网格,但需要注意的是000和010的子节点会将这些网格平分//所以后续的分块方案是://行按16为中断点,列按32位中断点long ysplit=row/16;long xsplit=col/32;for (int j = 0; j <ysplit; j++) {for (int k = 0; k < xsplit; k++) {startx=k*32;endx=(k+1)*32-1;starty=j*16;endy=(j+1)*16-1;if(j==ysplit-1 && k==xsplit-1){fw.write(String.format("{\"startX\":%s,\"endX\":%s,\"startY\":%s,\"endY\":%s}",startx,endx,starty,endy));}else{fw.write(String.format("{\"startX\":%s,\"endX\":%s,\"startY\":%s,\"endY\":%s},",startx,endx,starty,endy));}}}}if(i<max-1) fw.write("],");else fw.write("]");}fw.write("]");fw.close();bw.close();}

这是生成layer.json中的available参数的方法,生成左树和右树的方法类似,就不列举了。

  最后,把我们的数据存到 sessionStorage 中,替换掉 Cesium 自己的,看看效果。

  完美,大功告成。

7.总结

  本篇博文中,我们深入的分析了 Cesiumterrainmetadata(元数据)这一拓展的组织形式和分块规则,并成功的修改了它的规则,用自己的修改好的规则和Cesium 的数据结合起来,也能实现数据的顺利加载。最后提一句,CesiumLabCesium 的规则也不一样,有兴趣可以自行对比。好了,本篇就讲到这里了,回见~

Cesium源码解析三(metadata元数据拓展中行列号的分块规则解析)相关推荐

  1. Alian解读SpringBoot 2.6.0 源码(三):启动流程分析之命令行参数解析

    目录 一.背景 1.1.run方法整体流程 1.2.本文解读范围 二.默认应用参数解析 2.1.接口ApplicationArguments 2.2.实现类DefaultApplicationArgu ...

  2. Cesium源码解析一(terrain文件的加载、解析与渲染全过程梳理)

    快速导航(持续更新中-) Cesium源码解析一(terrain文件的加载.解析与渲染全过程梳理) Cesium源码解析二(metadataAvailability的含义) Cesium源码解析三(m ...

  3. 阿里中间件seata源码剖析六:TCC模式中2阶段提交实现

    目录 TM通知TC事务状态 TC通知RM分支事务提交 RM处理TC提交事务请求 总结 上篇文章中,我们以TCC模式的demo为例,讲解了seata中全局事务的开启.在这个demo中,TM作为一个全局事 ...

  4. mybatis源码阅读(三):mybatis初始化(下)mapper解析

    转载自 mybatis源码阅读(三):mybatis初始化(下)mapper解析 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单. ...

  5. spring源码(三)——@Configuration类的注册

    前言 上一篇博客中已经总结到了spring在ConfigurationClassPostProcessor类中调用ConfigurationClassParser#parse方法,开始进行配置类的解析 ...

  6. 【投屏】Scrcpy源码分析三(Client篇-投屏阶段)

    Scrcpy源码分析系列 [投屏]Scrcpy源码分析一(编译篇) [投屏]Scrcpy源码分析二(Client篇-连接阶段) [投屏]Scrcpy源码分析三(Client篇-投屏阶段) [投屏]Sc ...

  7. Cesium源码解读系列(一):GeoJsonDataSource如何处理geojson格式的数据

    想写这个系列的文章起因,是因为项目上的"图层管理"模块功能进行了更改.里面涉及到了一种GeoJson格式的图层数据. 从接口获取到的数据,当时设计接口的时候就已经定好了数据格式.标 ...

  8. Spring源码分析(三)

    Spring源码分析 第三章 手写Ioc和Aop 文章目录 Spring源码分析 前言 一.模拟业务场景 (一) 功能介绍 (二) 关键功能代码 (三) 问题分析 二.使用ioc和aop重构 (一) ...

  9. 【SA8295P 源码分析】10 - HQX Display(OpenWFD)qcdisplaycfg_ADP_STAR_LA.xml 配置文件解析

    [SA8295P 源码分析]10 - HQX Display(OpenWFD)qcdisplaycfg_ADP_STAR_LA.xml 配置文件解析 一.HQX Display 介绍 1.1 Open ...

最新文章

  1. 仿写百度百科的目录树
  2. springcloud 创建子父项目_idea搭建springCloud----搭建父子项目(二)
  3. 苹果A13打得过麒麟990吗?看完秒懂
  4. JDK集合框架结构分析(二)
  5. 亲身经历:如何判断一个字符在a/z之前?
  6. 超简单的Oracle 数据库安装教程(Oracle安装包)
  7. 反射+泛型+注解(demo)
  8. 统计web服务器类型
  9. 光栅图形学(一)——直线段的扫描转换算法
  10. 正宇控股集团丨正宇,扬帆起航
  11. 云服务上搭建halo博客
  12. 10 个Web3 设计灵感网站
  13. vue-amap 实现定位+跑步路程+跑步时间计算功能
  14. HTML5+CSS3 02(表格、表单标签、语义化,字符实体标签)
  15. irreader RSS 订阅源阅读器工具软件 - 一款强大的网络内容阅读器
  16. uniapp 获取 iphone x 底部黑线高度_你知道 iPhone 可以称重吗?附快捷指令版,更方便...
  17. 计算机地质模拟,地质过程计算机模拟.ppt
  18. linux源码编译ant,linux(以ubuntu为例)下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件...
  19. AI绘图、模型切换、角色场景切换,龙坤AI助手全方位提升你的写作体验!
  20. 《python编程快速上手 让繁琐工作自动化》第一章习题答案

热门文章

  1. wifi上网实现智能家居,三选一
  2. Grafana监控系统之Prometheus+Grafana监控系统搭建
  3. 初始C语言(2) C生万物
  4. UBUNTU游戏集合
  5. ERP-非财务人员的财务培训教(二)------如何评价公司/部门经营业绩收藏
  6. aoa计算机二级excel答案,计算机AOA二级中excel的例题及答案
  7. 《软件测试工程师面试秘籍》—第1章1.3节过关斩将
  8. hell脚本之免交互(EOF免交互、Expect免交互)
  9. 涨点神器!ELSA:增强视觉Transformer的局部自注意力
  10. 摊牌了,微软始料未及,Excel和WPS用户:我们已经在使用了