当前位置: 首页 > news >正文

Cesium手动建模模型用Cesiumlab转3D Tiles模型位置不对,调整模型位置至指定经纬度

 Cesium加载3Dtiles模型的平移和旋转_3dtiles先旋转再平移示例-CSDN博客

Cesium 平移cesiumlab生产的3Dtiles切片模型到目标经纬度-CSDN博客

【ArcGIS+CityEngine】自行制作Lod1城市大尺度白膜数据_cityengine 生成指定坐标集指定区域的白模-CSDN博客

以上次ArcGIS+CityEngine制作的白膜为例:

 导出至FBX/OBJ

然后在CesiumLab中转化为3D Tiles模型

 但是发现模型位置不正确,默认位置在北京天安门上空,需要将模型调整至指定经纬度位置!!

起初以为只需做平移变化,平移至指定经纬度:

tileset.readyPromise.then(function() {// // 获取tileset的中心点坐标const boundingSphere = tileset.boundingSphereconst center = boundingSphere.center// 将中心点坐标转换为WGS84坐标系下的经纬度const cartographic = Cesium.Cartographic.fromCartesian(center)console.log(cartographic)const longitude = Cesium.Math.toDegrees(cartographic.longitude)const latitude = Cesium.Math.toDegrees(cartographic.latitude)const height = Cesium.Math.toDegrees(cartographic.height)// const startLon = 116.391005;// const startLat = 39.906623// 将经纬度调整为研究区域的经纬度const areaLongitude = 118.792930// const areaLongitude = 114.150301const areaLatitude = 31.9707912// 计算tileset的平移量,并将其应用到modelMatrix中const translation = Cesium.Cartesian3.fromDegrees(areaLongitude, areaLatitude)const centerNew = Cesium.Cartesian3.fromDegrees(longitude, latitude)const translationVector = Cesium.Cartesian3.subtract(translation, centerNew, new Cesium.Cartesian3())const translationMatrix = Cesium.Matrix4.fromTranslation(translationVector);console.log(translationMatrix)tileset.modelMatrix = translationMatrixviewer.zoomTo(tileset)})

 但是平移的结果存在问题!!!模型为倾斜的,发生旋转了,未贴地,需要调整!!!

why: 

在Cesium中,当你尝试在全局坐标系下直接平移3D Tiles数据时,可能会遇到模型变得不平(即模型的几何形状在视觉上扭曲或倾斜)的问题。这通常是因为平移操作没有考虑到原始模型与地球表面之间的相对位置关系

 

How: 

  1. 使用地球表面的局部坐标系
    尝试将平移操作转换为地球表面的局部坐标系中的移动。这通常涉及到计算目标位置与当前位置之间的地球表面距离,并沿着地球表面移动模型。然而,Cesium的API可能不直接支持这种操作,因此你可能需要实现一些自定义的逻辑。

  2. 调整模型矩阵以考虑地球曲率
    如果你直接在模型矩阵中设置平移,你需要确保这个平移是沿着地球表面的切线方向进行的,而不是简单地沿着全局坐标系的X、Y、Z轴。这可能需要你根据目标经纬度计算出一个合适的平移向量,该向量应该考虑到地球表面的曲率

Solution:

  1. 将模型平移回世界坐标系原点(地心)

  2. 将局部坐标Z轴调整到与世界坐标Z轴重合

  3. 将局部坐标X,Y轴调整到与世界坐标X,Y轴重合

  4. 将目标位置的eastNorthUp局部坐标系平移回世界坐标系原点(地心)

  5. 旋转物体坐标系与目标坐标系重合

  6. 平移到目标位置,即为最终变换矩阵

 理论基础:GAMES101 Lecture 04 Transformation Cont._哔哩哔哩_bilibili

function moveModel(tileset,longitude,latitude,height) {//计算世界坐标系中的目标位置offsetvar cartographic = new Cesium.Cartographic.fromCartesian(tileset.boundingSphere.center);var offset = Cesium.Cartesian3.fromDegrees(longitude,latitude,cartographic.height+height);//将模型位移至地心const origin = tileset.boundingSphere.center;const originMatrix = tileset.modelMatrix;//模型的初始变换矩阵const backToEarthCenter = new Cesium.Cartesian3(-origin.x,-origin.y,-origin.z);//初始位置到地心的位移向量let backToEarthCenterMatrix = Cesium.Matrix4.fromTranslation(backToEarthCenter);//初始位置到地心的变换矩阵Cesium.Matrix4.multiply(backToEarthCenterMatrix, originMatrix, backToEarthCenterMatrix);//移动模型到地心的矩阵// 旋转模型使得Z轴与世界坐标Z轴重合let arrowX = new Cesium.Cartesian3(1, 0, 0);let arrowZ = new Cesium.Cartesian3(0, 0, 1);let angleToXZ = Cesium.Cartesian3.angleBetween(arrowX, new Cesium.Cartesian3(origin.x, origin.y, 0));//局部Z轴在世界坐标系XY平面上投影到X轴角度,即绕Z顺时针旋转这个角度可以到XZ平面上let angleToZ = Cesium.Cartesian3.angleBetween(origin, arrowZ);//然后绕Y轴顺时针旋转此角度可使得Z轴与世界坐标系Z轴重合const rotationAngleToXZ = Cesium.Matrix3.fromRotationZ((origin.y>0?-1:+1)*angleToXZ);//绕Z轴旋转的Matrix3矩阵,正角度逆时针旋转const rotationAngleToZ = Cesium.Matrix3.fromRotationY(-angleToZ);//绕Y轴旋转的Matrix3矩阵,负角度顺时针旋转let rotationAngleToZMatrix = Cesium.Matrix3.multiply(rotationAngleToZ, rotationAngleToXZ, new Cesium.Matrix3);//连续旋转的Matrix3矩阵,即先绕Z轴旋转,后绕Y旋转的矩阵。rotationAngleToZMatrix = Cesium.Matrix4.fromRotationTranslation(rotationAngleToZMatrix);//连续旋转的Matrix4矩阵Cesium.Matrix4.multiply(rotationAngleToZMatrix, backToEarthCenterMatrix, rotationAngleToZMatrix);//将移动至地心模型,旋转至Z轴重合的矩阵// 旋转模型使得X,Y轴与世界坐标X,Y轴重合const rotationZ = Cesium.Matrix3.fromRotationZ(-Math.PI/2); // 绕Z轴旋转90°的Matrix3变换矩阵let rotationMatrix = Cesium.Matrix4.fromRotationTranslation(rotationZ); // 绕Z轴旋转90°的Matrix4变换矩阵Cesium.Matrix4.multiply(rotationMatrix, rotationAngleToZMatrix, rotationMatrix);//将移动至地心模型的物体坐标系,旋转到与世界坐标系重合的矩阵//在地心位置,旋转物体坐标系和世界坐标系重合的模型,使得与目标坐标系重合const offsetToWorldMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(offset);//获取到以目标位置为原点,的eastNorthUp局部坐标系的变换矩阵const backToEarthCenterOffset = new Cesium.Cartesian3(-offset.x, -offset.y, -offset.z);//目标位置到地心的位移向量let backToEarthCenterMatrixOffset = Cesium.Matrix4.fromTranslation(backToEarthCenterOffset);//目标位置到地心的变换矩阵Cesium.Matrix4.multiply(backToEarthCenterMatrixOffset, offsetToWorldMatrix, backToEarthCenterMatrixOffset);//获得从世界坐标系旋转至目标坐标系的旋转矩阵(只有旋转,没有位移)Cesium.Matrix4.multiply(backToEarthCenterMatrixOffset, rotationMatrix, backToEarthCenterMatrixOffset);//将移动至地心模型的物体坐标系,旋转到与目标坐标系重合的矩阵(完成模型的最终旋转,没有位移)//移动到目标位置const backToOriginMatrix = Cesium.Matrix4.fromTranslation(offset);//地心到目标位置位移向量const lastMatrix = Cesium.Matrix4.multiply(backToOriginMatrix,backToEarthCenterMatrixOffset,new Cesium.Matrix4());//最终矩阵,即将地心位置的模型移动到目标位置(完成模型的最终旋转,最终位移)console.log('最终变换矩阵',lastMatrix);return lastMatrix //返回最终变换矩阵
}
------------------------------------------------------------------------------------------
let tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({url: ".../tileset.json",}));tileset.readyPromise.then(function (tileset) {window.tileset = tilesetlet longitude = 104.98680let latitude = 32.20795let height = 100let modelMatrix = moveModel(tileset,longitude,latitude,height)tileset.modelMatrix = modelMatrix;//移动模型// 创建圆形包围盒let boundingSphere = new Cesium.BoundingSphere(tileset.boundingSphere.center,tileset.boundingSphere.radius);//飞向该包围盒viewer.camera.flyToBoundingSphere(boundingSphere);});

相关文章:

Cesium手动建模模型用Cesiumlab转3D Tiles模型位置不对,调整模型位置至指定经纬度

Cesium加载3Dtiles模型的平移和旋转_3dtiles先旋转再平移示例-CSDN博客 Cesium 平移cesiumlab生产的3Dtiles切片模型到目标经纬度-CSDN博客 【ArcGISCityEngine】自行制作Lod1城市大尺度白膜数据_cityengine 生成指定坐标集指定区域的白模-CSDN博客 以上次ArcGISCityEngine制…...

学习C语言第23天(程序环境和预处理)

1. 程序的翻译环境和执行环境 在ANSIC的任何一种实现中,存在两个不同的环境 第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。 第2种是执行环境,它用于实际执行代码。 2. 详解编译链接 2.1 翻译环境 每个源文件单独经过编…...

Ubuntu22.04安装

使用Vmware安装好后 首先执行下面命令,不然每次打开终端会出现To run a command as administrator (user root)… touch ~/.sudo_as_admin_successful换源 参考 sudo cp /etc/apt/sources.list /etc/apt/sources.list.baksudo gedit /etc/apt/sources.list清空…...

从入门到自动化:一篇文章掌握Python的80%

Python作为一种高级编程语言,以其简洁明了的语法和强大的功能性,在全球编程社区内享有极高的声誉。本文将带领你从Python的基础语法入手,介绍其常用库的应用,以及如何将Python用于数据分析、网络爬虫和简单的自动化任务&#xff0…...

开源的主流机器学习框架

主流的开源机器学习框架包括: 1. TensorFlow:由Google开发和维护的深度学习框架,广泛用于生产环境和研究。支持多种平台,并具有丰富的工具和库支持。 2. PyTorch:由Facebook开发的深度学习框架,以其动态计…...

RabbitMQ:发送者的可靠性之配置发送者重试机制

文章目录 为什么需要重试机制?如何配置重试机制?测试重试机制使用重试机制的注意事项 在使用消息队列(MQ)系统时,网络故障是不可避免的问题,尤其是在与RabbitMQ等服务交互时。如果生产者在发送消息时遇到网…...

基于深度学习的大规模MIMO信道状态信息反馈

MIMO系统 MIMO系统利用多个天线在发送端和接收端之间建立多条独立的信道,从而使得同一时间可以传输多个数据流,从而使得同一之间可以传输多个数据流,提高数据传输速率。 优势 增加传输速率和容量,提高信号覆盖范围和抗干扰能力…...

在Docker中部署Rasa NLU服务

最近因为项目需要将rasa nlu配置到docker容器中供系统调用,本篇主要整理该服务的docker配置过程。 本篇的重点在于docker的使用,不在Rasa NLU。 系统环境:Ubuntu 18.04.6 1. Rasa介绍 Rasa是一个开源的机器学习框架,专为构建基于文…...

SQL语句创建数据库(增删查改)

SQL语句 一.数据库的基础1.1 什么是数据库1.2 基本使用1.2.1 连接服务器1.2.2 使用案例 1.2 SQL分类 二.库的操作2.1 创建数据库2.2 创建数据库示例2.3 字符集和校验规则2.3.1 查看系统默认字符集以及校验规则2.3.2查看数据库支持的字符集2.3.3查看数据库支持的字符集校验规则2…...

微信小程序-Vant组件库的使用

一. 在app.json里面删除style:v2 为了避免使用Vant组件库和微信小程序组件样式的相互影响 二.在app.json里面usingComponents注册Vant组件库的自定义组件 "usingComponents": {"van-icon": "./miniprogram_npm/vant-weapp/icon/index&qu…...

为什么企业需要进行能源体系认证?

通过能源体系认证,企业可以向公众和利益相关方展示其在节能减排方面的承诺和成就。这不仅提升了企业的社会责任形象,还增强了品牌的信誉度。在当今消费者更加关注环境问题的背景下,绿色企业形象有助于赢得市场和客户的认可与信任。 能源体系认…...

【日常记录-MySQL】EVENT

Author:赵志乾 Date:2024-08-07 Declaration:All Right Reserved!!! 1. 简介 在MySQL中,EVENT是一种数据库对象,其用于设定数据库任务自动执行。这些任务可以是任意有效的SQL语句&a…...

嵌入式学习day12(LinuxC高级)

由于C高级部分比较零碎,各部分之间没有联系,所以学起来比较累,多练习就好了 一丶Linux起源 寻科普|第二期:聊聊Linux的前世今生 UNIX和linux的区别: (1)linux是开发源代码的自由软件.而unix是…...

pytorch中的hook机制register_forward_hook

上篇文章主要介绍了hook钩子函数的大致使用流程,本篇文章主要介绍pytorch中的hook机制register_forward_hook,手动在forward之前注册hook,hook在forward执行以后被自动执行。 1、hook背景 Hook被成为钩子机制,pytorch中包含forwa…...

使用Gin框架返回JSON、XML和HTML数据

简介 Gin是一个高性能的Go语言Web框架,它不仅提供了简洁的API,还支持快速的路由和中间件处理。在Web开发中,返回JSON、XML和HTML数据是非常常见的需求。本文将介绍如何使用Gin框架来返回这三种类型的数据。 环境准备 在开始之前&#xff0…...

网工内推 | 国企运维工程师,华为认证优先,最高年薪20w

01 上海陆家嘴物业管理有限公司 🔷招聘岗位:IT运维工程师 🔷岗位职责: 1、负责对公司软、硬件系统、周边设备、桌面系统、服务器、网络基础环境运行维护、故障排除。 2、负责对各部门软件操作、网络安全进行检查、指导。 3、负责…...

c# 使用异步函数实现线程的功能

c#程序执行时 想要拖动窗口 需要使用线程,但是使用线程 对操作前端窗体很不友好. 所以写了一个异步函数,网上搜了一下,貌似异步函数比线程 更加友好,更加现代 做这个功能的原因是 主要是想等程序执行完 走一个提示.用线程很难做到 using System; using System.Threading; usi…...

MySQL之MySQL server has gone away复现测试

测试MySQL server has gone away复现条件 环境情形一报错信息复现测试 情形二报错信息复现测试 环境 Python: 3.8/3.9 MySQL: 5.x 情形一 报错信息 File "/usr/local/lib/python3.6/dist-packages/MySQLdb/cursors.py", line 319, in _querydb.query(q)File "/…...

编程深水区之并发④:Web多线程

Node的灵感来源于Chrome,更是移植了V8引擎。在Node中能够实现的多线程,在Web环境中自然也可以。 一、浏览器是多进程和多线程的复杂应用 在本系列的第二章节,有提到现代浏览器是一个多进程和多线程的复杂应用。浏览器主进程统管全局&#xf…...

【实战指南】从提升AI知识库效果,从PDF转Markdown开始

经常有人抱怨AI知识库精确度不够、答非所问。我有时候想想,会觉得其实AI也挺冤的,因为很有可能不是它能力不行,而是你一开始给的文档就有问题,导致它提取文本有错误、不完整,那后边一连串的检索、生成怎么可能好呢&…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

线程同步:确保多线程程序的安全与高效!

全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

【Oracle】分区表

个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息&#xff0…...