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

Cesium源码解析六(3dtiles属性获取、建筑物距离计算、建筑物着色及其原理分析)

快速导航

Cesium源码解析一(搭建开发环境)
Cesium源码解析二(terrain文件的加载、解析与渲染全过程梳理)
Cesium源码解析三(metadataAvailability的含义)
Cesium源码解析四(metadata元数据拓展中行列号的分块规则解析)
Cesium源码解析五(Quantized-Mesh(.terrain)格式文件在CesiumJS和UE中加载情况的对比)
Cesium源码解析六(3dtiles属性获取、建筑物距离计算、建筑物着色及其原理分析)

目录

  • 快速导航
  • 前言
  • 1.代码示例
  • 2.属性获取原理分析
  • 3.建筑物距离计算原理分析
  • 4.建筑物着色原理分析
  • 5.总结

前言

  在本文中,我们将探讨如何使用 CesiumJS 来加载和显示 3D 建筑物数据,并根据用户点击的位置进行动态着色。我们将使用 CesiumJS 的 OpenStreetMap 建筑物数据集,通过点击地图上的建筑物,根据距离计算并动态地为这些建筑物着色。这不仅增强了地图的交互性,还为用户提供了直观的地理空间数据可视化体验。我们将逐步讲解如何设置 Cesium Viewer,加载 3D 建筑物数据,处理用户点击事件,以及根据距离进行建筑物的颜色处理。希望通过本文,您能深入理解 CesiumJS 的强大功能,并能够在自己的项目中应用这些技术。

1.代码示例

// 创建一个Cesium Viewer实例,指定目标DOM元素的id为 "cesiumContainer"
var viewer = new Cesium.Viewer("cesiumContainer", {baseLayerPicker: false,  // 禁用基础图层选择器
});// 创建一个事件处理器,用于处理屏幕空间事件(如点击、拖动)
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);// 创建OpenStreetMap(OSM)建筑物的3D模型
var osmBuildings = Cesium.createOsmBuildings();// 将OSM建筑物添加到场景的primitives集合中
viewer.scene.primitives.add(osmBuildings);// 设置相机视图,定位到指定的经纬度(西雅图附近)和高度
viewer.scene.camera.setView({destination: Cesium.Cartesian3.fromDegrees(-122.3472, 47.598, 370),orientation: {heading: Cesium.Math.toRadians(10), // 方向(水平旋转角度)pitch: Cesium.Math.toRadians(-10)   // 倾斜(垂直旋转角度)}
});// 定义一个函数,用于获取和打印特征的属性
function getFeatureProperty(feature) {let names = feature.getPropertyNames();  // 获取特征属性的名称数组for (var i = 0; i < names.length; i++) {var prop = feature.getProperty(names[i]);  // 获取每个属性的值if (prop) console.log(names[i], prop);     // 打印属性名称和值}
}// 定义一个函数,用于根据距离着色
function showByDistance() {colorByDistanceToCoordinate(47.62051, -122.34931);  // 默认根据指定经纬度着色// 内部函数处理点击事件function move(movement) {viewer.selectEntiy = undefined;var pickBuilding = viewer.scene.pick(movement.position);  // 获取点击位置的建筑物if (pickBuilding) {getFeatureProperty(pickBuilding);  // 获取点击建筑物的属性var latitude = pickBuilding.getProperty("cesium#latitude");var longitude = pickBuilding.getProperty("cesium#longitude");colorByDistanceToCoordinate(latitude, longitude);  // 根据点击的建筑物位置进行着色}}// 设置鼠标左键点击事件的处理函数handler.setInputAction(move, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}// 定义一个函数,根据指定经纬度着色建筑物
function colorByDistanceToCoordinate(pickLatitude, pickLongitude) {osmBuildings.style = new Cesium.Cesium3DTileStyle({defines: {// 定义着色器中的distance变量,计算每个建筑物与指定坐标的距离distance: "distance(vec2(${feature['cesium#longitude']},${feature['cesium#latitude']})," + `vec2(${pickLongitude},${pickLatitude}))`},color: {conditions: [["${distance} > 0.014", "color('blue')"],  // 大于0.014的距离,颜色为蓝色["${distance} > 0.010", "color('green')"], // 大于0.010的距离,颜色为绿色["${distance} > 0.006", "color('yellow')"],// 大于0.006的距离,颜色为黄色["${distance} > 0.0001", "color('red')"],  // 大于0.0001的距离,颜色为红色["true", "color('white')"],                // 其他距离,颜色为白色]}});
}
// 定义一个函数,根据距离渲染建筑物
function showByDistance() {// 首先调用 colorByDistanceToCoordinate,以特定坐标(47.62051, -122.34931)为参考点进行初始着色colorByDistanceToCoordinate(47.62051, -122.34931);// 定义一个内部函数 move 用于处理点击事件function move(movement) {viewer.selectEntiy = undefined;  // 清除当前选择的实体// 获取点击位置的建筑物特征var feature = viewer.scene.pick(movement.position);if (feature) {  // 如果点击位置有建筑物特征getFeatureProperty(feature);  // 获取并打印该建筑物的属性// 获取建筑物的经度和纬度var latitude = feature.getProperty("cesium#latitude");var longitude = feature.getProperty("cesium#longitude");// 调用 colorByDistanceToCoordinate 以点击位置的建筑物为参考点重新着色colorByDistanceToCoordinate(latitude, longitude);}}// 设置鼠标左键点击事件的处理函数,将其与 move 函数绑定handler.setInputAction(move, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}// 调用 showByDistance 函数以启动初始着色和点击事件处理
showByDistance();

2.属性获取原理分析

  当我们点击一个建筑物时,Cesium会自动展示这个建筑物的信息。我们也在控制台输出一下自己获取到的属性信息,看看能不能对应的上。
在这里插入图片描述
在这里插入图片描述
  可以看到完全对应的上。而当我们看下源码就会发现属性获取的调用过程如下:
sequenceDiagram
   participant User as 用户
   participant Scene as Cesium.Scene
   participant Handler as ScreenSpaceEventHandler
   participant Feature as Cesium3DTileFeature
   participant BatchTable as Cesium3DTileBatchTable

User->>Handler: 点击事件
Handler->>Scene: pick(movement.position)
Scene-->>Handler: 返回Cesium3DTileFeature
Handler->>Feature: 获取属性名
Feature->>BatchTable: getPropertyNames()
BatchTable-->>Feature: 返回属性名数组
Feature-->>Handler: 返回属性名数组
Handler->>Feature: 获取属性值(name)
Feature->>BatchTable: getProperty(batchId, name)
BatchTable-->>Feature: 返回属性值
Feature-->>Handler: 返回属性值
Handler-->>User: 打印属性名和值

3.建筑物距离计算原理分析

  在CesiumJS 中,建筑物之间的距离计算是通过 GLSL 着色器来实现的,计算每个建筑物与一个参考点之间的欧几里得距离。以下是距离计算的步骤:

  1. 定义距离计算表达式

    defines: {distance: "distance(vec2(${feature['cesium#longitude']}, ${feature['cesium#latitude']}), vec2(" + `${pickLongitude}, ${pickLatitude}))`
    }
    
    • defines 部分定义了 GLSL 表达式,用于计算每个建筑物与参考点的距离。
    • distance 是 GLSL(OpenGL Shading Language)中的函数,用于计算两个二维向量(坐标)之间的欧几里得距离。
    • vec2 是 GLSL 中表示二维向量的构造函数。
    • ${feature['cesium#longitude']}${feature['cesium#latitude']} 分别表示建筑物的经度和纬度。
    • ${pickLongitude}${pickLatitude} 表示参考点(如用户点击位置)的经度和纬度。
  2. 计算距离

    GLSL 表达式 distance 计算每个建筑物的位置与参考点之间的距离。这个距离值将用于后续的颜色条件判断。

    float distance = distance(vec2(buildingLongitude, buildingLatitude), vec2(referenceLongitude, referenceLatitude));
    
  3. 应用距离值

    这个计算的距离值会被应用到每个建筑物,用于在着色器中进行条件判断,决定建筑物的颜色。

    osmBuildings.style = new Cesium.Cesium3DTileStyle({defines: {distance: "distance(vec2(${feature['cesium#longitude']}, ${feature['cesium#latitude']}), vec2(" + `${pickLongitude}, ${pickLatitude}))`}
    });
    

4.建筑物着色原理分析

  在 CesiumJS 中,建筑物的着色是基于计算出的距离,并通过条件语句来设置颜色的。在 Cesium3DTileStyle中定义颜色条件,根据计算出的距离为建筑物设置颜色。

osmBuildings.style = new Cesium.Cesium3DTileStyle({defines:{distance:"distance(vec2(${feature['cesium#longitude']},${feature['cesium#latitude']}),"+`vec2(${pickLongitude},${pickLatidude}))`},color:{conditions:[["${distance} > 0.014","color('blue')"],["${distance} > 0.010","color('green')"],["${distance} > 0.006","color('yellow')"],["${distance} > 0.0001","color('red')"],["true","color('white')"],]}
})
  1. 定义部分

    • defines 部分定义了 GLSL 表达式,用于计算每个建筑物与参考点的距离。
    • distance 函数使用建筑物的经纬度和参考点的经纬度,计算欧几里得距离。
  2. 颜色条件部分

    • color 部分定义了颜色条件,根据 distance 值设置不同的颜色。
    • 使用条件数组 conditions,依次匹配 distance 的值,并根据匹配的条件设置颜色。

这两个原理共同作用,为用户提供了一个动态且交互的建筑物着色效果,根据点击的位置和距离进行直观的展示。

5.总结

  本文中我们通过代码示例展示了如何在Cesiumjs中对3dtiles进行属性获取、建筑物距离计算、建筑物着色及其原理分析,深入的理解了其原理,回见~

相关文章:

Cesium源码解析六(3dtiles属性获取、建筑物距离计算、建筑物着色及其原理分析)

快速导航 Cesium源码解析一&#xff08;搭建开发环境&#xff09; Cesium源码解析二&#xff08;terrain文件的加载、解析与渲染全过程梳理&#xff09; Cesium源码解析三&#xff08;metadataAvailability的含义&#xff09; Cesium源码解析四&#xff08;metadata元数据拓展…...

AI 情感聊天机器人之旅 —— 相关论文调研

开放域闲聊场景 Prompted LLMs as Chatbot Modules for Long Open-domain Conversation 发布日期&#xff1a;2023-05-01 简要介绍&#xff1a;作者提出了 MPC&#xff08;模块化提示聊天机器人&#xff09;&#xff0c;这是一种无需微调即可创建高质量对话代理的新方法&…...

WPF Prism框架搭建

WPF Prism框架搭建 1.引入Prism框架 在Nuget包管理器中搜索Prism&#xff0c;并添加到项目中 2.在项目中使用prism框架 2.1 修改app.xaml 删除项目中自带的StartupUri 修改Application节点为prism:PrismApplication 引入prism命名空间 <prism:PrismApplication x:C…...

MyBatisplus使用报错--Invalid bound statement

报错如下 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.lotus.mybatis.mapper.UserMapper.selectListat org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235)at com.baomidou.mybatisplus.cor…...

QT-QPainter实现一个动态充电的电池

1、效果 2、核心代码 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer>...

【云原生】Kubernetes----Metrics-Server组件与HPA资源

目录 引言 一、概述 &#xff08;一&#xff09;Metrics-Server简介 &#xff08;二&#xff09;Metrics-Server的工作原理 &#xff08;三&#xff09;HPA与Metrics-Server的作用 &#xff08;四&#xff09;HPA与Metrics-Server的关系 &#xff08;五&#xff09;HPA与…...

模拟原神圣遗物系统-小森设计项目,设计圣遗物(生之花,死之羽,时之沙,空之杯,理之冠)抽象类

分析圣遗物 在圣遗物系统&#xff0c;玩家操控的是圣遗物的部分 因此我们应该 物以类聚 人与群分把每个圣遗物的部分&#xff0c;抽象出来 拿 生之花&#xff0c;死之羽为例 若是抽象 类很好的扩展 添加冒险家的生之花 时候继承生之花 并且名称冒险者- 生之花 当然圣遗物包含…...

仿真模拟--telnet服务两种认证模式(自作)

自己做的笔记,有问题或看不懂请见解一下~ 目录 两个路由器间实现telnet服务(password认证模式) server client 两个路由器间实现telnet服务(aaa认证模式) server client 改名 tab键补齐 不会就扣问号 ? save 两个路由器间实现telnet服务…...

Apple Phone Memory

Apple Phone Memory 苹果手机内存查询&#xff0c;哪些应用程序&#xff08;app&#xff09;占用内存&#xff1a; 设置 通用 iPhone储存空间 清理下QQ音乐&#xff1a;...

Kubernetes容器运行时:Containerd vs Docke

容器化技术笔记 Kubernetes容器运行时&#xff1a;Containerd vs Docke - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this arti…...

【java 线程的状态】

介绍 Java 线程在运⾏的⽣命周期中的指定时刻只可能处于下⾯ 6 种不同状态的其中⼀个状态 状态名称说明NEW初始状态,线程被构建,但是还没有调用start()方法RUNNABLE运行状态,Java线程将操作系统中的就绪和运行两种状态统称为"运行中"BLOCKED阻塞状态,表示线程阻塞于…...

php加密验签

签名生成步骤&#xff08;小程序端/前端&#xff09;&#xff1a; 确定参与签名的参数&#xff1a;选择需要参与签名的请求参数&#xff0c;通常包括请求的时间戳、随机数、请求的数据等。 参数排序与拼接&#xff1a;将所有参与签名的参数按照字母顺序排序&#xff0c;并拼接成…...

【Golang - 90天从新手到大师】Day06 - 数组

系列文章合集 Golang - 90天从新手到大师 数组是golang中最常用的一种数据结构,数组就是同一类型数据的有序集合 定义一个数组 格式: var name [n]type n为数组长度,n>0 且无法修改,type为数组的元素类型如: var a [2]int上面的例子定义了一个长度为2,元素类型为int的数组…...

java的有参构造方法

java的有参构造方法和无参构造方法类似&#xff0c;区别是构造方法名称里后面跟着一个括号&#xff0c;括号里是参数的定义 示例代码如下 class student4{private String name;private int age;public student4(String n,int a) {namen;agea;System.out.println("调用了…...

Vue66-vue-默认插槽

一、默认插槽需求 1-1、原本的写法&#xff1a; 在每个category组件中用v-show来做条件渲染&#xff0c;但是不方便&#xff01; 1-2、默认插槽 img标签&#xff0c;ul标签&#xff0c;video标签&#xff0c;都是在app组件中完成解析之后&#xff0c;塞到category组件中的&…...

tsf-consul的使用

在腾讯云微服务平台TSF中使用Consul作为服务发现组件,通常需要遵循以下步骤: ### 1. 创建应用 首先,您需要在TSF控制台创建一个应用。在创建应用时,选择合适的业务类型、开发语言、开发框架等信息。对于使用Consul作为服务发现组件的Spring Cloud应用,您需要选择“业务应…...

【perl】基本语法 /备忘录/

分享 perl 语言学习资源 Perl 教程|极客教程 (geek-docs.com) Perl [zh] (runebook.dev) Perl 运算符 | 菜鸟教程 (runoob.com) Perl Documentation - Perldoc Browser Search the CPAN - metacpan.org 当然还有一些经典书籍&#xff0c;不再列举。 1、数字 1.1、数字表…...

mongodb 集群安装

整体架构图&#xff1a; 1. 配置域名 Server1&#xff1a; OS version: CentOS Linux release 8.5.2111 hostnamectl --static set-hostname mongo01 vi /etc/sysconfig/network # Created by anaconda hostnamemong01 echo "192.168.88.20 mong1 mongo01.com mongo…...

绿茶集团重启IPO:流量渐退、业绩波动,还能讲出好故事吗?

近日&#xff0c;绿茶集团有限公司(下称“绿茶集团”)向港交所递交上市申请&#xff0c;花旗、招银国际为其联席保荐人。 回望绿茶集团的上市之路&#xff0c;可谓有诸多坎坷。该公司于2021年3月首度向港交所发起冲击&#xff0c;但却将中文版招股书中的“流动负债总额”错写成…...

Git与SSH

Git Git是一种分布式版本控制系统&#xff0c;最初由Linus Torvalds为管理Linux内核开发而设计并开发。Git可以帮助开发团队协作管理代码&#xff0c;跟踪代码变更历史&#xff0c;并在需要时回溯到特定版本。 分布式版本控制&#xff1a;每个开发者都可以拥有完整的代码仓库…...

我的创作纪念日--码农阿豪

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…...

Git 学习笔记(超详细注释,从0到1)

Git学习笔记 1.1 关键词 Fork、pull requests、pull、fetch、push、diff、merge、commit、add、checkout 1.2 原理&#xff08;看图学习&#xff09; 1.3 Fork别人仓库到自己仓库中 记住2个地址 1&#xff09;上游地址&#xff08;upstream地址&#xff09;&#xff1a;http…...

GitLab项目组相关操作(创建项目组Group、创建项目组的项目、为项目添加成员并赋予权限)

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。 君不见,黄河之水天上来,奔流到海不复回。 君不见,高堂明镜悲白发,朝如青丝暮成雪。 ——《将…...

英语恶补ing

ing的词组都有停下来做某事的感觉了。 second hand是形容词了。 wouldnt buy这里的would是情态动词&#xff0c;也是助动词 助动词不能单独使用&#xff0c;要搭配实义动词&#xff0c;这样才能构成谓语 情态动词&#xff08;modals&#xff09;在英语中有多种作用&#xff…...

DS1339C串行实时时钟-国产兼容RS4C1339

RS4C1339串行实时时钟是一种低功耗的时钟/日期设备&#xff0c;具有两个可编程的一天时间报警器和一个可编程方波输出。地址和数据通过2线双向总线串行传输。时钟/日期提供秒、分钟、小时、天、日期、月份和年份信息。对于少于31天的月份&#xff0c;月末的日期会自动调整&…...

神经网络模型---LeNet-5

一、LeNet-5 1.定义LeNet-5模型 model models.Sequential([1.1添加一个二维卷积层&#xff0c;有6个过滤器&#xff0c;每个过滤器的尺寸是5x5。输入图像尺寸是28x28像素&#xff0c;具有1个颜色通道,激活函数是relu layers.Conv2D(6, (5, 5), activationrelu, input_shape…...

免费分享:1994-2020年中国各行业二氧化碳排放数据(附下载方法)

日前&#xff0c;国务院印发《2024—2025年节能降碳行动方案》针对重点领域进行部署&#xff0c;同时明确了制度标准、价格政策、资金支持、科技引领、市场化机制、全民行动等6项措施&#xff0c;为节能降碳提供支撑保障。1994-2020年中国各行业二氧化碳排放数据为评估环境政策…...

Qemu虚拟机在线迁移到VMware

libvirt版本&#xff1a;libvirt-10.0.0qemu版本&#xff1a;qemu-8.2.0 在生产环境中&#xff0c;大多数的场景是 vmware 虚拟机迁移到 qemu 环境&#xff0c;一般是通过关机然后导出、导入磁盘镜像来实现。 如果要将 qemu 环境虚拟机迁移到 vmware 怎么办呢&#xff1f;要求…...

计算机游戏因为d3dcompiler_47.dll丢失无法启动怎么办?解决只要d3dcompiler_47.dll丢失无法启动游戏软件的方法

d3dcompiler_47.dll 是一个动态链接库文件&#xff0c;属于 Microsoft DirectX 的一部分&#xff0c;主要负责编译和运行 3D 图形程序。它是支持 Direct3D 功能的核心组件&#xff0c;Direct3D 是一种用于编程 3D 图形的 API&#xff0c;广泛应用于游戏和图形密集型应用程序中。…...

LDO的原理及测试方法

一、基本结构 这是LM317芯片的核心,这个电路单元称为Bandgap Reference带隙基准源。属于模拟集成电路中的经典电路结构。 LDO拓扑结构图 常见的基本结构 利用VBE的负温度系数,而VT是正温度系数,正负温度系数抵消就的得到稳定的基准参考电压了(三极管的方程VBE=VT*In(lC/IS…...

提供信息门户网站定制/站长工具 站长之家

一个Cron-表达式是一个由六至七个字段组成由空格分隔的字符串&#xff0c;其中6个字段是必须的而一个是可选的&#xff0c;如下&#xff1a; 字段名允许的值允许的特殊字符秒0-59, - * /分0-59, - * /小时0-23, - * /日1-31, - * ? / L W C月1-12 or JAN-DEC, - * /周几1-7 o…...

路由器设置/抖音关键词排名优化软件

纵观历年来的中考数学卷&#xff0c;压轴题几乎都是与二次函数有关。今天郑老师为大家整理了二次函数与几何图形的综合题&#xff0c;希望对大家的复习有帮助。今天我们接着讲3题与面积有关的问题。例1(2018•黄冈)已知直线l&#xff1a;y&#xff1d;kx1与抛物线y&#xff1d;…...

艺术类网站模板/广州seo公司

JavaScript奇技淫巧之遍历数组 正常的for循环就不提了&#xff0c;直接进入正题。如下&#xff1a; 123456789//示例1for(var i0,a;a["jack","tom","lily","andy"][i];){console.log(a);}//示例2var ary ["jack","tom…...

南阳企业网站制作/深圳刚刚突然宣布

1、什么是五大学科竞赛 五大学科竞赛分别是数学、物理、化学、生物和信息学&#xff0c;竞赛分为市级、省级、国决和世界奥赛四个级别&#xff0c;竞赛生需要通过层层选拔才能最终站在世界舞台上。 2、参加五大学科竞赛的时间 黄金时期&#xff1a;高一高二&#xff08;尤其是…...

网络推广服务如何退费/东莞关键词排名快速优化

1.map标签 带有可点击区域的图像映射&#xff0c;一张图片可以有多个不同可点击区域&#xff0c;&#xff0c;每个区域点击后跳转页面不同 2.示例 <img src"./images/345.jpg" alt"" srcset"" usemap"#mp"><map name"mp…...

金融网站建设/google海外推广

一、 面向对象编程概述 类与对象的概念 类&#xff08;class&#xff09;与对象&#xff08;object&#xff09;是两种以计算机为载体的计算机语言的合称。类是对对象的抽象&#xff0c;对象是对客观事物的抽象。 它们二者的关系就是&#xff1a;类是对对象的抽象&#xff0c;…...