cesium学习记录09-turf.js的使用(画矩形结合地形生成三角网)

上一篇是绘制多边形,这一篇来说绘制矩形,但又因为只说绘制矩形太短了,所以就结合一下turf.js,生成一下地形三角网
Turf.js中文网

最终效果:

在这里插入图片描述
在这里插入图片描述

一、引入Turf.js

1,下载

npm install @turf/turf

2,引入

import * as turf from "@turf/turf";

二、鼠标绘制矩形区域

代码:

 //画矩形DrawRectangle() {var allPoints = [];// 设置返回值return new Promise((resolve, reject) => {let viewer = this.viewer;let topLeftPoint = null;let bottomRightPoint = null;let drawingRectangle = viewer.entities.add({id: "drawingRectangle",name: "画矩形",rectangle: {coordinates: new Cesium.CallbackProperty(() => {if (topLeftPoint === null || bottomRightPoint === null) {return;}let west = topLeftPoint.longitude;let north = topLeftPoint.latitude;let east = bottomRightPoint.longitude;let south = bottomRightPoint.latitude;return new Cesium.Rectangle(west, south, east, north);}, false),material: Cesium.Color.BLUE.withAlpha(0.2),closeTop: true,closeBottom: false}});let handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);handler.setInputAction(event => {var cartesian = this.getCatesian3FromPX(event.position);if (cartesian) {if (topLeftPoint === null) {topLeftPoint = Cesium.Cartographic.fromCartesian(cartesian);}viewer.entities.add({position: cartesian,point: {color: Cesium.Color.RED,pixelSize: 10}});}}, Cesium.ScreenSpaceEventType.LEFT_CLICK);handler.setInputAction(event => {if (topLeftPoint) {bottomRightPoint = Cesium.Cartographic.fromCartesian(this.getCatesian3FromPX(event.endPosition));}}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);handler.setInputAction(() => {if (topLeftPoint !== null && bottomRightPoint !== null) {handler.destroy(); // 关闭鼠标事件监听,结束绘制let west = Cesium.Math.toDegrees(topLeftPoint.longitude);let north = Cesium.Math.toDegrees(topLeftPoint.latitude);let east = Cesium.Math.toDegrees(bottomRightPoint.longitude);let south = Cesium.Math.toDegrees(bottomRightPoint.latitude);allPoints.push({ lng: west, lat: north });allPoints.push({ lng: east, lat: north });allPoints.push({ lng: east, lat: south });allPoints.push({ lng: west, lat: south });allPoints.push(allPoints[0]); // 闭合resolve(allPoints);}}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);});
},

(getCatesian3FromPX方法在上一篇)

效果:

在这里插入图片描述

代码说明:

函数定义和参数:

DrawRectangle() { … }: 这是定义DrawRectangle方法的部分

初始化变量:

var allPoints = [];: 初始化一个空数组,用于保存绘制的矩形的顶点坐标。
let topLeftPoint = null;: 初始化一个变量,用于存储矩形的左上角点。
let bottomRightPoint = null;: 初始化一个变量,用于存储矩形的右下角点。

Promise构造函数:

return new Promise((resolve, reject) => { … });: 返回一个新的Promise对象,用于处理异步操作。resolve和reject是两个回调函数,分别表示异步操作成功和失败的处理。

创建矩形Entity:

let drawingRectangle = viewer.entities.add({ … });: 用于在Cesium Viewer中添加一个新的矩形Entity。它使用CallbackProperty动态计算矩形的坐标。

创建事件处理器:

let handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);: 初始化一个新的Cesium屏幕空间事件处理器。

监听鼠标单击事件:

当用户在Cesium Viewer上单击鼠标左键时,这个事件会被触发。
if (topLeftPoint === null) { … }: 判断是否已经设置了矩形的左上角点。如果没有,则设置。

监听鼠标移动事件:

当用户在Cesium Viewer上移动鼠标时,这个事件会被触发。
if (topLeftPoint) { … }: 当左上角点设置后,根据鼠标的当前位置设置矩形的右下角点。
监听鼠标双击事件:

当用户在Cesium Viewer上双击鼠标左键时,这个事件会被触发。
当左上角和右下角点都被设置后,结束绘制,关闭鼠标事件监听。
handler.destroy(); 用于关闭鼠标事件监听,结束绘制。
计算出矩形的四个顶点的经纬度坐标,并将这些坐标点保存到allPoints数组中。
resolve(allPoints);: 最后,通过resolve函数将allPoints数组传递出去,表示异步操作成功完成。

总结:

这个DrawRectangle方法允许用户通过以下三个步骤在Cesium地图上绘制一个矩形:

单击地图以设置矩形的左上角点。
移动鼠标以实时预览矩形的形状。
双击地图以确认矩形的右下角点,并完成矩形的绘制。
方法返回一个Promise对象,当用户完成矩形的绘制后,这个Promise对象将被resolve,返回矩形的顶点坐标。

三、根据矩形区域生成点集

(resultPoints即上面矩形的顶点坐标返回值,num是手动穿的参数,当然数值越大点就越多了)

// 1. 创建一个矩形区域
// var rectangle = Cesium.Rectangle.fromDegrees(117.09649937089316, 36.20673458245797, 117.11797117691083, 36.230040948473906)
var rectangle = Cesium.Rectangle.fromDegrees(resultPoints[0].lng,resultPoints[2].lat,resultPoints[2].lng,resultPoints[0].lat)
// 2. 在这个矩形区域内生成点集
var width = num;  // 横向点数
var height = num; // 纵向点数
var terrainProvider =viewer.terrainProvider
var positions = [];
for (var y = 0; y < height; y++) {for (var x = 0; x < width; x++) {var longitude = Cesium.Math.lerp(rectangle.west, rectangle.east, x / (width - 1));var latitude = Cesium.Math.lerp(rectangle.south, rectangle.north, y / (height - 1));positions.push(Cesium.Cartographic.fromRadians(longitude, latitude));}
}

四、根据地形和区域为上述点集赋高度值

(这里的terrainProvider即地图加载的地形,我这里使用了cesium默认带的地形:viewer.terrainProvider = Cesium.createWorldTerrain({ requestVertexNormals: true, requestWaterMask: true });,参数terrainProvider即这里的viewer.terrainProvider。positions即上面的positions)

Cesium.sampleTerrainMostDetailed(terrainProvider, positions).then(function(samples) {var points = samples.map(function(sample) {return turf.point([Cesium.Math.toDegrees(sample.longitude), Cesium.Math.toDegrees(sample.latitude), sample.height],{ z: sample.height })  // 将高度值保存到名为 'z' 的属性中);});
//显示点集  
var cartesianPoints = points.map(function(point) {var coord = point.geometry.coordinates;var cartographic = Cesium.Cartographic.fromDegrees(coord[0], coord[1], coord[2]);return Cesium.Cartographic.toCartesian(cartographic);
});
var pointCollection = new Cesium.PointPrimitiveCollection();cartesianPoints.forEach(function(position) {
pointCollection.add({position: position,color: Cesium.Color.RED,pixelSize: 5
});
});
viewer.scene.primitives.add(pointCollection);})

(需要注意的是,//显示点集后面的添加点的代码在生成三角网是不必要的,只是我觉得看着好看一点 )
在这里插入图片描述

五、使用turf.js生成三角形网格

即将Cesium.sampleTerrainMostDetailed(terrainProvider, positions)方法里面改为:

代码:

Cesium.sampleTerrainMostDetailed(terrainProvider, positions).then(function(samples) {var points = samples.map(function(sample) {return turf.point([Cesium.Math.toDegrees(sample.longitude), Cesium.Math.toDegrees(sample.latitude), sample.height],{ z: sample.height })  // 将高度值保存到名为 'z' 的属性中);});// 创建一个FeatureCollection
var featureCollection = turf.featureCollection(points);
var tin = turf.tin(featureCollection, 'z');
var geometryInstances = [];  // 用于存放所有的三角形GeometryInstance
var instances = [];
// 遍历每个TIN三角形
tin.features.forEach(function(feature,i) {var coordinates = feature.geometry.coordinates[0];var heights = [feature.properties.a, feature.properties.b, feature.properties.c];var positions = coordinates.map(function(coord, index) {return Cesium.Cartesian3.fromDegrees(coord[0], coord[1], heights[index]);});viewer.entities.add({name: "三角面",id: "triangle"+i,polygon: {hierarchy: [positions[0], positions[1], positions[2]],heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,perPositionHeight: true,material: Cesium.Color.fromCssColorString("#23B8BA").withAlpha(1.0),//  extrudedHeight: 0,outline: true,outlineColor:  Cesium.Color.GREEN,}});
});var cartesianPoints = points.map(function(point) {var coord = point.geometry.coordinates;var cartographic = Cesium.Cartographic.fromDegrees(coord[0], coord[1], coord[2]);return Cesium.Cartographic.toCartesian(cartographic);});var pointCollection = new Cesium.PointPrimitiveCollection();cartesianPoints.forEach(function(position) {pointCollection.add({position: position,color: Cesium.Color.RED,pixelSize: 5});
});
viewer.scene.primitives.add(pointCollection);
})

在这里插入图片描述

代码说明:

函数定义和参数:

GeneratingTriangulation(resultPoints,num) { … }: 这是定义GeneratingTriangulation方法的部分,它接受两个参数:resultPoints是一个包含矩形四个顶点坐标的数组;num是横向和纵向的点数。

创建一个矩形区域:

var rectangle = Cesium.Rectangle.fromDegrees(…):根据resultPoints中提供的坐标,创建一个矩形区域。

在这个矩形区域内生成点集:

var positions = [];: 初始化一个空数组,用于保存生成的点集的坐标。
通过两个嵌套循环在矩形区域内均匀地生成点集。

获取点集的高程信息:

Cesium.sampleTerrainMostDetailed(terrainProvider, positions).then(function(samples) { … }:使用Cesium的sampleTerrainMostDetailed函数获取每个点的高程信息。

转换高程采样点为Turf.js点:

将Cesium高程采样点转换为Turf.js点格式,并保存每个点的高程(Z值)。

生成TIN三角网:

var tin = turf.tin(featureCollection, ‘z’);: 使用Turf.js的tin函数,基于点集和它们的Z值生成TIN三角网。

在Cesium地图上绘制TIN三角网:

通过遍历每个TIN三角形,并为每个三角形创建一个Cesium的polygon实体。这些多边形实体有高度信息,因此它们会按照地形进行渲染。

在Cesium地图上绘制点集:

遍历cartesianPoints(点集的笛卡尔坐标),并将它们作为点实体添加到地图上,这样可以在地图上可视化这些点。

注解:

Cesium.Rectangle.fromDegrees(…):这个函数创建一个矩形,参数是矩形的西、南、东、北边界的经纬度。
Cesium.sampleTerrainMostDetailed(terrainProvider, positions):这个函数从给定的地形服务提供商中采样最详细级别的地形数据,以获取指定位置的地形高程。
turf.tin(…):这个函数是Turf.js库中的一个函数,用于根据输入的点集生成TIN三角网。Turf.js是一个JavaScript库,用于地理空间分析。
这个方法最终的结果是在Cesium地图上绘制了一个TIN三角网,该三角网是根据指定的矩形区域和点数生成的。每个三角形都是一个单独的Cesium实体,并且这些实体的顶点高度是基于地形数据的。

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

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

相关文章

使用maven打包时如何跳过test,有三种方式

方式一 针对spring项目&#xff1a; <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skipTests>true</skipTests> </configuration> …

影响力再度提升,Smartbi多次蝉联Gartner、IDC等权威认可

近期&#xff0c;思迈特软件捷报频传&#xff0c;Smartbi凭借技术创新实力和产品能力&#xff0c;成功入选Gartner中国增强数据分析代表厂商及自助分析代表厂商&#xff0c;同时&#xff0c;连续三年蝉联“IDC中国FinTech 50”榜单。 Part.1 再次被Gartner提名 Smartbi深度融…

如何在控制台查看excel内容

背景 最近发现打开电脑的excel很慢&#xff0c;而且使用到的场景很少&#xff0c;也因为mac自带了预览的功能。但是shigen就是闲不住&#xff0c;想自己搞一个excel预览软件&#xff0c;于是在一番技术选型之后&#xff0c;我决定使用python在控制台显示excel的内容。 具体的需…

【数据库系统】-- 【1】DBMS概述

1.DBMS概述 01数据库系统概述02数据库技术发展概述03关系数据库概述04数据库基准测试 01数据库系统概述 几个基本概念 为什么使用数据库系统 数据库发展的辉煌历程 02数据库技术发展概述 数据模型 应用领域 ● OLTP ● OLAP ● HTAP ● GIS OLTP与OLAP 与其他技术相…

V2board缓存投毒漏洞复现

1.什么是缓存投毒 缓存投毒&#xff08;Cache poisoning&#xff09;&#xff0c;通常也称为域名系统投毒&#xff08;domain name system poisoning&#xff09;&#xff0c;或DNS缓存投毒&#xff08;DNS cache poisoning&#xff09;。它是利用虚假Internet地址替换掉域名系…

PHP-MD5注入

0x00 前言 有些零散的知识未曾关注过&#xff0c;偶然捡起反而更加欢喜。 0x01 md5 注入绕过 md5函数有两个参数&#xff0c;第一个参数是要进行md5的值&#xff0c;第二个值默认为false&#xff0c;如果为true则返回16位原始二进制格式的字符串。意思就是会将md5后的结果当…

使用qsqlmysql操作mysql提示Driver not loaded

环境: win10 IDE: qt creator 编译器: mingw32 这里简单的记录下。我遇到的情况是在IDE使用debug和release程序都是运行正常&#xff0c;但是当我编译成发布版本之后。老是提示Driver not load。 这就很奇诡了。 回顾了下编译的时候是需要在使用qt先编译下libqsqlmysql.dll的…

神经网络基础-神经网络补充概念-08-逻辑回归中的梯度下降算法

概念 逻辑回归是一种用于分类问题的机器学习算法&#xff0c;而梯度下降是优化算法&#xff0c;用于更新模型参数以最小化损失函数。在逻辑回归中&#xff0c;我们使用梯度下降算法来找到最优的模型参数&#xff0c;使得逻辑回归模型能够更好地拟合训练数据。 逻辑回归中的梯…

python selenium如何保存网站的cookie用于下次自动登录

## 一、python selenium如何保存网站的cookie 使用Selenium保存网站的Cookie非常简单。下面是一个示例&#xff0c;展示了如何使用Selenium打开网站&#xff0c;然后保存获取到的Cookie&#xff1a; from selenium import webdriver# 初始化浏览器 browser webdriver.Chrome…

正则表达式 —— Awk

Awk awk&#xff1a;文本三剑客之一&#xff0c;是功能最强大的文本工具 awk也是按行来进行操作&#xff0c;对行操作完之后&#xff0c;可以根据指定命令来对行取列 awk的分隔符&#xff0c;默认分隔符是空格或tab键&#xff0c;多个空格会压缩成一个 awk的用法 awk的格式…

【经典排序】—— “希尔排序”

插入排序希尔排序插入排序VS希尔排序 测试 希尔排序是在插入排序的基础上进行改进优化&#xff0c;所以学习希尔排序之前需要先了解插入排序。 插入排序 像玩扑克牌摸牌时一样&#xff0c;一张一张摸&#xff0c;每摸到一张插入到对应的位置&#xff0c;插入排序就是从第一个位…

大模型技术实践(一)|ChatGLM2-6B基于UCloud UK8S的创新应用

近半年来&#xff0c;通过对多款主流大语言模型进行了调研&#xff0c;我们针对其训练方法和模型特点进行逐一分析&#xff0c;方便大家更加深入了解和使用大模型。本文将重点分享ChatGLM2-6B基于UCloud云平台的UK8S实践应用。 01各模型结构及特点 自从2017年6月谷歌推出Transf…

NFTScan NFT API 在 DID Protocol 开发中的应用

自互联网发展以来&#xff0c;Web2.0 时代产生了网络社会&#xff0c;社会已经不再局限于地理边界&#xff0c;而 Web 3.0 引入了去中心化的理念&#xff0c;强调个体数据隐私和可信互操作性。在这个新的时代中&#xff0c;去中心化身份&#xff08;Decentralized Identifier 即…

vue3+vite配置vantUI主题

❓在项目中统一配置UI主题色&#xff0c;各个组件配色统一修改 vantUI按需安装 参考vantUI文档 创建vantVar.less文件夹进行样式编写 vantVar.less :root:root{//导航--van-nav-bar-height: 44px;//按钮--van-button-primary-color: #ffffff;--van-button-primary-backgr…

【Rust】Rust学习 第十一章编写自动化测试

Rust 是一个相当注重正确性的编程语言&#xff0c;不过正确性是一个难以证明的复杂主题。Rust 的类型系统在此问题上下了很大的功夫&#xff0c;不过它不可能捕获所有种类的错误。为此&#xff0c;Rust 也在语言本身包含了编写软件测试的支持。 编写一个叫做 add_two 的将传递…

FFmpeg 硬编码VideoToolBox流程

介绍 FFmpeg已经提供对 VideoToolBox 的编解码支持&#xff1b;主要涉及到的文件有videotoolbox.c、videotoolbox.h、videotoolboxenc.c、ffmepg_videotoolbox.c。在编译 FFmpeg 源码时&#xff0c;想要支持VideoToolBox&#xff0c;在 configure 时&#xff0c;需要–enable-…

激活函数总结(十一):激活函数补充(Absolute、Bipolar、Bipolar Sigmoid)

激活函数总结&#xff08;十一&#xff09;&#xff1a;激活函数补充 1 引言2 激活函数2.1 Absolute激活函数2.2 Bipolar激活函数2.3 Bipolar Sigmoid激活函数 3. 总结 1 引言 在前面的文章中已经介绍了介绍了一系列激活函数 (Sigmoid、Tanh、ReLU、Leaky ReLU、PReLU、Swish、…

第十三章 SpringBoot项目(总)

1.创建SpringBoot项目 1.1.设置编码 1.4.导入已有的spring boot项目 2.快速搭建Restfull风格的项目 2.1.返回字符串 RestController public class IndexController {RequestMapping("/demo1")public Object demo1() {System.out.println("demo1 ran...."…

2022年12月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题:数组逆序重放 将一个数组中的值按逆序重新存放。例如,原来的顺序为8,6,5,4,1。要求改为1,4,5,6,8。 输入 输入为两行:第一行数组中元素的个数n(1 输出 输出为一行:输出逆序后数组的整数,每两个整数之间用空格分隔。 样例输入 5 8 6 5 4 1 样例输出 1 4 5 6 8 以下是…

网络安全--linux下Nginx安装以及docker验证标签漏洞

目录 一、Nginx安装 二、docker验证标签漏洞 一、Nginx安装 1.首先创建Nginx的目录并进入&#xff1a; mkdir /soft && mkdir /soft/nginx/cd /soft/nginx/ 2.下载Nginx的安装包&#xff0c;可以通过FTP工具上传离线环境包&#xff0c;也可通过wget命令在线获取安装包…