分享
查看: 2627|回复: 0

[发布] 物联网可视化行业应用 智慧城市地下管线3D可视化

[复制链接]

物联网可视化行业应用 智慧城市地下管线3D可视化

发表于 2019-9-29 11:48:58 来自 发布 阅读模式 倒序浏览
zzv_icon2627 zzr_icon0 查看全部


在物联网不断发展的情况下,物联网可视化也成为了越来越多的企业的追求,腾讯的滨海大厦-智慧楼宇可视化应用、阿里的杭州临平智慧文化艺术长廊-数字孪生智慧建筑IBV,除了这些bat企业,还有其他企业也在使用ThingJS搭建属于自己的三维可视化应用,而管网也是城市最重要的公共基础设施之一,与城市的发展和居民日常生活息息相关。根据不同的市政建设,管网分供水、排污、供暖、通信、电力等多种类别,其广泛分布遍及地下。随着城市发展建设所衍生出空间分布复杂,变化大,种类繁多等问题,可视化管理是未来发展最好的解决方案。

Demo预览

物联网可视化行业应用 智慧城市地下管线3D可视化


实现

第一步,加载场景

  1. //加载场景代码var app = new THING.App({ // 场景地址
  2. "url": "http://www.thingjs.com/./uploads/wechat/S2Vyd2lu/scene/Demo_地下管线", //背景设置
  3. "skyBox": "BlueSky"});
复制代码

第二步,创建管线以及创建管线信息面板。这里PolygonLine这种类型我们在之前的Demo中使用过没看过的同学可以点进去看一下,当然那篇比较糙还是没有这篇好看的,可以两篇对比一下效果,文章地址。这里这个renderOrder属性划重点,这里将line的visible属性设置为false,当场景加载完成后我们的管线就已经创建好了为了能更好的配合我们的面板所以给他先隐藏掉了,等到开关触发再对他进行展示。

  1. function createLine(name, color, points) { var line = null;
  2. line = app.create({
  3. type: 'PolygonLine',
  4. name: name,
  5. points: points,
  6. style: {
  7. color: color,
  8. },
  9. });
  10. line.renderOrder = -10000;
  11. line.scrollUV = true;
  12. line.visible = false; return line;
  13. }function createInfo(obj, position) { var panel = new THING.widget.Panel({
  14. template: 'default2',
  15. width: '120px',
  16. cornerType: 'polyline'
  17. }) var dataObj = {
  18. name: obj.name,
  19. color: obj.style.color
  20. }
  21. panel.addString(dataObj, 'name').caption('名称');
  22. panel.addString(dataObj, 'color').caption('颜色'); var uiAnchor = app.create({
  23. type: 'UIAnchor', parent: obj,
  24. element: panel.domElement,
  25. position: [position[0], -1, position[2]],
  26. pivot: [-0.2, 2.1]
  27. }); return uiAnchor;
  28. }
复制代码

第三步,创建功能面板以及创建各种类管线。

  1. //管线的模拟数据var dataJson = [{ 'id': 'BJ002', 'starId': '2TAG001', 'stopId': '2TAG002', 'starDeep': '-1.5', 'stopDeep': '-1.5', 'material': 'ASTNX01', 'pressure': '120' },
  2. { 'id': 'BJ002', 'starId': '2TAG001', 'stopId': '2TAG002', 'starDeep': '-1.5', 'stopDeep': '-1.5', 'material': 'ASTNX01', 'pressure': '120' },
  3. { 'id': 'BJ002', 'starId': '2TAG001', 'stopId': '2TAG002', 'starDeep': '-1.5', 'stopDeep': '-1.5', 'material': 'ASTNX01', 'pressure': '120' }];
复制代码
  1. app.on('load', function () {
  2. // init_camera
  3. app.camera.flyTo({ 'position': [-6.199233956799988, 49.47465259648085, 113.74453304853118], 'target': [-4.002967317456267, 26.055382001258867, 37.65111202780902], 'time': 2000,
  4. });
  5. //创建场景
  6. var controlPanel = new THING.widget.Panel({
  7. titleText: '地下管线Demo',
  8. hasTitle: true, // 是否有标题
  9. zIndex: 999, // 设置层级
  10. });
  11. var data = {
  12. totalOpen: false,
  13. viewOpen: false,
  14. waterOpen: false,
  15. blowOffOpen: false,
  16. heatOpen: false
  17. };
  18. //openTotal按钮控制
  19. var totalOpen = controlPanel.addBoolean(data, 'totalOpen').caption('状态切换');
  20. totalOpen.on('change', function (ev) { if (ev) {
  21. //将campus下所有的obj的opacity = 0.4,将name = Uncorrelated 的obj的visiable = false
  22. app.query('Campus')[0].style.opacity = 0.3;
  23. app.query('Uncorrelated')[0].visible = false;
  24. } else {
  25. //反之初始化
  26. app.query('Campus')[0].style.opacity = 1;
  27. app.query('Uncorrelated')[0].visible = true;
  28. }
  29. });
  30. //viewOpen视角控制
  31. var viewOpen = controlPanel.addBoolean(data, 'viewOpen').caption('2D/3D');
  32. viewOpen.on('change', function (ev) { if (ev) {
  33. app.camera.viewMode = THING.CameraView.TopView;
  34. } else {
  35. app.camera.viewMode = THING.CameraView.Normal;
  36. app.skyBox = 'BlueSky';
  37. }
  38. });
  39. //waterOpen供水管线 color #0000FF
  40. var waterOpen = controlPanel.addBoolean(data, 'waterOpen').caption('供水管线');
  41. var waterLine = [];
  42. waterLine.push(createLine('供水管线', 'https://thingjs.com/static/images/poly_line_04.png', [[-61.736, -1.5, 10], [74.408, -1.5, 10]]));
  43. waterLine.push(createLine('供水管线', 'https://thingjs.com/static/images/poly_line_04.png', [[-61.736, -1.50, 8], [-16.126, -1.50, 8], [-16.126, -1.50, -20], [-10.126, -1.50, -20], [-10.126, -1.50, 8], [74.408, -1.5, 8]]));
  44. waterLine.push(createLine('供水管线', 'https://thingjs.com/static/images/poly_line_04.png', [[-61.736, -1.50, 12], [-45.001, -1.5, 15.755], [-20.736, -1.5, 12], [74.408, -1.5, 12]]));
  45. waterLine.push(createLine('供水管线', 'https://thingjs.com/static/images/poly_line_04.png', [[4, -1.5, 46], [4, -1.50, 13.809], [4, -2, 13.809], [4, -2, 6], [4, -1.50, 6], [4, -1.5, -34]]));
  46. waterLine.push(createLine('供水管线', 'https://thingjs.com/static/images/poly_line_04.png', [[6, -1.50, 46], [6, -1.50, 13.809], [6, -2, 13.809], [6, -2, 6], [6, -1.50, 6], [6, -1.5, -34]]));
  47. waterLine.push(createLine('供水管线', 'https://thingjs.com/static/images/poly_line_04.png', [[8, -1.50, 46], [8, -1.50, 13.809], [8, -2, 13.809], [8, -2, 6], [8, -1.50, 6], [8, -1.5, -34]]));
  48. createInfo(waterLine[0], dataJson[0],[-28.847, -1.5, 7.957]);
  49. waterOpen.on('change', function (ev) {
  50. waterLine.forEach(function (obj) {
  51. obj.visible = ev;
  52. })
  53. });
  54. //blowOffLine排污管线 color #FFEC8B
  55. var blowOffOpen = controlPanel.addBoolean(data, 'blowOffOpen').caption('排污管线');
  56. var blowOffLine = [];
  57. blowOffLine.push(createLine('排污管线', 'https://thingjs.com/static/images/poly_line_03.png', [[-2, -3, 46], [-2, -3, -34]]));
  58. blowOffLine.push(createLine('排污管线', 'https://thingjs.com/static/images/poly_line_03.png', [[0, -3, 46], [0, -3, -34]]));
  59. blowOffLine.push(createLine('排污管线', 'https://thingjs.com/static/images/poly_line_03.png', [[-61.736, -3, 4], [74.408, -3, 4]]));
  60. blowOffLine.push(createLine('排污管线', 'https://thingjs.com/static/images/poly_line_03.png', [[-61.736, -3, 2], [74.408, -3, 2]]));
  61. createInfo(blowOffLine[0], dataJson[1],[15.299, -1.5, 1.87]);
  62. blowOffOpen.on('change', function (ev) {
  63. blowOffLine.forEach(function (obj) {
  64. obj.visible = ev;
  65. })
  66. });
  67. //heatLine供热管线 color #FF7F24
  68. var heatOpen = controlPanel.addBoolean(data, 'heatOpen').caption('供热管线');
  69. var heatLine = [];
  70. heatLine.push(createLine('供热管线', 'https://thingjs.com/static/images/poly_line_02.png', [[-61.736, -2, 0], [65.736, -2, 0], [74.408, -2, -8]]));
  71. heatLine.push(createLine('供热管线', 'https://thingjs.com/static/images/poly_line_02.png', [[-61.736, -2, -2], [65.736, -2, -2], [74.408, -2, -10]]));
  72. heatLine.push(createLine('供热管线', 'https://thingjs.com/static/images/poly_line_02.png', [[-4, -2, 46], [-4, -2, -34]]));
  73. heatLine.push(createLine('供热管线', 'https://thingjs.com/static/images/poly_line_02.png', [[-6, -2, 46], [-6, -2, -34]]));
  74. createInfo(heatLine[0], dataJson[2],[-6.041, -1.817, 8.865]);
  75. heatOpen.on('change', function (ev) {
  76. heatLine.forEach(function (obj) {
  77. obj.visible = ev;
  78. })
  79. });
复制代码

小结
这个取点坐标的方法在上文中没有告诉大家,只是因为我原来用的方法就比较傻了,我是自己写了一个全局的singleclick事件,触发之后打印出当前鼠标的pickedPosistion记录下来再写进数组中,这无疑的是很麻烦的操作。
其实ThingJS已经给我们写好了一个工具叫做拾取场景坐标,他的使用方式下面我会给大家贴几张图。整个代码100+行还是比较简洁了(作者能力有限,已经努力精简了下文可以给作者多提意见,虚心接受)。最后附上完整代码!

完整代码

  1. //加载场景代码
  2. var app = new THING.App({
  3. // 场景地址 "url": "http://www.thingjs.com/./uploads/wechat/S2Vyd2lu/scene/Demo_地下管线",
  4. //背景设置 "skyBox": "BlueSky"});
  5. app.on('load', function () {
  6. // init_camera
  7. app.camera.flyTo({ 'position': [-6.199233956799988, 49.47465259648085, 113.74453304853118], 'target': [-4.002967317456267, 26.055382001258867, 37.65111202780902], 'time': 2000,
  8. });
  9. //创建场景
  10. var controlPanel = new THING.widget.Panel({
  11. titleText: '地下管线Demo',
  12. hasTitle: true, // 是否有标题
  13. zIndex: 999, // 设置层级
  14. });
  15. var data = {
  16. totalOpen: false,
  17. viewOpen: false,
  18. waterOpen: false,
  19. blowOffOpen: false,
  20. heatOpen: false
  21. };
  22. //openTotal按钮控制
  23. var totalOpen = controlPanel.addBoolean(data, 'totalOpen').caption('状态切换');
  24. totalOpen.on('change', function (ev) { if (ev) {
  25. //将campus下所有的obj的opacity = 0.4,将name = Uncorrelated 的obj的visiable = false
  26. app.query('Campus')[0].style.opacity = 0.3;
  27. app.query('Uncorrelated')[0].visible = false;
  28. } else {
  29. //反之初始化
  30. app.query('Campus')[0].style.opacity = 1;
  31. app.query('Uncorrelated')[0].visible = true;
  32. }
  33. });
  34. //viewOpen视角控制
  35. var viewOpen = controlPanel.addBoolean(data, 'viewOpen').caption('2D/3D');
  36. viewOpen.on('change', function (ev) { if (ev) {
  37. app.camera.viewMode = THING.CameraView.TopView;
  38. } else {
  39. app.camera.viewMode = THING.CameraView.Normal;
  40. app.skyBox = 'BlueSky';
  41. }
  42. });
  43. //waterOpen供水管线 color #0000FF
  44. var waterOpen = controlPanel.addBoolean(data, 'waterOpen').caption('供水管线');
  45. var waterLine = [];
  46. waterLine.push(createLine('供水管线', 'https://thingjs.com/static/images/poly_line_04.png', [[-61.736, -1.5, 10], [74.408, -1.5, 10]]));
  47. waterLine.push(createLine('供水管线', 'https://thingjs.com/static/images/poly_line_04.png', [[-61.736, -1.50, 8], [-16.126, -1.50, 8], [-16.126, -1.50, -20], [-10.126, -1.50, -20], [-10.126, -1.50, 8], [74.408, -1.5, 8]]));
  48. waterLine.push(createLine('供水管线', 'https://thingjs.com/static/images/poly_line_04.png', [[-61.736, -1.50, 12], [-45.001, -1.5, 15.755], [-20.736, -1.5, 12], [74.408, -1.5, 12]]));
  49. waterLine.push(createLine('供水管线', 'https://thingjs.com/static/images/poly_line_04.png', [[4, -1.5, 46], [4, -1.50, 13.809], [4, -2, 13.809], [4, -2, 6], [4, -1.50, 6], [4, -1.5, -34]]));
  50. waterLine.push(createLine('供水管线', 'https://thingjs.com/static/images/poly_line_04.png', [[6, -1.50, 46], [6, -1.50, 13.809], [6, -2, 13.809], [6, -2, 6], [6, -1.50, 6], [6, -1.5, -34]]));
  51. waterLine.push(createLine('供水管线', 'https://thingjs.com/static/images/poly_line_04.png', [[8, -1.50, 46], [8, -1.50, 13.809], [8, -2, 13.809], [8, -2, 6], [8, -1.50, 6], [8, -1.5, -34]]));
  52. createInfo(waterLine[0], dataJson[0],[-28.847, 0, 7.957]);。
  53. waterOpen.on('change', function (ev) {
  54. waterLine.forEach(function (obj) {
  55. obj.visible = ev;
  56. })
  57. });
  58. //blowOffLine排污管线 color #FFEC8B
  59. var blowOffOpen = controlPanel.addBoolean(data, 'blowOffOpen').caption('排污管线');
  60. var blowOffLine = [];
  61. blowOffLine.push(createLine('排污管线', 'https://thingjs.com/static/images/poly_line_03.png', [[-2, -3, 46], [-2, -3, -34]]));
  62. blowOffLine.push(createLine('排污管线', 'https://thingjs.com/static/images/poly_line_03.png', [[0, -3, 46], [0, -3, -34]]));
  63. blowOffLine.push(createLine('排污管线', 'https://thingjs.com/static/images/poly_line_03.png', [[-61.736, -3, 4], [74.408, -3, 4]]));
  64. blowOffLine.push(createLine('排污管线', 'https://thingjs.com/static/images/poly_line_03.png', [[-61.736, -3, 2], [74.408, -3, 2]]));
  65. createInfo(blowOffLine[0], dataJson[1],[15.299, 0, 1.87]);
  66. blowOffOpen.on('change', function (ev) {
  67. blowOffLine.forEach(function (obj) {
  68. obj.visible = ev;
  69. })
  70. });
  71. //heatLine供热管线 color #FF7F24
  72. var heatOpen = controlPanel.addBoolean(data, 'heatOpen').caption('供热管线');
  73. var heatLine = [];
  74. heatLine.push(createLine('供热管线', 'https://thingjs.com/static/images/poly_line_02.png', [[-61.736, -2, 0], [65.736, -2, 0], [74.408, -2, -8]]));
  75. heatLine.push(createLine('供热管线', 'https://thingjs.com/static/images/poly_line_02.png', [[-61.736, -2, -2], [65.736, -2, -2], [74.408, -2, -10]]));
  76. heatLine.push(createLine('供热管线', 'https://thingjs.com/static/images/poly_line_02.png', [[-4, -2, 46], [-4, -2, -34]]));
  77. heatLine.push(createLine('供热管线', 'https://thingjs.com/static/images/poly_line_02.png', [[-6, -2, 46], [-6, -2, -34]]));
  78. createInfo(heatLine[0], dataJson[2],[-6.041, 0, 8.865]);
  79. heatOpen.on('change', function (ev) {
  80. heatLine.forEach(function (obj) {
  81. obj.visible = ev;
  82. })
  83. });
  84. });function createLine(name, image, points) {
  85. var line = null;
  86. line = app.create({ type: 'PolygonLine',
  87. name: name,
  88. points: points,
  89. image: image
  90. });
  91. line.renderOrder = -10000;
  92. line.scrollUV = true;
  93. line.visible = false; return line;
  94. }function createInfo(obj,json, position) {
  95. var panel = new THING.widget.Panel({
  96. template: 'default2',
  97. width: '200px',
  98. cornerType: 'polyline'
  99. })
  100. // panel.zIndex = -10000;
  101. panel.renderOrder = -1000;
  102. var dataObj = {
  103. name: ' ',
  104. id: json.id,
  105. starId: json.starId,
  106. stopId: json.stopId,
  107. starDeep: json.starDeep,
  108. stopDeep: json.stopDeep,
  109. material: json.material,
  110. pressure: json.pressure,
  111. }
  112. panel.addString(dataObj, 'name').caption(obj.name);
  113. panel.addString(dataObj, 'id').caption('管线编号');
  114. panel.addString(dataObj, 'starId').caption('起点编号');
  115. panel.addString(dataObj, 'stopId').caption('终点编号');
  116. panel.addString(dataObj, 'starDeep').caption('起点深度');
  117. panel.addString(dataObj, 'stopDeep').caption('终点深度');
  118. panel.addString(dataObj, 'material').caption('材料');
  119. panel.addString(dataObj, 'pressure').caption('压力');
  120. var uiAnchor = app.create({ type: 'UIAnchor',
  121. parent: obj,
  122. element: panel.domElement,
  123. position: [position[0], 0, position[2]],
  124. pivot: [-0.2, 2.1]
  125. }); return uiAnchor;
  126. }
  127. var dataJson = [{ 'id': 'BJ002', 'starId': '2TAG001', 'stopId': '2TAG002', 'starDeep': '-1.5', 'stopDeep': '-1.5', 'material': 'ASTNX01', 'pressure': '120' },
  128. { 'id': 'BJ002', 'starId': '2TAG001', 'stopId': '2TAG002', 'starDeep': '-1.5', 'stopDeep': '-1.5', 'material': 'ASTNX01', 'pressure': '120' },
  129. { 'id': 'BJ002', 'starId': '2TAG001', 'stopId': '2TAG002', 'starDeep': '-1.5', 'stopDeep': '-1.5', 'material': 'ASTNX01', 'pressure': '120' }];
复制代码

2018年由优锘科技携其主创团队开发的新一代物联网可视化开发平台ThingJS,使用当今热门易学的 Javascript 语言进行开发。不仅可以针对单栋或多栋建筑组成的园区场景进行可视化开发,搭载丰富插件后,也可以针对地图级别场景进行开发。广泛应用于数据中心、仓储、学校、医院、安防、预案等多种领域。拥有着卓越的眼光和优秀的物联网可视化技术,并且相比于three.js,unity,它的入门门槛极低,操作十分简单,极大的简化了开发难度、提升开发效率。

avatar
游客~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

130700ppkpl8x3t7tt1b1t