SuperMap iClient3D for Cesium 构建隧道

作者:kele

背景

前段时间看到一篇构建隧道的文章(https://blog.csdn.net/supermapsupport/article/details/128453116),突然想到一个使用场景:隧道通常是建在山体下面,是否可以通过这种方式构建出一条贯穿山体的隧道,来模拟实际的施工方案?答案是可以,效果图如下:
在这里插入图片描述

一、实现思路

1、生成隧道模型
2、地形挖洞
3、把隧道模型放在洞口中
该方案的难点在于,如何根据隧道的截面坐标,将地形挖洞,使洞口与隧道模型完全吻合
由于地形服务无法做布尔运算,这里采用地形开挖方式实现,并不展示开挖底面与侧面,这样就相当于给地形裁剪一个口子,关键接口:
在这里插入图片描述
在这里插入图片描述

二、实现过程

1、构建管道模型

用鼠标绘制一条折线代表隧道的走向
然后使用iServer放样分析,输入隧道截面坐标,分析出一条带管壁厚度的隧道

var s3mInstanceColc = new Cesium.S3MInstanceCollection(scene._context);
scene.primitives.add(s3mInstanceColc);
var sqlParameter = {
    "loftRegion":{"type":"REGION" , "parts":[8,8], "points":[{ x: -2.5, y: 7.5},
            { x: -6.5, y: 5.5 },
            { x: -10.5, y: 0 },
            { x: -10.5, y: -10.5 },  //隧道截面坐标,单位为米
            { x: 10.5, y: -10.5 },
            { x:10.5, y: 0},
            { x: 6.5, y: 5.5 },
            { x: 2.5, y: 7.5},
            { x: -1.5, y: 6.5},
            { x: 1.5, y: 6.5},
            { x: 5.5, y: 4.5 },
            { x: 9.5, y: 0},
            { x: 9.5, y: -9.5 },
            { x: -9.5, y: -9.5 },
            { x: -9.5, y: 0 },
            { x: -5.5, y: 4.5 }]},
    "loftLine":{"type":"LINE3D", "parts":[2], "points":posArray},
    "chamfer":"5",
    "lonlat":"TRUE"
};
var url = "http://10.10.4.82:8090/iserver/services/spatialAnalysis-test/restjsr/spatialanalyst/geometry/3d/loft.json?returnContent=true";
var queryData = JSON.stringify(sqlParameter);

$.ajax({
    type: "post",
    url: url,
    data: queryData,
    success: function (result) {
        var geometry = result.geometry;
        if (!geometry) {
            return;
        }
        var buffer = new Uint8Array(geometry.model).buffer;
        var position = geometry.position;
        var color = Cesium.Color.GRAY;
        s3mInstanceColc.add('visibleBody', {
            position: Cesium.Cartesian3.fromDegrees(position.x, position.y, position.z+10),
            color: color,
            attributes: 'test'
        }, buffer);
        viewer.flyTo(s3mInstanceColc);
    },
    error: function (msg) {
        console.log(msg);
    },
})

在这里插入图片描述

2、根据隧道给地形挖洞

2.1、去除挖洞封边效果,去除侧面与底面贴图
scene.globe.showExcavationSide = false;
scene.globe.excavationBottomTextureUrl = null;
scene.globe.excavationSideTextureUrl = null;

2.2、开挖方案

在这里插入图片描述
从图中可以看出,隧道口被堵死,我们需要拿到隧道与地形相交部分的节点坐标,然后将地形挖开。所以关键步骤就是如何得到相交坐标,如下图所示:
在这里插入图片描述
第一步获取隧道截面坐标(红色点),第二步利用隧道方向向量,绘制出基于截面坐标且平行与隧道的线段(通视分析),第三步得到线段与地形的交点(蓝色点),第四步用得到的交点坐标将地形挖开

2.3、获取截面坐标点(红色点)

①在构建隧道模型时,我们可以根据传入的平面坐标,计算每个端点与中心点的距离
②在绘制隧道走向时,我们根据绘制坐标计算出隧道的方向向量,从而获取线的角度,在这个角度基础上±90°,得到隧道垂直方向,方向+距离即可计算出目标点的世界坐标。利用不同距离得到多个点坐标,再给各个点设置高度,即可得到所有的隧道截面世界坐标。向量与角度的计算可以参考这篇文章:Cesium计算向量、角度、距离
关键代码:

this.getPointByDirectionAndLen = function (position, angle, len) {
  let matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position);
  let mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(angle));
  let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
  Cesium.Matrix4.multiply(matrix, rotationZ, matrix);
  let result;
  result = Cesium.Matrix4.multiplyByPoint(
      matrix,
      new Cesium.Cartesian3(0, len, 0),
      new Cesium.Cartesian3()
  );
  return result;
};

2.4、获取开挖点(蓝色点)

经过上面的步骤,我们已经得到隧道截面坐标(下图中C坐标)、隧道线向量(AB)。根据公式:D坐标-C坐标 = 向量AB
可以得到D坐标
在这里插入图片描述
得到C、D坐标后,使用通视分析(sightline)得到观察点C到目标点D,之间与地形的障碍点;依次对每个截面坐标做以上操作,即可得到所有障碍点
关键代码:

this.getBarrierArray = function (LonLatArr,sightline) {
  let pointA = new Cesium.Cartesian3.fromDegrees(posArray[0].x,posArray[0].y,posArray[0].z);
  let pointB = new Cesium.Cartesian3.fromDegrees(posArray[1].x,posArray[1].y,posArray[1].z);
  let index = 0;
  //向量AB
  const positionvector = Cesium.Cartesian3.subtract(pointB, pointA, new Cesium.Cartesian3());
  myfun(index);
  let BarrierArray = [];
  function myfun(index){
    if(index < LonLatArr.length){
      let cart = new Cesium.Cartesian3.fromDegrees(LonLatArr[index][0], LonLatArr[index][1], LonLatArr[index][2]);
      let posD = {
        x: cart.x + positionvector.x,
        y: cart.y + positionvector.y,
        z: cart.z + positionvector.z
      };
      let thisArray = [];
      thisArray.push(cart);
      thisArray.push(posD);
      var name = "point" + index;
      sightline.viewPosition = Cartesian2toDegrees(thisArray[0]);
      sightline.addTargetPoint({
        position: Cartesian2toDegrees(thisArray[1]),
        name: name
      });
      setTimeout(()=>{
        let barrp = sightline.getBarrierPoint(name);
        console.log(barrp);

        if(!barrp.isViewer){
          BarrierArray.push(barrp.position.longitude * (180/Math.PI));
          BarrierArray.push(barrp.position.latitude * (180/Math.PI));
          BarrierArray.push(barrp.position.height);
        }
        sightline.removeAllTargetPoint();
      },30);
      index++;
      setTimeout(()=>{
        myfun(index)
      },40)
    }
  }

  function Cartesian2toDegrees(position) {
    var cartographic = Cesium.Cartographic.fromCartesian(position);
    var longitude = Cesium.Math.toDegrees(cartographic.longitude);
    var latitude = Cesium.Math.toDegrees(cartographic.latitude);
    var height = cartographic.height;

    return [longitude, latitude, height];
  }

  return BarrierArray
};

2.5、地形开挖

得到所有障碍点后,通过这些点进行地形开挖

viewer.scene.globe.addExcavationRegion({
    name: 'ggg',
    position: brruipos,
    height: dep,
    transparent: false
});

范例:

链接:https://pan.baidu.com/s/1sDwfmI6hBFIS3eCt7tBGug
提取码:6655

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/15843.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用Python和机器学习进行文本情感分类

使用Python和机器学习进行文本情感分类 1. 效果图2. 原理3. 源码参考这篇博客将介绍如何使用Python进行机器学习的文本情感分类(Text Emotions Classification)。 1. 效果图 训练文本及情感分类前5条数据如下: 训练过程及测试文本情感分类效果图如下: 可以看到 对文本“S…

【量化交易笔记】5.SMA,EMA 和WMA区别

股票中的SMA&#xff0c;EMA和WMA是常用的技术分析指标。这些指标基于历史股价计算得出&#xff0c;可以帮助投资者了解股票的趋势&#xff0c;为决策提供依据。虽然它们都是平均值算法&#xff0c;但它们之间还是有一些区别的。 SMA 简单移动平均线&#xff08;Simple Moving…

分布式的流处理平台Kafka

目录&#xff1a; 一、简介二、基本概念三、生产者使用详解四、发送消息五、消费者代码示例 一、简介 ApacheKafka 是一个分布式的流处理平台。它具有以下特点&#xff1a; 支持消息的发布和订阅&#xff0c;类似于 RabbtMQ、ActiveMQ 等消息队列&#xff1b;支持数据实时处理…

计算机组成原理第五章(2)---中断

5.1概述 产生和应用 在IO设备和主机交换数据时&#xff0c;由于设备本身的机电特性的影响&#xff0c;其工作速度比较低&#xff0c;与CPU无法匹配&#xff0c;如果采用程序查询的方式需要CPU进行等待&#xff0c;但是如果在等待的过程中CPU可以执行其他的程序&#xff0c;可…

【@Param注解】| 台面使用——>底层原理分析

🐇 🐇 😄 🐇 🐇 🐇 🐇 😄 🐇 🐇 🐇 🐇 😄 🐇 🐇 🐇 🐇 😄 🐇 🐇 🐇 🐇 😄 目录 🦁 定义🦁 台面使用🦁 底层原理分析🦁 尾声🐇 🐇 😄 🐇 🐇 🐇 🐇 😄 🐇 🐇 🐇 🐇 😄 🐇 🐇 🐇 🐇 😄…

java实现乘法的方法

我们都知道&#xff0c;乘法运算的核心思想就是两个数相乘&#xff0c;如果能将乘法运算转化成一个加数的运算&#xff0c;那么这个问题就很容易解决。比如我们要实现23的乘法&#xff0c;首先需要定义两个变量&#xff1a;2和3。我们将这两个变量定义为一个变量&#xff1a;2x…

PySide6/PyQT多线程之 信号与槽 / (Signal Slot)的高效利用

前言 PySide6/PyQT信号槽是一种事件处理方式&#xff0c;允许程序中的对象发送和接收信号。 在 PySide6/PyQT 精进的过程中&#xff0c;一定躲不开 信号和槽 这座大山&#xff0c;这是一个比较有意思的知识点&#xff1a; 初接触的看不懂&#xff0c;觉得复杂&#xff1b;看得…

本地 WAF 已死,云 WAF 永生

多年来&#xff0c;Web 应用程序防火墙 (WAF) 一直是应用程序保护的代名词。事实上&#xff0c;许多应用程序安全团队认为保护其应用程序的最佳选择是一流的本地 WAF 解决方案&#xff0c;尤其是当这些应用程序部署在本地或私有云中时。 但自从引入本地 WAF 以来&#xff0c;…

JMeter的使用(二)

九、直连数据库 通过直连数据库让程序代替接口访问数据库&#xff0c;如果二者预期结果不一致&#xff0c;就找到了程序缺陷。 获取某条学院的名字&#xff0c;放在百度搜索: JMeter 不具备直连数据库功能&#xff0c;必须整合第三方(jar包)实现配置数据库的连接通过JDBC Re…

@PostConstruct注解和@PreDestroy注解

前言 Bean注解指定初始化和销毁的方法&#xff0c;也介绍了使用InitializingBean和DisposableBean来处理bean的初始化和销毁。JDK中还提供了两个注解能够在bean创建完成并且属性赋值完成之后执行一些初始化工作和在容器销毁bean之前通知我们进行一些清理工作。 1.PostConstru…

LDAP概念和原理介绍

LDAP概念和原理介绍 相信对于许多的朋友来说&#xff0c;可能听说过LDAP&#xff0c;但是实际中对LDAP的了解和具体的原理可能还比较模糊&#xff0c;今天就从“什么是LDAP”、“LDAP的主要产品”、“LDAP的基本模型”、“LDAP的使用案例”四个方面来做一个介绍。 我们在开始…

有什么牌子台灯性价比高?性价比最高的护眼台灯

由心感叹现在的孩子真不容易&#xff0c;学习压力比我们小时候大太多&#xff0c;特别是数学&#xff0c;不再是简单的计算&#xff0c;而更多的是培养学生其他思维方式&#xff0c;有时候我都觉得一年级数学题是不是超纲了。我女儿现在基本上都是晚上9点30左右上床睡觉&#x…

自动拣货仓库亮灯方案

方案目标概叙&#xff1a; 系统在美团平台下单后&#xff0c;骑手会收到取货码&#xff0c;凭借取货码到指定的智能仓库去取货&#xff0c;仓库标签系统调取相应订单信息&#xff0c;执行亮灯指令&#xff08;屏幕显示订单信息及拣货数量&#xff0c;并亮灯&#xff09;&#…

【MySQL】存放页面的大池子——InnoDB的表空间

概念&#xff1a; 页&#xff1a; 是InnoDB存储引擎管理数据库的最小磁盘单位&#xff0c;一个页的大小一般是16KB。一次至少读取一页的数据到内存&#xff0c;或者刷新一页的数据到磁盘。数据页&#xff1a;FIL_PAGE_INDEX类型的页&#xff0c;B树中的节点就是数据页。区&…

Elasticsearch --- 索引库、文档操作

一、索引库操作 索引库就类似数据库表&#xff0c;mapping映射就类似表的结构。 我们要向es中存储数据&#xff0c;必须先创建“库”和“表”。 1.1、mapping映射属性 mapping是对索引库中文档的约束&#xff0c;常见的mapping属性包括&#xff1a; type&#xff1a;字段数据…

标准ACL配置

标准ACL配置 【实验目的】 掌握标准ACL的配置。 验证配置。 【实验拓扑】 实验拓扑如图1所示。 图1 实验拓扑 设备参数如表所示。 表1 设备参数表 设备 接口 IP地址 子网掩码 默认网关 R1 S0/3/0 192.168.1.1 255.255.255.252 N/A Gi0/0/0 192.168.2.1 255.…

js判断是否为null,undefined,NaN,空串或者空对象

js判断是否为null&#xff0c;undefined&#xff0c;NaN&#xff0c;空串或者空对象 这里写目录标题 js判断是否为null&#xff0c;undefined&#xff0c;NaN&#xff0c;空串或者空对象特殊值nullundefinedNaN空字符串&#xff08;""&#xff09;空对象&#xff08;…

mysql实现存在则保存,不存在则更新

方式1 ON DUPLICATE KEY UPDATE 使用前提&#xff1a;表必须配置唯一键或者主键&#xff0c;且保存的字段中包含该键【重点】 原理&#xff1a; ON DUPLICATE KEY UPDATE如果配合主键&#xff0c;存在数据a&#xff0c;新插入b&#xff0c;如果主键不冲突&#xff0c;会保存b…

分布式监控平台-Zabbix

分布监控平台-Zabbix 一、Zabbix概述1、Zabbix是什么&#xff1f;2、Zabbix监控原理 二、部署Zabbix服务端&#xff08;端口&#xff1a;10051&#xff09;1、关闭防火墙 修改主机名2、获取Zabbix下载资源3、安装SCL(Software Collections)&#xff0c;修改 Zabbix-front 前端源…

Analysis For Office的一些使用技巧

目录 1. 自由特性下钻停止刷新 2. 直接双击过滤内容 3.重复层级值 4. 从过滤值选参数 5.从Excel复制参数 6. 保存参数值 7.计划值回退到上一步 8. 保存当前导航步骤 1. 自由特性下钻停止刷新 一般我们每次拖一个自由特性到workbook里&#xff0c;报表都会自动刷新。如…