官方示例(17):3D场景顶牌模型化开发ThingJS

本文介绍了如何在3D场景中创建广告顶牌,包括在CampusBuilder中设置信息牌以及使用ThingJS进行场景顶牌的开发。详细讲述了在模模搭中配置信息牌的步骤,以及在ThingJS平台上进行编辑和代码描述的方法,强调了3D效果和交互功能的实现。

#前端 #3D开发 #物联网场景可视化

  1. 3D场景中的广告顶牌
  2. CampusBuilder设置信息牌
  3. ThingJS开发场景顶牌
3D场景中的广告顶牌

我们都见过户外广告牌,作为一种户外媒体装置设立于楼群或公路旁,不仅吸引人流,提供场景指引,还可以作为建筑设计的一部分。因此,广告牌的造型设计是多样的。
在这里插入图片描述

在物理世界,广告牌会受到制作材料、受力构件的影响;在3D场景中,顶牌不再是实际意义上的广告牌,而是一种信息表达形式。
3D场景的广告顶牌通常需要图形标注,加入了在线元素,比如缩放、颜色和透明度等,起到更美观的作用。

CampusBuilder设置信息牌

ThingJS提供可视化开发组件,智慧场景在CampusBuilder(模模搭)搭建。

(1)顶牌在模模搭界面内又称为“信息牌”,通常在模型(如柜子)上显示,所以要先选中模型,并明确模型ID、模型名称和自定义属性,左下角编辑信息牌。
在这里插入图片描述

(2)信息牌可以选择不同的样式,并且设置3D模型化或者可见显示,预览确认后即可。
在这里插入图片描述

(3)确认信息牌之后,模型上方会显示并同步到ThingJS开发项目。

<think>我们使用ThingJS平台创建3D城关区模型。ThingJS是基于WebGL的3D开发平台,适用于物联网可视化开发。 目标:构建兰州市城关区的3D行政区划模型,包含建筑物、道路、河流等要素,并添加数据面板。 步骤: 1. 创建场景 2. 加载城关区地理底图(使用GeoJSON数据) 3. 生成3D建筑模型 4. 添加道路、河流等要素 5. 创建信息展示面板 注意:ThingJS使用JavaScript开发,代码在在线平台(https://www.thingjs.com/)运行。 以下是完整代码示例: ```javascript // 兰州市城关区3D模型 - ThingJS实现 var app = new THING.App({ url: 'https://www.thingjs.com/static/models/storehouse' // 默认场景 }); app.on('load', function() { // 设置地图中心点为兰州城关区(示例坐标) app.background = [0, 0, 0]; // 黑色背景 app.camera.position = [103.792, 300, 36.05]; // 经度, 高度, 纬度 // 1. 创建行政区划底图 // 假设我们有城关区的GeoJSON数据 const chengguanGeoJSON = { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "城关区" }, "geometry": { "type": "Polygon", "coordinates": [[ [103.732, 36.061], [103.852, 36.061], [103.852, 36.040], [103.732, 36.040], [103.732, 36.061] // 闭合 ]] } } ] }; // 创建行政区划地块 const district = app.create({ type: 'GeoJSON', data: chengguanGeoJSON, style: { color: '#3388FF', opacity: 0.5, outlineColor: '#FFFFFF' }, // 设置高度(单位:米) height: 10, position: [0, 0, 0] }); district.name = '城关区'; // 2. 创建3D建筑群(使用随机生成建筑代替真实数据) const buildings = []; // 在城关区范围内随机生成100栋建筑 for (let i = 0; i < 100; i++) { // 随机生成在城关区内的坐标 let lon = 103.732 + Math.random() * (103.852 - 103.732); let lat = 36.040 + Math.random() * (0.021); // 36.040~36.061 // 随机建筑高度(3~15层,每层3米) let height = Math.floor(Math.random() * 13 + 3) * 3; let building = app.create({ type: 'Building', position: [lon, 0, lat], // ThingJS中position格式:[x, y, z] 对应 [经度, 高度, 纬度] width: 15 + Math.random() * 10, length: 15 + Math.random() * 10, height: height, style: { color: THING.Math.randomColor() } }); buildings.push(building); } // 3. 创建道路(简化示例) const roads = [ { name: '天水路', path: [[103.735, 36.045], [103.845, 36.045]] }, { name: '东岗路', path: [[103.740, 36.050], [103.850, 36.050]] } ]; roads.forEach(road => { app.create({ type: 'Road', path: road.path, // 路径坐标点 width: 20, // 道路宽度(米) style: { color: '#888888' } }); }); // 4. 创建信息面板 const panel = new THING.widget.Panel({ title: '城关区数据', width: '300px', height: '200px', position: [20, 20] }); // 添加数据字段 panel.addString('名称', 'name').value = '兰州市城关区'; panel.addNumber('人口()', 'population').value = 150; panel.addNumber('GDP(亿元)', 'gdp').value = 1200; panel.addNumber('面积(km²)', 'area').value = 220; // 5. 添加交互:点击建筑显示信息 buildings.forEach(building => { building.on('click', function() { // 显示tip app.tip.show(`建筑高度:${this.height}米`); }); }); }); ``` ### 代码说明 1. **场景初始化** - 创建 `THING.App` 实例加载默认场景 - 设置摄像机位置到城关区上空 2. **行政区划创建** - 使用 `GeoJSON` 数据创建行政区划多边形 - 设置半透明蓝色填充和白色边框 3. **建筑生成** - 在行政区范围内随机生成100栋3D建筑 - 每栋建筑随机生成宽度、长度和高度 - 使用随机颜色区分建筑 4. **道路网络** - 创建两条主要道路(天水路和东岗路) - 使用 `Road` 类型对象绘制直线道路 5. **交互功能** - 左侧信息面板显示行政区关键数据 - 点击建筑显示高度信息 ### 扩展建议 1. **数据对接** - 使用真实GIS数据替换示例坐标 - 对接城市建筑数据库获取真实建筑轮廓 2. **功能增强** - 添加人口热力图图层 - 实现日夜模式切换 - 加入交通流模拟 --- §§相关问题§§: 1. 如何在ThingJS中加载真实的城市GIS建筑数据? 2. 怎样实现建筑物根据实际高度和用途(住宅/商业)着色? 3. 如何在ThingJS中添加随时间变化的交通流量模拟? 4. 怎样将物联网设备数据(如摄像头、传感器)接入3D场景? </think>### 使用 ThingJS 构建兰州市城关区 3D 模型解决方案 以下是使用 ThingJS 平台创建兰州市城关区三维可视化模型的完整代码方案: ```javascript // 初始化 ThingJS 场景 const app = new THING.App({ url: 'https://www.thingjs.com/static/models/storehouse' // 基础场景 }); // 兰州市城关区核心数据模型 const districtData = { name: "兰州市城关区", center: [103.792, 36.05], // 中心点坐标(经度, 纬度) boundary: [ // 边界坐标(简化) [103.732, 36.061], [103.852, 36.061], [103.852, 36.040], [103.732, 36.040] ], population: 1500000, gdp: 1200, // 单位: 亿元 area: 220 // 单位: 平方公里 }; // 创建城关区边界模型 app.on('load', function() { // 1. 创建地形基底 const terrain = app.create({ type: 'Terrain', url: 'https://www.thingjs.com/static/terrain/terrain.terrain', position: [0, -50, 0], scale: [2, 1, 2] }); // 2. 创建行政区边界 const boundary = app.create({ type: 'Polygon', points: districtData.boundary.map(coord => { return THING.GeoPoint.fromCoord(coord).position }), color: '#3388FF', opacity: 0.6, height: 20 }); boundary.name = districtData.name; // 3. 添加核心建筑物 const buildings = [ { name: "兰州站", position: [103.841, 36.043], height: 60, color: '#FF5722' }, { name: "兰州大学", position: [103.840, 36.049], height: 40, color: '#4CAF50' }, { name: "黄河铁桥", position: [103.821, 36.067], height: 20, color: '#795548' } ]; buildings.forEach(building => { const pos = THING.GeoPoint.fromCoord(building.position).position; const obj = app.create({ type: 'ExtrusionBuilding', points: [ [pos[0] - 0.001, pos[2] - 0.001], // 建筑基底多边形 [pos[0] + 0.001, pos[2] - 0.001], [pos[0] + 0.001, pos[2] + 0.001], [pos[0] - 0.001, pos[2] + 0.001] ], height: building.height, style: { color: building.color, image: '/images/bricks.jpg' } }); obj.name = building.name; // 添加点击事件 obj.on('click', function() { showInfoPanel(this.name, building); }); }); // 4. 创建道路系统 const roads = [ { name: "天水路", path: [[103.735, 36.045], [103.845, 36.045]], width: 20 }, { name: "东岗路", path: [[103.740, 36.050], [103.850, 36.050]], width: 15 } ]; roads.forEach(road => { const points = road.path.map(coord => THING.GeoPoint.fromCoord(coord).position ); app.create({ type: 'Road', points: points, width: road.width, style: { color: '#666666', image: '/images/road.jpg' } }); }); // 5. 创建数据展示UI createDashboard(); }); // 创建信息面板 function createDashboard() { // 创建2D UI面板 const panel = new THING.widget.Panel({ title: '城关区数据面板', width: '300px', height: '250px', position: [20, 20] }); // 添加数据字段 panel.addString('行政区名称', 'name').value = districtData.name; panel.addNumber('人口数量', 'population').value = districtData.population; panel.addNumber('GDP(亿元)', 'gdp').value = districtData.gdp; panel.addNumber('面积(km²)', 'area').value = districtData.area; // 添加控制按钮 panel.addButton('显示热力图', function() { toggleHeatmap(); }); panel.addButton('夜间模式', function() { app.background = [0.05, 0.05, 0.1]; app.envMap = '/images/night.jpg'; }); } // 显示建筑信息 function showInfoPanel(title, data) { const infoPanel = new THING.widget.Panel({ title: title, width: '250px', height: '150px', position: [350, 20] }); infoPanel.addString('建筑类型', 'type').value = data.type || '公共建筑'; infoPanel.addNumber('高度()', 'height').value = data.height; infoPanel.addString('建成时间', 'year').value = data.year || '1950年'; // 10秒后自动关闭 setTimeout(() => infoPanel.destroy(), 10000); } // 切换人口热力图 function toggleHeatmap() { // 实现热力图显示逻辑 // 此处简化实现,实际需对接数据服务 const points = []; for (let i = 0; i < 200; i++) { const lon = 103.732 + Math.random() * 0.12; const lat = 36.040 + Math.random() * 0.021; points.push({ position: THING.GeoPoint.fromCoord([lon, lat]).position, value: Math.random() * 100 }); } const heatmap = app.create({ type: 'HeatMap', points: points, radius: 100, gradient: { 0: '#00FFFF', // 低密度 0.5: '#00FF00', 1: '#FF0000' // 高密度 } }); } ``` ### 代码功能详解 #### 1. 场景初始化 - 使用 `THING.App` 创建基础3D场景 - 加载默认仓库场景作为基底 #### 2. 行政区划模型 - **地形基底**:创建自适应地形作为基础 - **边界模型**:通过多边形创建蓝色半透明区域边界 - **高程设置**:使用高度值创建3D立体效果 #### 3. 建筑系统 - **核心建筑**:创建兰州站、兰州大学等地标建筑 - **建筑参数**:自定义高度、颜色和纹理 - **交互功能**:添加点击事件显示建筑信息 #### 4. 道路系统 - **道路生成**:使用路径点创建主要道路 - **宽度控制**:自定义不同等级道路宽度 - **纹理贴图**:添加道路纹理增强真实感 #### 5. 数据可视化 - **信息面板**:右侧悬浮面板显示区域关键数据 - **热力图**:模拟人口分布热力效果 - **模式切换**:实现日夜模式切换功能 ### 扩展建议 1. **数据对接** - 连接GIS数据库获取真实建筑轮廓 - 对接人口统计API实现动态热力数据 - 集成物联网设备实时数据 2. **功能增强** - 添加时间轴展示区域发展历史 - 实现建筑爆炸图展示内部结构 - 加入交通流量模拟系统 3. **交互优化** - VR/AR设备支持 - 多人在线协作查看 - 语音控制导航
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值