Ceisum三维场景demo
技术栈&资源
- 框架:EarthSDK(基于cesium二次开发包)
- 底图:Arcgis公开地图服务
- 楼栋白膜:自有shape数据,使用CesiumLab切片为tileset.json
- glb模型:window资源管理器自带提取
汽车行驶效果
添加车辆模型
let position = [1.998931022772786, 0.6645500890446009, 0]
//添加车辆
var json = {
"czmObject": {
"xbsjType": "Model",
"url": "/assets/glb/delivery.glb",
"minimumPixelSize": 128,
"maximumScale": 20,
"viewDistance": 500,
// "maximumScale": 500,
// "viewDistance": 1000,
"xbsjPosition": position,
},
"ref": "model1",
}
//添加到场景
this._earth.sceneTree.root.children.push(json)
添加车辆行驶路径
let path = [
[1.9996593978198705, 0.6643798949112332, 0],
[1.999667332682519, 0.6643399484248445, 0],
[1.999661980266788, 0.6643084183139442, 0],
[1.9996677912020882, 0.6642558052776021, 0],
[1.9996703854084483, 0.6642032457083487, 0],
........
]
let json_path = {
"ref": 'path1',
"czmObject": {
"xbsjType": "Path",
"positions": path,
"rotations": [
[0, 0, 0]
],
"currentSpeed": 50,//当前播放速度,单位为米
"alwaysAlongThePath": true,//始终沿着路径方向运动
"show": false, // 显示路径
"loop": true, // 是否为环线
"playing": true, // 飞行
// 是否循环播放
// 如果为false,则playing设置为true时,会从当前位置播放到最后一个关键点,并停止播放,此时playing属性会自动变成false。 若此属性为true时,播放到最后一个关键点以后,将自动重第一个关键点继续播放。
"loopPlay": true,
"cameraAttached": false// 相机绑定
}
}
this._earth.sceneTree.root.children.push(json_path)
绑定车辆和路径,让车辆在路径上按照一定速度行驶
let model1 = this._earth.sceneTree.$refs.model1.czmObject;
let path1 = this._earth.sceneTree.$refs.path1.czmObject;
this._uw1 = XE.MVVM.watch(path1, 'currentPosition', position => {
model1.xbsjPosition = [...position];
});
其他
实例代码仅供参考,还需考虑以下问题,
- 车辆的车头方向和即将进行路线一致
- camera视角绑定
- 车辆头部指向性箭头的绑定
楼栋分层效果
准备数据
- 自有楼栋面数据,且必须有楼高或层数信息
- 使用arcmap或qgis等数据处理工具,给shp添加一个字段,字段内容为面的顶点信息
coordinates
,要根据面的顶点去构造每层的面 - 使用cesiumLab的矢量楼块切片功能进行shp切片
- 切片完成后,在cesiumLab的服务界面中,可以看到刚刚进行切片的url访问路径,或者处理结果放到自己的web服务器下进行访问
- 思路
- 双击建筑物后隐藏当前建筑物
- 读取建筑物的顶点和层数属性,构造层数个面,每层间隔为楼高
- 生成楼层标注,1F , 2F , 3F…
- 双击其他建筑物,还原上一个建筑物的 1 , 2, 3 步骤,再重新执行当前建筑物的 1 , 2, 3 步骤
加载建筑白膜
//动态效果
var fsBody = `
// 可以修改的参数
// 注意shader中写浮点数是,一定要带小数点,否则会报错,比如0需要写成0.0,1要写成1.0
float _baseHeight = 0.0; // 物体的基础高度,需要修改成一个合适的建筑基础高度
float _heightRange = 20.0; // 高亮的范围(_baseHeight ~ _baseHeight + _heightRange) 默认是 0-60米
float _glowRange = 120.0; // 光环的移动范围(高度)
// 建筑基础色
float vtxf_height = v_elevationPos.z - _baseHeight;
float vtxf_a11 = fract(czm_frameNumber / 120.0) * 3.14159265 * 2.0;
float vtxf_a12 = vtxf_height / _heightRange + sin(vtxf_a11) * 0.1;
gl_FragColor *= vec4(vtxf_a12, vtxf_a12, vtxf_a12, 1.0);
// 动态光环
float vtxf_a13 = fract(czm_frameNumber / 360.0);
float vtxf_h = clamp(vtxf_height / _glowRange, 0.0, 1.0);
vtxf_a13 = abs(vtxf_a13 - 0.5) * 2.0;
float vtxf_diff = step(0.005, abs(vtxf_h - vtxf_a13));
gl_FragColor.rgb += gl_FragColor.rgb * (1.0 - vtxf_diff);
`;
this._earth.sceneTree.root.children.push({
"ref": "tileset_sjz_building",
"czmObject": {
"xbsjType": "Tileset",
"name": "楼栋白膜",
"url": "http://localhost/building3d-tiles/tileset.json",
"xbsjStyle": "var style = {\n color: \"vec4(0, 0.5, 1.0,1)\"\n}",//颜色
"xbsjClippingPlanes": {},
"xbsjCustomShader": {//光环上下的动态效果
"fsBody": fsBody,
}
}
})
楼栋分层
//双击事件,建筑物创建切片
var _that = this
this._earth._viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) {
//判断是否为3DTileFeature对象
if (pickedFeature !== undefined && pickedFeature instanceof Cesium.Cesium3DTileFeature) {
//隐藏当前对象,并且创建楼层切片
pickedFeature.show = false;
//coordinate 和 floor 即为顶点和层高信息
var res = _that.createBuildingLevelImg(pickedFeature.getProperty("coordinate"), pickedFeature.getProperty("floor"));
}
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
//创建楼层切片
createBuildingLevelImg(coordinate, level) {
var l = parseFloat(level);
var positions = this.PolygonWktToArray(coordinate);
var x_min = positions[0];
var y_min = positions[1];
for (var i = 0; i < positions.length; i++) {
if (i % 2 == 0) {
if (x_min > positions[i]) {
x_min = positions[i]
}
} else {
if (y_min > positions[i]) {
y_min = positions[i]
}
}
}
//设置材质
var material = new Cesium.Material({
fabric: {
type: 'Color', //Image
uniforms: {
color: new Cesium.Color(30 / 255, 144 / 255, 1.0, 0.5) //imgUrl color
}
}
})
var primitives = [];
var indexs = []
//循环生成GeometryInstance,高度累乘
for (i = 1; i <= l; ++i) {
let height = 0 + 3 * (i - 1);
var t = "";
if (t < 10) {
t = i;
} else {
t = ("" + i).split('').join(' ')
}
// 添加层数 1F、2F、3F、4F.......
this._earth._viewer.entities.add({
id: "building_label_" + i,
position: Cesium.Cartesian3.fromDegrees(x_min, y_min, height),
label: {
text: t + " F",
verticalOrigin: Cesium.VerticalOrigin.BASELINE,
font: "12px sans-serif",
pixeloffset: new Cesium.Cartesian2(300.0, 100.0),
scale: 0.2,
horizontalOrigin: Cesium.HorizontalOrigin.RIGHT,
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 2000),
scaleByDistance: new Cesium.NearFarScalar(100, 10, 2000, 1),
},
});
// 添加面
var primitive = new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(
Cesium.Cartesian3.fromDegreesArray(positions)
),
vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
height: height
}),
id: "building_level_" + i
}),
appearance: new Cesium.EllipsoidSurfaceAppearance({
material: material,
aboveGround: true, //显示背面
})
});
var index = this._earth._viewer.scene.primitives._primitives.length;
this._earth._viewer.scene.primitives.add(primitive, index)
primitives.push(primitive);
indexs.push(index);
}
}
其他
- 双击事件需要考虑
- 判断双击对象是否为3DTileFeature对象
- 标注和面通过ID前缀进行分组,一批操作里的ID前缀一致( 个人拙技,只能想到通过此行为区分 )
- 是否只允许一个对象进行切片,若不允许,需要把上一次双击的对象( 3DTileFeature 和 楼层面 )显示状态还原。
- 分层后,面的点击事件,例如:点击选中为红色,鼠标经过为黄色
- 退出按钮:和(3)一致,即把双击的对象( 3DTileFeature 和 楼层面 )显示状态还原。
- 3DTile对象也分level,在level5下双击建筑物进行了建筑物分层后,若缩放至level6,建筑物则又会重新显示,此时需要记录点击的位置,监听视角变化(类似的事件都可以),当变化时,重新判定双击处是否有新的3DTileFeature生成,若有,则继续隐藏。
广告牌、Label、光线效果
光柱、DIV跟随且超过距离隐藏
Ceisum三维场景demo的更多相关文章
- 超图GIS入门iserver搭建,前端调用iserver加载三维场景demo
目录 前言 一.GIS介绍,为什么选择它? 二.环境安装 三.调用三维GIS场景 设置地图风格 添加地图iServer服务 前言 前段时间因为对3D制图感兴趣,学习了一下国内制作GIS的公司产品技术, ...
- cesium 之三维场景展示篇(附源码下载)
前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材. 内 ...
- three.js-走进3d的奇妙世界一创建一个三维场景
一.git代码仓库地址 git clone https://github.com/josdirksen/learning-threejs-third 下载并解压 二.创建一个三维场景 如下图所示 ...
- 三维场景中使用BillBoard技术
三维场景中对于渲染效果不是很精致的物体可以使用BillBoard技术实现,使用该技术需要将物体实时朝向摄像机,即计算billboard的旋转矩阵M. 首先根据摄像机位置cameraPos和billBo ...
- SuperMap 二维地图和三维场景弹窗窗口大小控制
注:此处所说的弹窗窗口,主要指的是那些弹窗窗口中嵌入iframe,包含信息页面的窗口大小控制. 1.首先来了解下 SuperMap 示例中的处理方案 二维的处理方式 //初始化Anchored类 po ...
- 从WW中剥离一个三维场景框架
从WW中剥离一个三维场景框架,初步实现的一个.可以绘制一个三角形,但是不能够控制摄像机,没有增加鼠标事件.没有投影,世界变幻之类的东西.以后会不断学习逐步增加进来. 下载地址 下载V1.0.0.2
- 3D游戏引擎中常见的三维场景管理方法
对于一个有很多物体的3D场景来说,渲染这个场景最简单的方式就是用一个List将这些物体进行存储,并送入GPU进行渲染.当然,这种做法在效率上来说是相当低下的,因为真正需要渲染的物体应该是视椎体内的物体 ...
- World Wind Java开发之七——读取本地栅格文件(影像+高程)构建三维场景(转)
http://blog.csdn.net/giser_whu/article/details/41679515 首先,看下本篇博客要达到的效果图: 下面逐步分析如何加载影像及高程文件. 1.World ...
- 三维场景如何嵌入到PPT中展示?
今天要跟大家一起交流的大体内容如标题所示,日常生活中,ppt已经成为人们工作学习生活中不可或缺的工具之一,那么三维场景是如何在ppt中加载展示的呢?请大家慢慢往下看. 1.创建命令按钮和web bro ...
- SLAM: Structure From Motion-移动中三维场景重建
wiki链接:https://en.wikipedia.org/wiki/Structure_from_motion 三维重建: 三维物体建模总结 1. 视野内三维物体重建 : Kinect fusi ...
随机推荐
- 如何在Spark键值对数据中,对指定的Key进行输出/筛选/模式匹配
在用键值对RDD进行操作时,经常会遇到不知道如何筛选出想要数据的情况,这里提供了一些解决方法 目录 1.对固定的Key数据进行查询 2.对不固定的Key数据进行模糊查询 1.对固定的Key数据进行查询 ...
- 【Python】公众号聚合登录软件+源码
废话不多说了,直接上图,回复拿软件和源码[自己打包,配置环境比较复杂] 写这个软件就是因为其他平台的会员太贵了,还不如自己写个,不限制账号登录数~ 授权,打开和删除功能都是正常的, 面板功能,我打算做 ...
- UE5笔记:虚幻引擎反射系统和对象
虚幻引擎反射系统 使用宏提供引擎和编辑器各种功能,封装你的类.使用虚幻时,可以使用标准的C++类,函数和变量 虚幻中对象的基类是UObject,UCALSS宏的作用是标记UObject的子类,以便UO ...
- 4.5 Linux压缩文件或目录中文件为.gz格式(gzip命令)
gzip 是 Linux 系统中经常用来对文件进行压缩和解压缩的命令,通过此命令压缩得到的新文件,其扩展名通常标记为".gz". 再强调一下,gzip 命令只能用来压缩文件,不能压 ...
- word 文档签章控件生成的签章批量删除
某个签章工具的word插件缺少批量插入签章的功能.同时,发现在投标工具中可以使用导出生成pdf时批量签章的功能.现在需要移除先前手动操作生成的多个签章,有如下发现-- 1.对少量签章,可以先选中签章右 ...
- Vue.js vuex
1.前言 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,它解决了vue中不同组件之间状态共享的问题. 通俗的说,它就是一个带响应式的全局变量管理,它数据的改变会触发相关页面/组件的更 ...
- python+playwright安装+使用vsocde运行代码
python虚拟环境 1.安装python,环境配置 2.修改pip镜像源 3.新增虚拟环境 注意路径,例子的路径是在python的目录下生成一个venv文件夹 进入venv文件夹,使用virtual ...
- 【杂谈】如何选择:Session 还是 JWT?
服务端如何验证客户端已经登录? 在用户成功登录后,服务端会发放一个凭证.之后,客户端的每次请求都需要携带该凭证,服务端通过验证凭证的有效性来判断用户是否已登录,并处理请求. 以下是 Session 和 ...
- openEuler欧拉使用rc.local实现开机自启动
设置权限 chmod 775 /etc/rc.local 普通的单条是,直接写在rc.local里 /usr/local/nacos/bin/startup.sh -m standalone 复杂点 ...
- FCM发送测试消息(控制台和postman)
方法1 在firebase控制台新建通知 点击cloud messaging后点击新建通知 输入标题和内容,点击右边的发送测试消息,注意要在真机接收,模拟器收不到 然后添加测试令牌,测试令牌可以在ap ...