概要
既Cesium 1.49中3dtile加载性能大幅提升以后,Cesium 1.50再次迎来几个重量级新功能:
1 地球裁切,这下相当于可以截取一部分地形影像数据,当作一个平面场景来用了!
2 射线求交,为客户提供了进行通视分析和碰撞检测的可能!
3 贴地高度获取,为标签等位置的放置提供了依据。
4 地面大气效果,地球效果更加好看,算是弥补了长久以来的短板吧。。
Cesium 1.50又新增加了如下几个示例,以下分析也是根据这几个示例来的。
地面大气效果(Ground Atmosphere)
Cesium 1.50版新增了这个属性:globe.showGroundAtmosphere,默认为true,也就是默认开启了地面大气效果。地面大气效果如下:
而1.50版以前的效果大概是这个样子:
关键代码:
globe.showGroundAtmosphere = checked;
globe.lightingFadeOutDistance = defaultLightFadeOut;
globe.lightingFadeInDistance = defaultLightFadeIn;
globe.nightFadeOutDistance = defaultNightFadeOut;
globe.nightFadeInDistance = defaultNightFadeIn;
另外,Cesium老早之前就有一个scene.skyAtmosphere,用来控制大气效果了。不过这个只能控制相机在近地面时抬头看天的效果。Cesium中还有一个叫 Atmosphere Color 的示例,就是演示scene.skyAtmosphere的用法。
地球裁切(Cartographic Limit Rectangle)
这个示例可以用来裁切地球,效果如下图所示:
这是一个激动人心的效果!老早之前就有客户一直抱怨不想要地球,只想看平面,但是平面又涉及到拉伸变形的问题。这回有了它,就可以在地球上任意截取一块地形和影像。裁切的区域越小,就会越近似平面。
关键代码如下:
var coffeeBeltRectangle = Cesium.Rectangle.fromDegrees(-180.0, -23.43687, 180.0, 23.43687);
viewer.scene.globe.cartographicLimitRectangle = coffeeBeltRectangle;
我尝试着截取了一块中国区域,效果还不错。
模型上的高度获取(Clamp to 3D Model)
给定地理坐标,获取当前地理位置的物体高度。老早之前Cesium就提供了地形高程获取的相关函数,如ApproximateTerrainHeights、sampleTerrain、sampleTerrainMostDetailed,只是一直比较原始。这一次在Scene的层面提供,算是封装得比较好了。
var objectsToExclude = [point];
var cartographic = new Cesium.Cartographic();
var height = scene.sampleHeight(cartographic, objectsToExclude);
3dtiles数据上的高度获取(Clamp to 3D Tiles)
var position = positionProperty.getValue(clock.currentTime);
entity.position = scene.clampToHeight(position, objectsToExclude);
Cesium最新提供的两个方法sampleHeight和clampToHeight,按照官方文档的说法,都可以作用于globe, 3D Tiles, or primitives,都是用来给定地理坐标,然后获取对应的高度值。我这里只看到了参数类型略有不同,返回值一个是直接给高度,另外一个是返回一个position。貌似大同小异。。以下附带两个函数的说明如下:
射线求交(development/Pick From Ray)
Cesium提供了另外一个激动人心的功能,终于可以求交运算了。以前看超图的示例,有通视分析的功能,还想研究一下。没想到Cesium自己也提供了。
这项功能,不仅可以用来做通视分析,或许也可以用来做广大客户日思夜想的碰撞检测了!
关键代码如下:
var start = Cesium.Cartographic.toCartesian(blueCartographic);
var end = Cesium.Cartographic.toCartesian(redCartographic);
var direction = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(end, start, new Cesium.Cartesian3()), new Cesium.Cartesian3());
var ray = new Cesium.Ray(start, direction);
var results = [];
if (drillPick) {
results = scene.drillPickFromRay(ray, 10, objectsToExclude);
} else {
var result = scene.pickFromRay(ray, objectsToExclude);
if (Cesium.defined(result)) {
results = [result];
}
}
后记
Cesium 1.50版也带来一些额外的问题,加载老版本的3dtiles或者gltf数据时,可能会报错:
这个问题我在另外一篇文章中给予说明和解决方案。
欢迎关注 Cesium实验室 ,QQ群号:595512567。