three-tile开发: 5. 取得地图的地面信息

 three-tile 是一个开源的轻量级三维瓦片库,它基于threejs使用typescript开发,提供一个三维地形模型,能轻松给你的应用增加三维瓦片地图。

项目地址:GitHub - sxguojf/three-tile: 3D tile map using threejs

示例地址:GitHub - sxguojf/three-tile-example: three-tile Examples

接上节:https://blog.csdn.net/HZGJF/article/details/140414739

在地图操作中,我们常需要获取地图的地面信息,如鼠标拾取经纬度、点击放置物体到地面、测量某点距地高度等,一般使用threejs的射线法实现Raycaster – three.js docs (threejs.org),但因此类操作十分常用,three-tile对此功能进行了封装。

1. 射线法回顾和应用

 三维程序开发中,模型的拾取一般使用射线法,即由沿摄像机方向发出一条射线,计算射线与模型的交点,返回交点信息。

threejs提供Raycaster类来完成此过程,其实Raycaster类并不局限于沿摄像机发出射线,它可以从任意原点和方向发出,通过此特性,不仅能实现拾取,还能实现地面信息的测量。

Raycaster返回的交点包含如下信息:

distance —— 射线投射原点和相交部分之间的距离。
point —— 相交部分的点(世界坐标)
face —— 相交的面
faceIndex —— 相交的面的索引
object —— 相交的物体
uv —— 相交部分的点的UV坐标。
uv1 —— 相交部分的点的第二组UV坐标
normal - 交点处的内插法向量
instanceId – 与InstancedMesh物体相交时的instance索引

其中,最重要的为point属性,它包含了射线与模型的交点的世界坐标。当我们计算的是射线与地图模型的交点时,这点就是地面信息。

为了方便使用,three-tile对该交点进行扩展,增加了经纬度海拔高度属性location:

export interface LocationInfo extends Intersection {/** (经纬度海拔高度) */location: Vector3;
}

TileMap的几个成员函数均返回此类型

名称参数返回功能
getLocalInfoFromGeo(geo: Vector3)geo: 地理坐标(经纬度)LocationInfo:它继承于THREE.Intersection,除了交点信息,增加了location属性,包含地理坐标(经度、纬度、高度)通过射线法获取指定地理坐标的地面信息(法向量、高度等)
getLocalInfoFromWorld(pos: Vector3)pos: 世界坐标LocationInfo:它继承于THREE.Intersection,除了交点信息,增加了location属性,包含地理坐标(经度、纬度、高度)通过射线法获取指定世界坐标的地面信息(法向量、高度等)
getLocalInfoFromScreen(camera: Camera, pointer: Vector2)camera: 摄像机 ,pointer:屏幕坐标LocationInfo:它继承于THREE.Intersection,除了交点信息,增加了location属性,包含地理坐标(经度、纬度、高度)通过射线法获取指定屏幕坐标的地面信息(法向量、高度等)

2. 鼠标拾取地面信息

鼠标拾取使用TileMap.getLocalInfoFromScreen(),它通过传入摄像机和屏幕坐标取得地面信息。一般用于取得鼠标光标处的经纬度。

// 状态栏显示地理位置信息
export function showLocation(viewer: tt.plugin.GLViewer, map: tt.TileMap): void {const pointer = new Vector2();viewer.container.addEventListener("pointermove", (evt) => {pointer.x = (evt.clientX / viewer.renderer.domElement.clientWidth) * 2 - 1;pointer.y = -(evt.clientY / viewer.renderer.domElement.clientHeight) * 2 + 1;const info = map.getLocalInfoFromScreen(viewer.camera, pointer);if (info) {const dom = document.querySelector("#location")!;if (dom) {const lonlat = info?.location;dom.innerHTML = `${lonlat.x.toFixed(6)}°E, ${lonlat.y.toFixed(6)}°N, ${(lonlat.z * 1000).toFixed(0)}m, (${info.normal?.x.toFixed(2,)}, ${info.normal?.y.toFixed(2)}, ${info.normal?.z.toFixed(2)})`;}}});
}

3. 取得指定经纬度的地面信息

有的时候,我们需要向地面贴地放置一个模型,但仅知道它的经纬度,不想指定它的海拔高度,那可以用getLocalInfoFromGeo()取得指定经纬度的地面信息,然后将物体的position调整为返回的信息中的point,物体就贴地了。

4. 取得指定世界坐标的地面信息

还有一些情况,比如想在地上放一辆开动的汽车、放一个奔跑的人,它需要贴地运动,就可以在车、人运动过程中调用getLocalInfoFromWorld(),取得地面高度来调整模型的高度。

5. 其它应用

取得地面信息中,还包括normal成员,它是地面的法向量,即该点地面的朝向,通过它可以计算坡向、坡度等信息,这在一些测量类程序中十分有用。

6. 存在问题

three-tile的数据是动态加载的,如果瓦片没有加载就无法获取地面信息。所以使用时需要注意2点:

  1. 如果你在程序刚启动就取地面信息,会返回空。比如程序启动就取地面信息在上面放物体。
  2. 由于各级瓦片地形精度不一样,不同缩放倍数取得的地面高度也会大不一样。

为了避免上面两种情况的发生,可以在TileMap的loading-complete事件中获取并调整模型位置。loading-complete在每次瓦片加载完成发生。如果地图上模型很多,可能会影响程序性能,那只能是手工指定模型的高度。

本节介绍的几个函数实质上为threejs本身功能的再封装,熟悉threejs的完全可以自己写。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IT运维也有自己的节日 724向日葵IT运维节,三大版本如何选?

“724运维节”,是2016年由开放运维联盟发起倡议,广大运维人员共同投票产生的属于运维人自己的节日。 对于运维人最大的印象,那就是工作都需要7x24小时待命,是名副其实的“日不落骑士”,这也是大家选择724这一天作为运…

原理图大结局

一、总结哪些地方是5V供电?哪些地方是4V供电?哪些地方是3.3V供电?为什么会这样?根据什么原则来划分供电区域? 二、 5V 供电为什么有的地方要100uF+ 0.1uF 滤波?有的地方只要 10uF 滤波&#xff…

RabbitMQ - 延迟消息 - 死信交换机

目录 1、怎么理解延迟消息? 2、如何实现延迟消息? 2.1、方案一:死信交换机 2.1.1、什么是死信: 2.1.2、什么是死信交换机? 2.2、方案二:延迟消息插件 2.2.1、插件安装: 2.2.2、代码实现 …

AndroidStudio2023.3版本avd manager模拟器无法创建

创建到最后一步的时候提示WARN - #com.android.sdklib.internal.avd.AvdManager - com.android.prefs.AndroidLocationsException: Can’t locate Android SDK installation directory for the AVD .ini file. 前提: 1.sdk路径没问题 2.安装了下图内容 那是什么原因…

提高项目透明度:有效的跟踪软件

国内外主流的10款项目进度跟踪软件对比:PingCode、Worktile、Teambition、Tower、Asana、Trello、Jira、ClickUp、Notion、Liquid Planner。 在项目管理中,确保进度跟踪的准确性与效率是每位项目经理面临的主要挑战之一。选用合适的项目进度跟踪软件不仅…

【Python进阶】正则表达式、pymysql模块

目录 一、正则表达式的概述 1、基本介绍 2、快速使用re模块 二、正则的常见规则 1、匹配单个字符 2、原始字符串 3、匹配多个字符 4、匹配开头和结尾 5、匹配分组 三、Python与MySQL交互 1、pymysql模块的安装 2、pymysql的操作步骤 3、connection对象 4、cursor…

可重入锁深入学习(有码)

【摘要】 ​今天,梳理下java中的常用锁,但在搞清楚这些锁之前,先理解下 “临界区”。临界区在同步的程序设计中,临界区段活称为关键区块,指的是一个访问共享资源(例如:共享设备或是共享存储器&a…

6、evil box one

低—>中 目标:获取root权限以及2个flag 主机发现 靶机 192.168.1100.40 或者使用fping -gaq 192.168.100.1/24发现主机使用ping的方式。 端口扫描 发现开放了22和80 可以使用-A参数,-A参数会得到更多的扫描细节 访问80端口就是一个apache的基本的…

基于Python/MATLAB长时间序列遥感数据处理及在全球变化、植被物候提取、植被变绿与生态系统固碳分析、生物量估算与趋势分析应用

植被是陆地生态系统中最重要的组分之一,也是对气候变化最敏感的组分,其在全球变化过程中起着重要作用,能够指示自然环境中的大气、水、土壤等成分的变化,其年际和季节性变化可以作为地球气候变化的重要指标。此外,由于…

怎么安装Manim库在Windows环境下的Jupyter Notebook上

Manim 是解释性数学视频的动画引擎。 您可以使用它来制作数学视频(或其他字段)。也许你们会在有有些平台上会看过特别好看的数学动画,例如 3Blue1Brown等。这些动画特别好看,还特别丝滑,基本找不到太大的毛病。 我当初…

推荐 2 个 硬核的 AI 开源项目

01 AI 助手在你的终端中配对编程 Aider 由 Paul Gauthier 精心打造的开源AI配对编程工具,已经在GitHub上赢得了超过 12.8k 颗星星,人气爆棚! 这不仅仅是个工具,它是你在终端中的 AI 编程伙伴,帮你编辑存储在本地 Git 仓…

mavsdk_server安卓平台编译

1.下载好mavsdk并进入mavsdk目录 2.生成docker安卓平台文件 docker run --rm dockcross/android-arm64 >./dockcross-android-arm64 3.生成makefile ./dockcross-android-arm64 cmake -DCMAKE_BUILD_TYPERelease -DBUILD_MAVSDK_SERVERON -DBUILD_SHARED_LIBSOFF -Bbuild/…

JS进阶-异常处理

学习目标&#xff1a; 掌握异常处理 学习内容&#xff1a; throw抛异常try/catch捕获异常debugger throw抛异常&#xff1a; 异常处理是预估代码执行过程中可能发生的错误&#xff0c;然后最大程度的避免错误的发生导致整个程序无法继续运行。 <title>throw抛异常</…

前端面试题-怎样获取 url 地址栏 ? 后面的查询字符串,并以键值对形式放到对象里面

哈喽小伙伴们大家好!今天继续更新面试题系列文章 以百度为例&#xff1a; 我们以百度搜索掘金&#xff0c;url 为以下格式 https://cn.bing.com/search?q%E7%A8%80%E5%9C%9F%E6%8E%98%E9%87%91&formANNTH1&refig668f422a37c343b6b0f4ac940f65d043&pcEDGENTP&am…

免费的AI抠图工具 毫秒级抠图 离线可用 -鲜艺AI抠图

鲜艺AI抠图是一款免费的AI抠图工具&#xff0c;不登录、不联网&#xff0c;内嵌 AI 模型&#xff0c;快至毫秒级抠图&#xff0c;支持批量抠图&#xff0c;支持点击按钮选择图片、拖入图片、粘贴图片、粘贴图片链接、从网页拖入图片&#xff0c;支持Windows和macos&#xff0c;…

使用 NumPy 及其相关库(如 pandas、scikit-learn 等)时,由于 NumPy 的版本不兼容或者某些依赖库与 NumPy 的版本不匹配

题意&#xff1a; numpy.dtype size changed, may indicate binary incompatibility. Expected 96 from C header, got 88 from PyObject 问题背景&#xff1a; I want to call my Python module from the Matlab. I received the error: Error using numpy_ops>init thi…

戴尔inspiron如何独显直连?

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

解决安卓tv 蓝牙遥控器配对后输入法弹不出来的问题

t972在蓝牙配对后&#xff0c;自带的LatinIME 输入法会出现弹不出来的现象。 经过分析&#xff0c;主要为蓝牙的kl 文件适配存在问题。解决如下&#xff1a; 1.新建 kl文件 这个需要结合选用的遥控器来设定名称&#xff0c;我这边的遥控器是按照如下配置的 Vendor_2b54_Pr…

用户登陆实现前后端JWT鉴权

目录 一、JWT介绍 二、前端配置 三、后端配置 四、实战 一、JWT介绍 1.1 什么是jwt JWT&#xff08;JSON Web Token&#xff09;是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;用于在各方之间以安全的方式传输信息。JWT 是一种紧凑、自包含的信息载体&…

【Android面试八股文】组件化在项目中有什么意义?

一、没有组件化会出现什么问题? 早期的单一分层模式 问题一:无论分包怎么做,随着项目增大,项目失去层次感,后面接手的人扑街问题二:包名约束太弱,稍有不注意,就会不同业务包直接互相调用,代码高耦合问题三:多人开发在版本管理中,容易出现代码覆盖冲突等问题二、组件…