cesium加载gltf模型点击以及列表点击定位弹窗
Posted giserhome
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cesium加载gltf模型点击以及列表点击定位弹窗相关的知识,希望对你有一定的参考价值。
前言
cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材。
之前有部分订阅者咨询我,cesium加载gltf模型点击弹窗以及模型列表点击定位弹窗那些交互是怎么实现的,虽说比较简单,但是总有新手是有这块需求的。所以,今天我抽空整理一下本篇素材,简单写一下。
实现效果图如下:
大概思路如下:
- 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小专栏:
以上是关于cesium加载gltf模型点击以及列表点击定位弹窗的主要内容,如果未能解决你的问题,请参考以下文章