cesium加載gltf模型點擊以及列表點擊定位彈窗

前言

cesium 官網的api文檔介紹地址cesium官網api,裏面詳細的介紹 cesium 各個類的介紹,還有就是在線例子:cesium 官網在線例子,這個也是學習 cesium 的好素材。css

以前有部分訂閱者諮詢我,cesium加載gltf模型點擊彈窗以及模型列表點擊定位彈窗那些交互是怎麼實現的,雖然說比較簡單,可是總有新手是有這塊需求的。因此,今天我抽空整理一下本篇素材,簡單寫一下。html

實現效果圖以下:
node

大概思路以下:git

  • gltf模型的模擬數據源配置,配置gltf模型路徑以及氣泡窗口顯示內容json數據源
/*三維模型gltf配置信息*/
MapConfig.mapPosition = Cesium.Cartesian3.fromDegrees(102.468086, 37.933179,3500);
MapConfig.position = Cesium.Cartesian3.fromDegrees(102.468086, 37.933179);
MapConfig.Obj3D = {
position:MapConfig.mapPosition,
models:[
{
id:"1_db",
name : "測試3D模型1_db",
type:"gltf",
position : MapConfig.position,
uri :"http://localhost:8180/cesium/3DModel/test/gltf/1_db.gltf"
},
{
id:"1_deng",
name : "測試3D模型1_deng",
type:"gltf",
position : MapConfig.position,
uri :"http://localhost:8180/cesium/3DModel/test/gltf/1_deng.gltf"
},
{
id:"1_men",
name : "測試3D模型1_men",
type:"gltf",
position : MapConfig.position,
uri :"http://localhost:8180/cesium/3DModel/test/gltf/1_men.gltf"
},
{
id:"1_my",
name : "測試3D模型1_my",
type:"gltf",
position : MapConfig.position,
uri :"http://localhost:8180/cesium/3DModel/test/gltf/1_my.gltf"
},
{
id:"1_pao",
name : "測試3D模型1_pao",
type:"gltf",
position : MapConfig.position,
uri :"http://localhost:8180/cesium/3DModel/test/gltf/1_pao.gltf"
},
{
id:"1_w",
name : "測試3D模型1_w",
type:"gltf",
position : MapConfig.position,
uri :"http://localhost:8180/cesium/3DModel/test/gltf/1_w.gltf"
},
{
id:"1_wd",
name : "測試3D模型1_wd",
type:"gltf",
position : MapConfig.position,
uri :"http://localhost:8180/cesium/3DModel/test/gltf/1_wd.gltf"
},
{
id:"1_wl",
name : "測試3D模型1_wl",
type:"gltf",
position : MapConfig.position,
uri :"http://localhost:8180/cesium/3DModel/test/gltf/1_wl.gltf"
},
{
id:"1_wq",
name : "測試3D模型1_wq",
type:"gltf",
position : MapConfig.position,
uri :"http://localhost:8180/cesium/3DModel/test/gltf/1_wq.gltf"
}
 
]
};
/*配置三維模型gltf氣泡窗口內容模擬數據源*/
MapConfig.Obj3Djson = [
{
id:"1_db",
name : "測試3D模型1_db",
address:"測試3D模型地址"
},
{
id:"1_deng",
name : "測試3D模型1_deng",
address:"測試3D模型地址"
},
{
id:"1_men",
name : "測試3D模型1_men",
address:"測試3D模型地址"
},
{
id:"1_my",
name : "測試3D模型1_my",
address:"測試3D模型地址"
},
{
id:"1_pao",
name : "測試3D模型1_pao",
address:"測試3D模型地址"
},
{
id:"1_w",
name : "測試3D模型1_w",
address:"測試3D模型地址"
},
{
id:"1_wd",
name : "測試3D模型1_wd",
address:"測試3D模型地址"
},
{
id:"1_wl",
name : "測試3D模型1_wl",
address:"測試3D模型地址"
},
{
id:"1_wq",
name : "測試3D模型1_wq",
address:"測試3D模型地址"
}
];
  • cesium加載gltf三維模型
cesium.add3DGlft(MapConfig.Obj3D);
/**
* 加載GLFT模型
* @method add3DGlft
* @param
* @return
*/
add3DGlft: function (obj) {
//加載3dModel
this.add3DEntityModels(obj.models);
},
/**
* 批量加載3D模型
* @method add3DEntityModels
* @param models 3D模型數組
* @return
*/
add3DEntityModels: function (models) {
//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, heading, pitch, roll);
if(models && models.length>0){
for(var i=0;i<models.length;i++){
var type = null;
if(models[i].type){
type = models[i].type;
}
var entity = this.cesiumViewer.entities.add({
name : models[i].name,
//id:models[i].id+Math.random().toString(36).substr(2),
id:models[i].id,
type : type,
position : models[i].position,
//orientation : orientation,
model : {
uri : models[i].uri,
//distanceDisplayCondition : new Cesium.DistanceDisplayCondition(100, 5000),//設置模型可見範圍,100米到5000米
//maximumScale:12,
//incrementallyLoadTextures:false,//肯定在加載模型後,是否繼續加載紋理
}
});
//this.cesiumViewer.trackedEntity = entity;//建議不跟蹤定位3D模型,否則鎖定視角操做不靈活
}
}
},
  • html界面的gltf列表面板設計以及動態加載
<!--三維模型gltf列表-->
<div id="showListsDIV" style="display:none;position: absolute;right:80px;top:40px;background: #0101018a;width: 300px;height: 650px;z-index:99;">
<div id="showLists" style="height:99%;"></div>
</div>
/**
*加載gltf信息列表
*/
function loadGltfList(){
var data = MapConfig.Obj3Djson;
if(data && data.length>0){
var innerStr = [];
for(var i=0;i<data.length;i++){
//innerStr.push('<div class="left_list_li_box" id = "' + data[i].id + '" onclick="this.toLocationGltf(\'' + data[i].id + '\')">');
innerStr.push('<div class="left_list_li_box" id = "' + data[i].id + '">');
innerStr.push('<div class="left_list_li_box_top">');
innerStr.push('<div class="left2_box2">');
innerStr.push('<img class="list_poi_marker" src="./gis/cesium/images/poiLocation.png"></img>');
innerStr.push('<div class="left_list_li1">');
innerStr.push('<p>');
innerStr.push('<a>id:' + data[i].id + '</a><br/>');
innerStr.push('<a>名稱:' + data[i].name + '</a><br/>');
innerStr.push('<a>地址:' + data[i].address + '</a><br/>');
innerStr.push('</p>');
innerStr.push('</div>');
innerStr.push('</div>')
innerStr.push('</div>');
innerStr.push('</div>');
}
$("#showLists").html(innerStr.join(''));
$(".left_list_li_box").click(function(e){
//console.log("left_list_li_box",e.currentTarget.id);
var id = e.currentTarget.id;
toLocationGltf(id);
});
//滾動條樣式
$("#showLists").mCustomScrollbar({
theme: "minimal-dark",
});
}
}
loadGltfList();
  • gtlf模型別來點擊彈窗函數,根據模型的id去匹配對應的模型entity,而後利用entity來進行彈窗顯示相關內容展現
/**
* 根據id匹配對應的模型
* @param id gltf模型id
*/
function toLocationGltf(id){
var entity = cesium.cesiumViewer.entities.getById(id);
if (entity instanceof Cesium.Entity){
for(var i = 0;i<MapConfig.Obj3Djson.length;i++){
var data = MapConfig.Obj3Djson[i];
if(id == data.id){
var content =
"<div>"+
"<span>名稱:</span><span>"+data.name+"</span></br>"+
"<span>地址:</span><span>"+data.address+"</span></br>"+
"</div>";
var cartographic = Cesium.Cartographic.fromCartesian(entity._position._value);//世界座標轉地理座標(弧度)
//var point=[ cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180];//地理座標(弧度)轉經緯度座標
var point=[ Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)];//地理座標(弧度)轉經緯度座標
var popupCartesian=Cesium.Cartesian3.fromDegrees(point[0], point[1], 0);
var position = Cesium.SceneTransforms.wgs84ToWindowCoordinates(cesium.cesiumViewer.scene, popupCartesian);
var obj = {position:position,content:content};
cesium.infoWindow(obj);
break;
}
}
}
}
  • 氣泡窗口函數
/**
* 彈出氣泡窗口
* @method infoWindow
* @param obj{position(必填):屏幕座標,destination(必填):跳轉目的點,content(必填):氣泡窗口內容,css(可填):設置css的width,height}
* @return 返回選中的模型Entity
*/
infoWindow: function (obj) {
var picked = this.cesiumViewer.scene.pick(obj.position);
if (Cesium.defined(picked)) {
var viewer = this.cesiumViewer;
var id = Cesium.defaultValue(picked.id, picked.primitive.id);
if (id instanceof Cesium.Entity) {
// if(obj.destination){
// this.cesiumViewer.camera.flyTo({//初始化跳轉某個地方
// destination : obj.destination
// });
// }
//填充內容
$(".cesium-selection-wrapper").show();
$('#trackPopUpLink').empty();
$('#trackPopUpLink').append(obj.content);
function positionPopUp (c) {
var x = c.x - ($('#trackPopUpContent').width()) / 2;
var y = c.y - ($('#trackPopUpContent').height());
$('#trackPopUpContent').css('transform', 'translate3d(' + x + 'px, ' + y + 'px, 0)');
}
var c = new Cesium.Cartesian2(obj.position.x, obj.position.y);
$('#trackPopUp').show();
positionPopUp(c); // Initial position at the place item picked
var removeHandler = viewer.scene.postRender.addEventListener(function () {
var changedC = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, id._position._value);
// If things moved, move the popUp too
if(c && changedC && c.x && changedC.x && c.y && changedC.y){
if ((c.x !== changedC.x) || (c.y !== changedC.y)) {
positionPopUp(changedC);
c = changedC;
}
}
 
});
// PopUp close button event handler
$('.leaflet-popup-close-button').click(function() {
$('#trackPopUp').hide();
$('#trackPopUpLink').empty();
$(".cesium-selection-wrapper").hide();
removeHandler.call();
return false;
});
return id;
}
}
},
  • 點擊三維模型gltf,彈窗顯示
//調用接口-氣泡窗口
var handler3D = new Cesium.ScreenSpaceEventHandler(cesium.cesiumViewer.scene.canvas);
handler3D.setInputAction(function(movement) {
//點擊彈出氣泡窗口
var pick = cesium.cesiumViewer.scene.pick(movement.position);
if(pick && pick.id && pick.id._position){//選中某模型
var cartographic = Cesium.Cartographic.fromCartesian(pick.id._position._value);//世界座標轉地理座標(弧度)
var point=[ Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)];//地理座標(弧度)轉經緯度座標
var destination=Cesium.Cartesian3.fromDegrees(point[0], point[1], 3000.0);
//判斷是否彈出氣泡窗口內容
switch (pick.id._type)
{
case "gltf":
for(var i = 0;i<MapConfig.Obj3Djson.length;i++){
var data = MapConfig.Obj3Djson[i];
if(pick.id._id == data.id){
var content =
"<div>"+
"<span>名稱:</span><span>"+data.name+"</span></br>"+
"<span>地址:</span><span>"+data.address+"</span></br>"+
"</div>";
var obj = {position:movement.position,destination:destination,content:content};
cesium.infoWindow(obj);
break;
}
}
break;
}
}
else{
$('#trackPopUp').hide();
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

更多精彩文章,見下面的cesium小專欄json

GIS之家/Cesium專題 - 小專欄​xiaozhuanlan.comcanvas

相關文章
相關標籤/搜索