Cesium案例之单体化
1.前言
单体化,听起来有点高大上,其实就是拾取模型,比如点击一个模型弹出一段信息框,显示该模型的信息。因为3Dtiles是一个整体,所以不能像threejs一样加载一个独立的模型,就可以直接为这个模型添加点击事件,于是就有了叫单体化的过程。官方示例中,就是一个典型的例子,可以点击某一幢建筑物,同时在右侧显示这幢建筑物的信息,另外一个示例,对于Pick效果展示的可能更加充分。
参考文章:
【1】.分类单体化的说明 (这就是如何进行点击选中一座房子的问题)
【2】.Cesium 案例分析 –单体化分析(分栋、分层)
【3】.cesium 3dtiles模型单体化点击高亮效果 (这里提供了一个结合Geoserver实现的单体化,鼠标点击倾斜模型,获取对应的点击坐标点;然后根据pick获取到的坐标点,结合geoserver发布的wfs服务,进行空间查询,匹配对应的geojson数据;最后根据获取到的geojson数据源来绘制显示高亮效果,并且弹出对应气泡窗口。)
【4】.CESIUM例子学习(九)——Primitive(4) (这里的代码其实也和上面的参考文章2的代码差不多,使用的是Primitive进行绘制)
2.原理
(1)切割单体化
通过建筑物矢量帮助我们进行空间计算,将建筑物矢量范围内的连续的三角面从倾斜摄影模型上截取出来,从而实现单体化。(2)矢量单体化
其原理是在进行三维渲染时,将矢量面的几何数据传递到GPU中,判断每个顶点是否在其范围内。如果在范围内,就高亮该区域显示的颜色;或者,使用类似阴影体(Shadow Volume,三维图形中一种常见的生成阴影的算法)的技术,来使矢量的单体化区域高亮。(3)ID单体化
指给倾斜摄影模型的每个想要单体化的区域的连续网格赋予一个特定的ID,这样在选中的时候我们获取到这个ID并对其高亮显示。(4)模型重建单体化
干脆就加入人工干预,重新构建单体化三维模型。
参考文章:
【1】.倾斜摄影单体化如何实现? 1.最直观的思路,就是用建筑物、道路、树木等对应的矢量面,对倾斜摄影模型进行切割,即把连续的三角面片网从物理上分割开,从而实现单体化。2,利用三角面片中每个顶点额外的存储空间,把对应的矢量面的ID值存储起来;即一个建筑所对应的三角面片的所有顶点,都存储了同一个ID值,从而实现在鼠标选中这个建筑时,该建筑可以呈现出高亮的效果。3.在三维渲染的时候,动态的把对应的矢量面叠加到倾斜摄影模型上,类似于一个保鲜膜从上到下完整的把对应建筑等物体的模型包裹起来,从而实现可被单独选中的效果。
【2】.基于正射影像边界检测的倾斜摄影模型单体化方法
【3】.在高德地图上实现建筑模型动态单体化 这里采用的就是高德的API进行了动态单体化的过程,看起来就是先创建了一个规则的盒模型,把模型罩着,之后再进行选中。
【4】.一种对倾斜摄影成果进行地物分类及单体化提取的方法 对多视角特征图像进行实例分割,通过目标检测提取目标地物的边缘轮廓,对提取的目标地物赋予类别标签,并进行标记,获取标记结果;对分割后的具有相同类别特征的目标地物采用地物特征构建条件约束模型,完成像素级的目标地物分割,获取地物目标分类结果;
【5】.倾斜单体化模型技术实现 1.切割单体化;2.矢量单体化;
3.鼠标拾取模型
这种其实非常的简单,就是通过监听鼠标的点击事件,判断是否选中了一个对象,选中了对象,则修改该对象的颜色,弹出对象的信息框。
1 | // 监听鼠标事件 |
参考文章:
【1】.Cesium 鼠标事件监听 (这篇文章讲解了如何对鼠标事件进行监听,以及有哪几类鼠标事件)
【2】.鼠标滑动点击选择模型 (这是官方的例子,实现了鼠标滑动和点击模型,这里有一个显示infobox的地方,我刚开始一值没找到这个infobox在哪里创建的,因为在点击事件中根本就没有创建infobox啊,只是将selectedEntity.description值初始化了,后来我才发现,原来我在创建viewer的时候,有一个infoBox属性,我给禁用了,所以就显示不出来信息框)
【3】.cesium 控制infobox中显示的内容
【4】.Cesium中的几种坐标和相互转换 (因为Cesium中有各种各样的坐标,所以需要进行相互的转换)
【5】.cesium给自定义的区域添加高亮 (这用了KML形式,感觉文不对题)
【6】.Cesium开发:模型实体高亮 (这是通过改变模型的颜色实现的)
【7】. younggis /Cesium-Examples Cesium示例,包括3DTiles、雷达扫描、动态扩散点、渐变立体墙、渐变建筑物、视场角大小、日照分析、空间三角形、可视域分析、动画、站心坐标转换、地形开挖、方量计算、FlowLine等
4.条件渲染
在 阿里通义千问 的帮助下,它竟然煞有介事的给我来了一个条件渲染,就是根据坐标范围进行设置不同的颜色,比如下面这个样子,解决了无数个类似的问题之后,测试了不知道多少回,最后告诉我,不支持直接的坐标条件。(不支持,你倒是早说啊,干嘛非要给我这个方案呢?开始我反复的问,单体化单体化,回复我这个方案可行,真正的实行起来,又不行了。)
1 | // 注意:在Cesium中,应该使用 ${positions} 或者直接使用数学表达式 |
根据测试,其实这个条件渲染,就是根据属性渲染,需要在3dtiles中绑定属性信息才可以。
参考文章:
【1】.【CesiumJS 入门】3D Tiles的样式和筛选 这里有些条件筛选的说明
【2】.Cesium3DTileStyle 这是文档说明
【3】.3d-tiles/specification/Styling/ 官方的条件表达式的github仓库
【4】.CESIUM例子学习(十二)——3D Tiles Styling 它是可以根据Cesium3DTileFeature属性来进行个性化渲染的功能,比如分级渲染,距离渲染、条件显示。这些功能的实现都很简单,根据项目需要,创建一个相应的Cesium3DTileStyle属性,并赋值给Cesium3DTileset即可完成。但前提条件是,你的3D Tiles的属性字段中得有需要字段与值。
【5】.基于Cesium实现倾斜摄影动态单体化 这是一个视频,视频说的更加的详细,但是我觉得相对于视频来说,我更加的习惯看文档。
