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模型点击以及列表点击定位弹窗的更多相关文章
- cesium加载gltf模型
cesium加载gltf模型 一.采用vue-cesium:在项目里加载依赖包.命令如下: npm i --save vue-cesium 在main.js中加入如下代码: https://www.n ...
- Cesium 加载 gltf 模型
var viewer = new Cesium.Viewer('cesiumContainer', { /*帮助*/ navigationHelpButton: true, baseLayerPick ...
- Three.js加载gltf模型
效果图 demo import './index.css'; var stats; stats = new Stats(); document.body.appendChild( stats.dom ...
- cesium 加载倾斜摄影模型(这里有一坑)
代码如下: // Construct the default list of terrain sources. var terrainModels = Cesium.createDefaultTerr ...
- WebGL简易教程(十五):加载gltf模型
目录 1. 概述 2. 实例 2.1. 数据 2.2. 程序 2.2.1. 文件读取 2.2.2. glTF格式解析 2.2.3. 初始化顶点缓冲区 2.2.4. 其他 3. 结果 4. 参考 5. ...
- Cesium加载影像和地形数据+开启高程遮挡效果+视点定位+定时更新
// 初始化Cesium var viewer = new Cesium.Viewer('cesiumContainer', { /*imageryProvider : new Cesium.ArcG ...
- cesium 学习(五) 加载场景模型
cesium 学习(五) 加载场景模型 一.前言 现在开始实际的看看效果,目前我所接触到基本上都是使用Cesium加载模型这个内容,以及在模型上进行操作.So,现在进行一些加载模型的学习,数据的话可以 ...
- ceisum_加载倾斜摄影模型
osgb转换为3Dtiles格式(使用工具转换) 然后加载到cesium中(加载代码见下,可以控制模型高度) var offset = function(height,tileset) { conso ...
- Cesium加载三维倾斜摄影数据
具体技术来源自论文 基于Cesium的倾斜摄影三维模型Web加载与应用研究. 技术架构图 应用实例 利用一个实际实例来详细说明如何利用Cesium加载倾斜摄影数据,并进行可视化和交互操作. 首先,利用 ...
随机推荐
- 请注意JS方法,方法同名,参数个数不一样是不能区分方法的,
请注意JS方法,方法同名,参数个数不一样是不能区分方法的, 所以要区分方法,只能利用方法名不同来区分,而不能利用参数个数与参数类型来分.
- Chrome的强大搜索功能
前言 前几天一个好朋友求助我,大概问题是他的电脑QQ啥都能上网,就浏览器上不了网不是IE而是chrome,我第一反应可能是dns问题.后来发甩过来一张图,好家伙把我吓得,类似于下面这张图 这图是我自己 ...
- vscode 快速入门
vscode 快速入门 本篇主要讲解 vscode 使用中的一些经验: 配置 vue 开发环境 - Vetur+ESLint+Prettier 代码片段的使用 常用插件 如何完全卸载 vscode 通 ...
- ubantu电脑无法开机修复
重启Ubuntu,随即长按F9进入grub菜单:在grub菜单中,选择recovery mode,回车确认:在Recovery Menu中,选择"Root Drop to root shel ...
- Excel转Json升级版-Python
Excel转Json升级版 将excel文件夹中所有xslx文件全部转换json文件,存放在data文件夹中: excel中的格式,从序号为2的行开始,2行为key:1行可以自由写注释: 使用时用双击 ...
- 一个自定义的c++错误类 和 同步异步、阻塞非阻塞(区别简述)
一个例子,自定义exception 继承std::exception 1 class _oct_udp_api_export_ udp_err : public std::exception 2 { ...
- cmake之指定clang(++)编译器为默认编译器
1.说明 本文演示环境的cmake版本3.18 clang是自己源码安装的,非获取已经编译好的binary 2.代码 2.1 添加下面的代码到CMakeLists.txt中,且放到 project语句 ...
- 【LeetCode】747. Largest Number At Least Twice of Others 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 寻找两次最大值 排序 大顶堆 日期 题目地址:htt ...
- 【LeetCode】388. Longest Absolute File Path 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述: 题目大意 解题方法 日期 题目地址:https://leetcode. ...
- 自我学习与理解:keras框架下的深度学习(三)回归问题
本文主要是使用keras对其有的波士顿房价数据集做一个回归预测,其代码架构与之前一样(都只是使用多层感知机):数据的预处理.搭建网络框架.编译.循环训练以及测试训练的网络模型.其中除了数据预处理与之前 ...