关于单体化
单体化效果做出来也有段时间了,可能还是有些问题没有讲清楚,我们这里再说下
单体化矢量的制作
单体化的原理就是一个通过矢量文件构造一个个封闭的几何体去附着到被分类的对象(倾斜或者地形),所以第一步我们需要制作这样的矢量。在GIS行业里,最常见的矢量数据就是shp格式,而arggis的arcmap就是编辑shp的官方工具,所以我们下来展示如何用arcmap制作一个 大雁塔的分层示例。
第一步,先要用arcgis另一个工具arccatalog 新建一个 shp数据图层


注意这里选polygon类型,也就是多边形图层。
设置为wgs84坐标系统
然后右键属性


我们这里增加四个字段:
name,类型为text,这个用来记录我们的 大雁塔级别的名称
minheight,类型为float,用来记录 这一层底面的绝对高程
maxheight,类型为float,用来记录 这一层顶面的绝对高程
height,类型为float,用来记录 这一层顶面相对底面的相对高度
也就是 height = maxheight - minheight
这里其实 maxheight 和 height 二选一就可以了,只是在cesiumlab处理的时候有一个选项可以来设定顶面高度是否是绝对高程。
第二步,在arcmap里绘制矢量面
在arcmap 里把这个shp 和 底图影像数据加进来

注意我这里的底图数据是用的我们自定义的一个arcmap插件,它可以加载各种在线的底图数据,这里我加载的谷歌无偏移影像。当然对于专业做gis的公司,这都不是问题,要么有自己的底图影像数据,要么是有类似的插件。(PS:我们的插件可以有偿转让)。
我们拖拽定位到大雁塔附件

调出editor工具,点开始编辑


使用右侧的createfeature 工具,选择 polygon工具
在图上鼠标单击勾多边形
这里注意两个问题:1,单体化矢量面尽量大一些,只要不和旁边的单体化矢量面相交就行,因为我们的倾斜数据,底图数据本身都有误差,如果太过紧凑,反倒不能完全包含倾斜数据,导致效果不好。2,单体化矢量面尽量简单一些,也就是多边形的顶点更少一些,越多的多边形顶点,我们生成的封闭体越复杂,渲染效率越低。
我们来填写下它的属性


minheight为什么填写了425 ? 这个高度值是我在lab里预览大雁塔倾斜的时候看到的

lab里点击高度是425.68,我们填写的425,因为这是最下面一层,我们可以向下增加一些余量。
maxheight为什么填439? 同样道理,这里也是手工在lab里点击第一层最顶端看到的

height的值就很好理解了,就是两者的插值 = 439 - 425 = 14
第一层我们就设置完毕了。
第二层我们直接在arcmap里选中第一层,然后ctrl+c,ctrl+v复制一个面就行了

第二层属性里的几个值
minheight当然等于第一层的maxheight
maxheight也是在lab里预览里看到的
height = maxheight - minheight
其他层的就不做了,这两个能说明问题就可以了。
注意编辑完成之后,editor工具栏里选择 stop editing
单体化矢量的处理
我们先做一个非单体化的处理效果

注意我们先在使用的 maxheight 和 minheight,因为maxheight是绝对高度,所以我们需要在其他选项里,勾选绝对高度

我们再试下,用height字段处理,这时候,不能选择 绝对高度 选项

你么可以验证下,这两种处理结果是一样的。
下来我们做一个单体化效果处理

单体化处理的时候,一定要勾选 分类单体 选项,如果不能勾选,是因为免费登陆版不支持,请向我们申请测试授权。

为什么是黑色的,目前lab为了精简单体化矢量的数据量,并没有填充法向量,所以cesium默认效果就这样的。
单体化效果的预览
要测试单体化效果,需要把倾斜数据 和 单体化数据增加到一个场景里(具体代码请翻看以前关于单体化的文章里介绍的)这里只说一个快速的方法。
请确认cesiumlab正在运行,那么打开如下网址
http://localhost:9000/demo/classification.html?url1={倾斜数据服务地址}&url2={单体化矢量服务地址}
比如在刚才我处理的就是这样的

注意服务地址需要加上tileset.json
比如我机器完整的地址是这样的
http://localhost:9000/demo/classification.html?url1=http://localhost:9002/api/folder/98b17b3012174607b07f0068a154889a/tileset.json&url2=http://localhost:9002/api/folder/bfc43dbf3b69446d8fb9147fa2503510/tileset.json

关于属性文件
cesiumlab的场景处理工具,默认情况下对于3dtiles只能附加两个字段的属性,一个是file,一个是name。
file是来自lab的任务处理界面上,每选定一个输入文件,默认的file值就是文件名

name属性来自模型的节点(node)名称,如果对模型格式不太了解的,那么的却是不知道这个node名在哪里,最简单的方式就是用max打开模型,在左侧会列出节点名称。

如图,我们这个示例场景里有两个node,一个叫Box001,一个叫GeoSphere001
3d max中 应该注意的问题
对于这样一个max场景,我们的处理工具其实是支持很多种格式导出,比如fbx,dae,obj等等。我一直在说推荐大家使用dae,原因在于dae是标准交换格式,它能保存完整的场景结构,不会随便去合并对象。
但是对于dae导出有两个插件,一个是max自带autodesk collada,一个是opencollada

前者的缺点是:导出巨慢无比,而且对于一些较大场景导出会失败
后者的缺点是:无法保留正确的场景结构图,尤其是左侧的node name
但是为了绑定正确的属性,我们必须使用前者导出。
我们先导出一个dae,使用默认参数在cesiumlab中处理一下

可见左侧场景结构是正确的。
右侧的属性面板也是正确的,存储了file和name属性。
至于lab里看到不透明,这个需要解释下,我用的这张图片是png格式,带透明通道的,但是3ds max里它默认不会使用透明通道。所以效果不同。
属性文件的格式
对于其他额外属性,我们可以通过属性文件的方式绑定到lab里,因为这个没有经过太多测试,而且它不仅仅是对文件属性绑定,而且还支持对模型的位置重新调整,担心引起更多麻烦,一直没有过多解释。
属性文件实际是支持两种格式,一种csv,一种shp
对于专业gis用户,shp格式多一些,对于普通用户可能csv更方便一些,下来我们以csv为例来说明
追加属性字段
使用excel编辑一个如下的文件,注意第一行为字段名称,不可以设置为中文

name 字段的两个值,就是我们刚才在max文件里看到的两个节点的名称
其他字段都是我们想附加的属性(不要问我一般有什么附加字段,这个根据你需要啊),这里我做测试,随便加了两个,一个表示朝向(chaoxiang),一个表示面积(mianji)
保存为utf8编码的csv

对于刚才的max模型,我们再来处理一下
输入里选择我们刚才导出的dae
属性文件里选择我们的属性文件

正确解析后,lab界面上会显示额外的一些信息
2个对象,表示这个属性文件只有两条记录
汉字编码,这个一般不用选择
名称字段,这个就是我们需要和 dae(或者max左侧列表)中的 node name去映射的字段
其他三个字段后面说

可见属性已经被追加到 name 对应的模型上去了
有了这些属性,我们就能利用cesium的3d tiles style 对它进行分析,比如我们把面积大于 1000的对象改为红色

通过属性字段调整模型位置
我们再来修改下excel文件,如下图所示

增加了三个字段 longitude,latitude,altitude,很明显这就是经度纬度高度
我们希望通过这三个字段来把 name 对应的模型放置到这个位置
我们再来lab里处理一下

这回我们再预览的时候,默认视角看不到东西,因为两个对象相隔甚远
点击左侧场景树,快速定位,可以看到这个模型已经放到设置的位置了

其他该注意的地方
由于csv的格式里没有所谓字段类型,但是对于经纬度三个字段必须为float类型的,也就是说,如果excel这么写,可能导致lab无法识别该字段为float,也就不能选择为经纬度字段

其次我们是通过 每个对象AABB包围盒的 下中心 来 映射设置的这个经纬度的。另外通过属性文件的这个映射优先级要高于 lab对于输入文件的里的 位置选项。 也就是如果某个 node 能在属性 文件里找到 经纬度位置,就不会使用 输入文件的位置选项 去计算。
后记
再次感谢大家对CesiumLab的喜爱和支持,希望Lab能和你一起成长
