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

news2024/12/23 5:37:41

上一篇是绘制多边形,这一篇来说绘制矩形,但又因为只说绘制矩形太短了,所以就结合一下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.coloradmin.cn/o/892376.html

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

相关文章

html(七)meta标签

一 meta标签 1、背景&#xff1a;发现自带某些请求头2、本文没有实际的生产应用场景,仅仅作为技术积累 ① meta标签含义 1、metadata: 元数据,是用于描述数据的数据,它不会显示在页面上,但是机器却可以识别2、应用场景&#xff1a; [1]、SEO搜索引擎优化[2]、定义页面使用…

React 调试开发插件 React devtools 的使用

可以在谷歌扩展应用商店里获取这个插件。如果不能访问谷歌应用商店&#xff0c;可以点此下载最新版 安装插件后&#xff0c;控制台出现 “Components” 跟 “Profiler” 菜单选项。 查看版本&#xff0c;步骤&#xff1a; 下面介绍 react devtools 的使用方式。 在 Component…

改进YOLO系列:1.添加SE注意力机制

添加SE注意力机制 1. SE注意力机制论文&#xff12;. SE注意力机制原理&#xff13;. SE注意力机制的配置&#xff13;.&#xff11;common.py配置&#xff13;.&#xff12;yolo.py配置&#xff13;.&#xff13;yaml文件配置 1. SE注意力机制论文 论文题目&#xff1a;Squee…

人工智能原理(10)

目录 一、进化计算 1、概述 2、进化算法搜索方式特点 二、遗传算法 1、遗传算法的基本原理 三、进化规划 1、标准进化规划 2、进化规划的基本技术 四、进化策略 1、进化策略及其改进 2、进化策略基本技术 一、进化计算 1、概述 进化计算包括遗传算法、进化规划、进…

安装IIS服务

什么是IIS服务 IIS&#xff08;Internet Information Services&#xff09;是微软公司开发的一款用于托管和管理Web应用程序的服务软件。IIS服务是一种在Windows操作系统上运行的Web服务器&#xff0c;它能够处理HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和HTT…

《Kubernetes部署篇:Ubuntu20.04基于外部etcd+部署kubernetes1.24.16集群(多主多从)》

一、架构图 如下图所示: 二、环境信息 1、部署规划 主机名K8S版本系统版本内核版本IP地址备注k8s-master-631.24.16Ubuntu 20.04.5 LTS5.15.0-69-generic192.168.1.63master节点 + etcd节点k8s-master-641.24.16Ubuntu 20.04.5 LTS5.15.0-69-generic192.168.1.64master节点 + …

【TA 挖坑02】RayMarching SDF 物体黏合

写在前面 由于实习和忙着论文很久没经营博客了&#xff0c;最近以各种方式收集到了一些想实现的效果&#xff0c;其中一个就是卡通云融合、变大变小、聚散收拢的效果如何实现的问题&#xff0c;这就不得不提搁置了很久的RayMarching... 挖坑&#xff01;整理一下有帮助的文章…

origin修改默认的字体等

因为默认是中文宋体&#xff0c;每次切换成英文尤其是希腊字母就很麻烦。 选择菜单栏的【设置】——【选项】点击。 弹出窗口中选择【文本字体】 设置成你需要的字体就好。 这里同样可以更改页面、图等的默认设置。 效果&#xff1a; 选择插入文字后&#xff0c;自动更改成…

PyQt5登录界面跳转

目录 1、设计ui界面 2、设计逻辑代码&#xff0c;实现登录界面跳转 3、结果 1、设计ui界面 设计后的ui界面 在这里可以设置密码不显示 这里可以设置快捷键 最后将ui界面转为py文件后获得的逻辑代码为&#xff1a;&#xff08;文件名为Login.py&#xff09; # -*- coding: u…

Windows上使用dump文件调试

dump文件 dump文件记录当前程序运行某一时刻的信息&#xff0c;包括内存&#xff0c;线程&#xff0c;线程栈&#xff0c;变量等等&#xff0c;相当于调试程序时运行到某个断点上&#xff0c;把程序运行的信息记录下来。可以通过Windbg打开dump&#xff0c;查看程序运行的变量…

DispatcherServlet doDispatch()方法解析(1)

目录 简介doDispatch() 源码解析this.mappingRegistry 简介 在DispatcherServlet类中, 最关键的就是doDispatch()这个方法, 每一次请求都需要经过这个方法, 对每个请求进行转发, 通过反射调用对应的方法 doDispatch() 源码解析 可以看到最关键的代码就是1047行, 根据请求对象…

Python规范

PEP8 风格指南&#xff1a; 缩进&#xff0c;用 4 个空格&#xff0c;不要用制表符。(Python 不允许混合制表符和空格进行缩进。)换行&#xff0c;一行不超过 79 个字符。用空行分隔函数和类&#xff0c;及函数内较大的代码块。 用两个空行包围顶级函数和类定义。类内的方法定…

算法通关村第十关 | 数组中第k个最大元素

1.数组中第k大的数字 题目&#xff1a; LeetCode&#xff1a;数组中的第k个最大元素&#xff0c;给定整数数组nums和整数k&#xff0c;请返回数组中第k个最大的元素&#xff0c;请注意&#xff0c;你需要找的是数组排序后第k个最大的元素&#xff0c;而不是第k个不同的元素。 运…

【【STM32-SPI通信协议】】

STM32-SPI通信协议 STM32-SPI通信协议 •SPI&#xff08;Serial Peripheral Interface&#xff09;是由Motorola公司开发的一种通用数据总线 •四根通信线&#xff1a;SCK&#xff08;Serial Clock&#xff09;、MOSI&#xff08;Master Output Slave Input&#xff09;、MISO…

stm32F103R6实现流水灯参考源代码

#include "main.h" #include "gpio.h" void SystemClock_Config(void); void sleep(int a) {int i0,j0;for(i0;i<a;i){for(j0;j<2000;j);}} 真正发挥效果的是这个main函数// int main(void) {int i0;HAL_Init();SystemClock_Config();MX_GPIO_Init()…

4.UE数字人工程运行逻辑及程序逻辑

1.Fay-UE5数字人工程导入 2.UE数字人语音交互 3.UE基本操作及数字人工程模块组成&#xff08;UE数字人系统教程&#xff09; 一、3个状态&#xff1a;鸡汤广告、交互&#xff08;聊天与否&#xff09;、跳舞 1、启动即开始循环鸡汤广告模式 2、第一次交互&#xff08;助理版…

gromacs教程练习1

gromacs能在win上运行&#xff0c;还是个开源的软件&#xff0c;这都很值得入手学习 记录下gromacs教程的练习情况&#xff1a; Lysozyme in water 水中的溶菌酶&#xff0c;嗯&#xff0c;估计就是把蛋白处理后放在显试溶剂里跑MD这个模拟。 1、文件的准备&#xff1a; 1、…

JVM虚拟机:初始化的介绍

本文重点 我们前面学习了三个步骤: 装载 连接 初始化 初始化 初始化的时候,会为静态成员变量赋值初始值,它有两种方式: ①声明类变量是指定初始值 ②使用静态代码块为类变量指定初始值 例子 最后输出的结果为3,它的过程是这样的: main方法中输出T.count,由于count是…

产品经理如何提高用户画像效果?SIKT模型

产品经理做用户画像&#xff0c;最担心被业务方反馈&#xff1a;没效果。这往往是由用户画像与业务场景脱节造成的。那么我们该如何从业务场景出发&#xff0c;让用户画像更有效&#xff1f;一般来说&#xff0c;我们可以采用SIKT模型解决这个问题。 用户画像 ​ 1、SIK…

使用CLI添加磁盘到VM

登录 https://portal.azure.com/#home&#xff0c;点击右上角的控制台图标 &#xff0c;打开CLI 在控制台中输入如下指令&#xff0c;在NetworkWatcherRG创建一个名字为TEST的虚拟机&#xff0c;使用的镜像是Win2019datacenter&#xff0c;username是aaa,password是1234567890A…