Cesium中文網:http://cesiumcn.org/ | 國內快速訪問:http://cesium.coinidea.com/
Viewer中的Entity功能
讓我們看看Viewer為操作entities提供出來的功能函數。
選中和描述
點擊Viewer中的entity將在entity的位置上呈現SelectionIndicator控件,提供一個InfoBox用於呈現更多的信息。我們可以設置name,來定義InfoBox的標題。我們也以HTML樣式來提供Entity.description的屬性。
wyoming.name = 'wyoming';
wyoming.description = '\
<img\
width="50%"\
style="float:left; margin: 0 1em 1em 0;"\
src="//cesium.com/docs/tutorials/creating-entities/Flag_of_Wyoming.svg"/>\
<p>\
Wyoming is a state in the mountain region of the Western \
United States.\
</p>\
<p>\
Wyoming is the 10th most extensive, but the least populous \
and the second least densely populated of the 50 United \
States. The western two thirds of the state is covered mostly \
with the mountain ranges and rangelands in the foothills of \
the eastern Rocky Mountains, while the eastern third of the \
state is high elevation prairie known as the High Plains. \
Cheyenne is the capital and the most populous city in Wyoming, \
with a population estimate of 63,624 in 2017.\
</p>\
<p>\
Source: \
<a style="color: WHITE"\
target="_blank"\
href="http://en.wikipedia.org/wiki/Wyoming">Wikpedia</a>\
</p>';
InfoBox中展示的所有HTML是沙盒式的。這組織了外部數據源帶有惡意的注入到Cesium的應用程序中。為了在描述中運行JavaScript或瀏覽器插件,訪問沙盒中的iframe通過viewer.infoBox.frame屬性。參考該文可以獲得更多的信息用於控制iframe中的沙盒。
Camera控制
使用iewer.zoomto命令查看特定Entity。還有一個viewer.flyto方法,用於對Entity執行動畫Camera飛行。這兩種方法都可以傳遞給Entity、EntityCollection、DataSource或實體數組。
任何一種方法都會計算所有提供的實體的視圖。默認情況下,Camera朝向北方,並從45度角向下看。通過傳入HeadingPitchrange自定義此項。
var heading = Cesium.Math.toRadians(90);
var pitch = Cesium.Math.toRadians(-30);
viewer.zoomTo(wyoming, new Cesium.HeadingPitchRange(heading, pitch));
zoomTo和flyTo都是異步函數;也就是說,它們不能保證在返回之前完成。例如,飛行到Entity會在許多動畫幀后發生。這兩個功能都返回Promises,可用於計划飛行或縮放完成后要執行的功能。用下面的代碼片段替換示例中的zoomTo。這架飛機飛往懷俄明州,並在飛行結束后選中它。
viewer.flyTo(wyoming).then(function(result){
if (result) {
viewer.selectedEntity = wyoming;
}
});
如果航班飛行成功完成,則傳遞給回調函數的結果參數將為true;如果航班被取消,則結果參數將為false,即,在此航班完成之前,用戶啟動了另一個航班或縮放;或者,由於目標沒有相應的可視化效果,即沒有可縮放的對象。
有時,特別是在處理時間動態數據時,我們希望Camera聚焦跟隨一個entity而不是地球的中心。可以通過設置viewer.trackedEntity完成。跟蹤實體需要設置position。
wyoming.position = Cesium.Cartesian3.fromDegrees(-107.724, 42.68);
viewer.trackedEntity = wyoming;
停止跟蹤需要設置viewer.trackedEntity為undefined或遠離entity雙擊屏幕即可。調用zoomTo或flyTo也可以取消跟蹤。
管理Entities
EntityCollection是用於管理和監視一組實體的關聯數組。viewer.entities是EntityCollection。EntityCollection包括用於管理實體的方法,如add、remove和removeAll。
有時我們需要更新我們以前創建的實體。所有實體實例都有一個唯一的id,可用於從集合中檢索實體。我們可以為實體指定一個ID,否則將自動生成一個ID。
viewer.entities.add({
id : 'uniqueId'
});
使用getByiId檢索實體。如果不存在具有提供的ID的實體,則返回undefined。
var entity = viewer.entities.getById('uniqueId');
要獲取實體或創建新實體(如果不存在),請使用getOrCreateEntity。
var entity = viewer.entities.getOrCreateEntity('uniqueId');
手動創建新實體,然后使用add將其添加到集合中。如果集合中已存在具有相id的實體,則此方法將拋出異常。
var entity = new Entity({
id : 'uniqueId'
});
viewer.entities.add(entity);
EntityCollection的功能使用CollectionChanged事件發光。當在集合中添加、刪除或更新實體時,會通知監聽器。
使用Sandcastle中的[Geometry Showcase]
(https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/index.html?src=Geometry and Appearances.html&label=Showcases) 示例。在創建viewer的行后粘貼以下代碼。
function onChanged(collection, added, removed, changed){
var msg = 'Added ids';
for(var i = 0; i < added.length; i++) {
msg += '\n' + added[i].id;
}
console.log(msg);
}
viewer.entities.collectionChanged.addEventListener(onChanged);
運行該示例時,您應該在控制台中看到大約65條消息,每次調用viewer.entities.add時都會看到一條消息。
當一次更新大量的實體時,將隊列更新結束后並在最后發送一個整體事件,這樣更具性能。這樣Cesium可以在一次通過中處理所需的變化。在示例末尾,在viewer.entities.add之前調用viewer.entities.suspendEvents,並調用viewer.entities.resumeEvents。當再次運行演示時,我們現在得到包含所有65個實體的單一事件。這些調用是引用計數的,因此可以嵌套多個掛起和恢復調用。
Picking 拾取
選擇(單擊選擇一個對象)是我們需要與基本API進行短暫交互的領域之一。使用scene.pick和scene.drillpick檢索實體。
/**
* Returns the top-most entity at the provided window coordinates
* or undefined if no entity is at that location.
*
* @param {Cartesian2} windowPosition The window coordinates.
* @returns {Entity} The picked entity or undefined.
*/
function pickEntity(viewer, windowPosition) {
var picked = viewer.scene.pick(windowPosition);
if (defined(picked)) {
var id = Cesium.defaultValue(picked.id, picked.primitive.id);
if (id instanceof Cesium.Entity) {
return id;
}
}
return undefined;
};
/**
* Returns the list of entities at the provided window coordinates.
* The entities are sorted front to back by their visual order.
*
* @param {Cartesian2} windowPosition The window coordinates.
* @returns {Entity[]} The picked entities or undefined.
*/
function drillPickEntities(viewer, windowPosition) {
var i;
var entity;
var picked;
var pickedPrimitives = viewer.scene.drillPick(windowPosition);
var length = pickedPrimitives.length;
var result = [];
var hash = {};
for (i = 0; i < length; i++) {
picked = pickedPrimitives[i];
entity = Cesium.defaultValue(picked.id, picked.primitive.id);
if (entity instanceof Cesium.Entity &&
!Cesium.defined(hash[entity.id])) {
result.push(entity);
hash[entity.id] = true;
}
}
return result;
};
Points, billboards, and labels(點、廣告牌和標簽)
通過設置position、point和label來創建圖形點或標簽。例如,在我們最喜歡的運動隊的主體育場放置一個點。
var viewer = new Cesium.Viewer('cesiumContainer');
var citizensBankPark = viewer.entities.add({
name : 'Citizens Bank Park',
position : Cesium.Cartesian3.fromDegrees(-75.166493, 39.9060534),
point : {
pixelSize : 5,
color : Cesium.Color.RED,
outlineColor : Cesium.Color.WHITE,
outlineWidth : 2
},
label : {
text : 'Citizens Bank Park',
font : '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth : 2,
verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
pixelOffset : new Cesium.Cartesian2(0, -9)
}
});
viewer.zoomTo(viewer.entities);
默認情況下,標簽水平和垂直居中。由於標簽和點共享相同的位置,它們在屏幕上重疊。為避免這種情況,請指定標簽源Verticalorigin.BOTTOM並將像素偏移量設置為(0,-9)。
將該點替換為一個billboard,它是一個始終面向用戶的標記。
var citizensBankPark = viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(-75.166493, 39.9060534),
billboard : {
image : '//cesiumjs.org/tutorials/Visualizing-Spatial-Data/images/Philadelphia_Phillies.png',
width : 64,
height : 64
},
label : {
text : 'Citizens Bank Park',
font : '14pt monospace',
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth : 2,
verticalOrigin : Cesium.VerticalOrigin.TOP,
pixelOffset : new Cesium.Cartesian2(0, 32)
}
});
有關更多自定義選項,請參見Sandcastle標簽和廣告牌示例。
3D models (三維模型)
CesiumJS支持通過glTF(運行時asset format)創建3D模型。您可以在3D modelsSandcastle中找到示例模型。
將位置和URI設置為glTF 模型以創建模型實體。
var viewer = new Cesium.Viewer('cesiumContainer');
var entity = viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706),
model : {
uri : '../../../../Apps/SampleData/models/GroundVehicle/GroundVehicle.glb'
}
});
viewer.trackedEntity = entity;
默認情況下,模型是垂直的,面向東。通過為Entity.Orientation屬性指定Quaternion來控制模型的方向。這將控制模型的heading、pitch和roll。
var viewer = new Cesium.Viewer('cesiumContainer');
var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706);
var heading = Cesium.Math.toRadians(45.0);
var pitch = Cesium.Math.toRadians(15.0);
var roll = Cesium.Math.toRadians(0.0);
var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, new Cesium.HeadingPitchRoll(heading, pitch, roll));
var entity = viewer.entities.add({
position : position,
orientation : orientation,
model : {
uri : '../../../../Apps/SampleData/models/GroundVehicle/GroundVehicle.glb'
}
});
viewer.trackedEntity = entity;
有關更高級的模型功能,請參見3D模型教程。如果你創建自己的模型,一定要看到我們關於glTF Tips for Artists提示的帖子。
The property system(屬性系統)
我們為實體定義的所有值都存儲為property對象。例如,請參見懷俄明州大綱的值:
console.log(typeof wyoming.polygon.outline);
outline是ConstantProperty的一個實例。本教程使用一種稱為隱式屬性轉換(implicit property conversion)的速記形式,它自動獲取原始值並在引擎蓋下創建相應的Property。如果沒有這個速記,我們將不得不編寫一個更長版本的初始示例:
var wyoming = new Cesium.Entity();
wyoming.name = 'Wyoming';
var polygon = new Cesium.PolygonGraphics();
polygon.material = new Cesium.ColorMaterialProperty(Cesium.Color.RED.withAlpha(0.5));
polygon.outline = new Cesium.ConstantProperty(true);
polygon.outlineColor = new Cesium.ConstantProperty(Cesium.Color.BLACK);
wyoming.polygon = polygon;
viewer.entities.add(wyoming);
之所以使用屬性,是因為實體API不僅能夠表示常量值,而且能夠表示隨時間變化的值。請參閱Callback Property和Interpolation Sandcastle示例,了解一些時間動態屬性。
資源
有關如何使用GeoJSON和CZML設置樣式和創建實體的示例,請參閱Cesium Workshop Tutorial。
Cesium中文網交流QQ群:807482793
Cesium中文網:http://cesiumcn.org/ | 國內快速訪問:http://cesium.coinidea.com/