概要

既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。

點擊鏈接加入群聊【Cesium實驗室】:jq.qq.com/?


推薦閱讀:
查看原文 >>
相关文章