一文讲解多种GIS分析功能

news2024/11/15 10:29:53

GIS行业有很多分析功能,对于刚入行的新手有着足够的吸引力,其实有许多分析功能实现原理大差不差,比如模型压平,基于模型的淹没分析以及模型裁切。本文将以模型裁切为切入口进行介绍其中原理。

首先

(立方体剖切示意图,图源:Mapmost SDK for WebGL)

在GIS行业中,诸多分析功能吸引着新手探索,而其中不乏原理相通之处,诸如模型压平、淹没分析与模型裁切等。以模型裁切为例,其核心在于利用空间分析技术,从复杂的地理实体中依据预定条件精准提取或裁切所需部分。这一过程涉及空间叠加运算,即确定数据集之间的空间关系,通过设定裁切边界来筛选目标区域,剔除非关注部分。相似地,模型压平是将局部模型扁平化,淹没分析预测水体上涨影响范围,皆围绕空间筛选与关系处理展开,虽应用场景各异,但均依托于GIS强大的空间分析引擎实现高效数据挖掘与可视化。对这些原理的掌握,将为GIS新手打下坚实基础。

通过剖析立方体剖切原理,本指南将启发现学者触类旁通,灵活运用此基础技法拓展至其他两项GIS分析功能实现,深入浅出解析空间分析精髓。

功能步骤拆解:

  1. 判定像素在立方体之内
  2. 在立方体之内则丢弃像素,否则正常渲染

对于第2点,glsl中提供了discard功能,用于丢弃当前像素。那么问题就只剩一个了,如何判定像素在立方体之内?

在OpenGL Shading Language (GLSL)中,准确判定像素是否位于立方体内部是一个涉及空间坐标变换与逻辑判断的关键过程。具体实现步骤可细分为下面两个步骤:

一、 坐标空间统一

首先,需要保证像素坐标与立方体顶点坐标处于同一个坐标系中,个人推荐是在模型本地坐标系下进行。这里简单回顾下MVP矩阵转换。MVP矩阵分别是模型(Model)、观察(View)、投影(Projection)三个矩阵。

GIS行业有很多分析功能,对于刚入行的新手有着足够的吸引力,其实有许多分析功能实现原理大差不差,比如模型压平,基于模型的淹没分析以及模型裁切。本文将以模型裁切为切入口进行介绍其中原理。

首先

(立方体剖切示意图,图源:Mapmost SDK for WebGL)

在GIS行业中,诸多分析功能吸引着新手探索,而其中不乏原理相通之处,诸如模型压平、淹没分析与模型裁切等。以模型裁切为例,其核心在于利用空间分析技术,从复杂的地理实体中依据预定条件精准提取或裁切所需部分。这一过程涉及空间叠加运算,即确定数据集之间的空间关系,通过设定裁切边界来筛选目标区域,剔除非关注部分。相似地,模型压平是将局部模型扁平化,淹没分析预测水体上涨影响范围,皆围绕空间筛选与关系处理展开,虽应用场景各异,但均依托于GIS强大的空间分析引擎实现高效数据挖掘与可视化。对这些原理的掌握,将为GIS新手打下坚实基础。

通过剖析立方体剖切原理,本指南将启发现学者触类旁通,灵活运用此基础技法拓展至其他两项GIS分析功能实现,深入浅出解析空间分析精髓。

功能步骤拆解:

  1. 判定像素在立方体之内
  2. 在立方体之内则丢弃像素,否则正常渲染

对于第2点,glsl中提供了discard功能,用于丢弃当前像素。那么问题就只剩一个了,如何判定像素在立方体之内?

在OpenGL Shading Language (GLSL)中,准确判定像素是否位于立方体内部是一个涉及空间坐标变换与逻辑判断的关键过程。具体实现步骤可细分为下面两个步骤:

一、 坐标空间统一

首先,需要保证像素坐标与立方体顶点坐标处于同一个坐标系中,个人推荐是在模型本地坐标系下进行。这里简单回顾下MVP矩阵转换。MVP矩阵分别是模型(Model)、观察(View)、投影(Projection)三个矩阵。

(MVP矩阵流程图,图源:https://blog.csdn.net/s178435865/article/details/131706248)

通常引擎中的片元着色器中都会有模型本地坐标系下的变量,形似:v_PositionMC,以及模型矩阵:u_ModelMatrix,因为需要把立方体中心点(世界坐标系)坐标转到模型本地坐标系下,实际上我们用到的是模型矩阵的逆矩阵,在验证技术链路时建议使用下面逆矩阵运算方法,验证通过后建议由JS提前运算,使用uniform参数传入,避免GPU计算资源浪费,因为JS计算只需要计算一次,片元计算是每一帧每一个像素都要调用下面方法,会造成计算资源浪费,下面是着色器代码进行矩阵逆运算方法:

mat4 inverse_mat4(mat4 m)
{
    float Coef00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
    float Coef02 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
    float Coef03 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
    
    float Coef04 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
    float Coef06 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
    float Coef07 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
    
    float Coef08 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
    float Coef10 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
    float Coef11 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
    
    float Coef12 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
    float Coef14 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
    float Coef15 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
    
    float Coef16 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
    float Coef18 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
    float Coef19 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
    
    float Coef20 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
    float Coef22 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
    float Coef23 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
    
    const vec4 SignA = vec4( 1.0, -1.0,  1.0, -1.0);
    const vec4 SignB = vec4(-1.0,  1.0, -1.0,  1.0);
    
    vec4 Fac0 = vec4(Coef00, Coef00, Coef02, Coef03);
    vec4 Fac1 = vec4(Coef04, Coef04, Coef06, Coef07);
    vec4 Fac2 = vec4(Coef08, Coef08, Coef10, Coef11);
    vec4 Fac3 = vec4(Coef12, Coef12, Coef14, Coef15);
    vec4 Fac4 = vec4(Coef16, Coef16, Coef18, Coef19);
    vec4 Fac5 = vec4(Coef20, Coef20, Coef22, Coef23);
    
    vec4 Vec0 = vec4(m[1][0], m[0][0], m[0][0], m[0][0]);
    vec4 Vec1 = vec4(m[1][1], m[0][1], m[0][1], m[0][1]);
    vec4 Vec2 = vec4(m[1][2], m[0][2], m[0][2], m[0][2]);
    vec4 Vec3 = vec4(m[1][3], m[0][3], m[0][3], m[0][3]);
    
    vec4 Inv0 = SignA * (Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2);
    vec4 Inv1 = SignB * (Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4);
    vec4 Inv2 = SignA * (Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5);
    vec4 Inv3 = SignB * (Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5);
    
    mat4 Inverse = mat4(Inv0, Inv1, Inv2, Inv3);
    
    vec4 Row0 = vec4(Inverse[0][0], Inverse[1][0], Inverse[2][0], Inverse[3][0]);
    
    float Determinant = dot(m[0], Row0);
    
    Inverse /= Determinant;
    
    return Inverse;
}

二、 立方体边界检验

通过两个变量定义立方体:中心点(u_center)以及长宽高尺寸(u_size),

通过把模型本地坐标减去立方体中心点坐标得到相对坐标,然后使用相对坐标对比立方体尺寸,如果相对坐标XYZ各自分量的绝对值都小于立方体尺寸,则判定像素是否在立方体之内,否则判定为立方体之外,伪代码如下:

// 模型本地坐标
varying vec3 v_PositionMC;
uniform mat4 u_ModelMatrix;
// 世界坐标系下的立方体中心坐标
uniform vec3 u_centerWC;
// 立方体尺寸
uniform vec3 u_size;
mat4 inverse_mat4(mat4 m)
{
    ...
    ...
}
void main() {
    vec3 centerMC = vec3(inverse_mat4(u_ModelMatrix) * vec4(u_centerWC, 1.0));
    vec3 offsetMC = v_PositionMC - centerMC;
    if (abs(offsetMC.x) <= u_size.x && abs(offsetMC.y) <= u_size.y && abs(offsetMC.z) <= u_size.z) {
        discard
    }
}

以上立方体剖切大致实现流程,在此基础上可以对立方体进行旋转,这时模型顶点也要做相应的旋转。当然了在GIS行业中,通常是使用geojson文件的不规则平面数据进行裁剪与压平等分析,这里给出思路:

  1. 使用正交投影相机,摆在面中心位置,绘制区域面到帧缓存(FBO),
  2. 然后当纹理传入着色器
  3. 片元着色器中计算片元相对于区域面中心点的坐标
  4. 使用相对坐标与区域面尺寸计算出UV
  5. 使用UV采样区域面纹理,如果有颜色判定为在区域面内,否则在区域外
  6. 然后对片元丢弃或者对顶点进行压平都可以,还有淹没分析也是如此

勇于探索引擎着色器及渲染管线的奥秘,意味着向技术巅峰迈出勇敢一步。内心的信念比眼前障碍更重要,每一步前行都是通往成功的坦途。这样的勇气与决心,正是铸就优秀开发者的基石。

参考文献:

https://blog.csdn.net/s178435865/article/details/131706248

https://www.cnblogs.com/crsky/p/6523780.html

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

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

相关文章

只需一个类文件,Erupt 可以能完成整个后台管理?这个低代码值得一试

只需一个类文件&#xff0c;Erupt 竟然能搞定整个后台管理&#xff1f;这个低代码值得一试 在纷繁复杂的后端开发世界里&#xff0c;Erupt 就像是一剂强心针&#xff0c;用一个 .class 文件就能实现后台管理功能&#xff0c;简直让人感叹“开发也可以这么简单&#xff01;”本文…

linux进程的概念和pid

进程的概念 进程是参与分配资源&#xff08;cpu&#xff0c;内存&#xff09;得实体&#xff0c;比如打开qq&#xff0c;浏览器就是打开了进程。 进程这么多&#xff0c;如何管理进程呢&#xff1f; 在linux下进程通过PCB&#xff08;task_struct&#xff09;来管理进程 ta…

足浴行业在线预约小程序源码系统+支持拼团功能 带完整的安装代码包以及搭建部署教程

系统概述 在快节奏的现代生活中&#xff0c;人们对健康养生的需求日益增长&#xff0c;足浴行业作为传统养生方式之一&#xff0c;其市场需求也随之不断扩大。为了满足消费者日益增长的便捷性需求&#xff0c;一款集在线预约、拼团优惠于一体的足浴行业小程序源码系统应运而生…

Vue/cli不同环境下打包后js文件没有添加hash值-会导致缓存问题-解决

环境变量 包文件判断是根据NODE_ENV=production,这时会对应打包加上hash值,所以在配置不同环境对应命令的时候,把NODE_ENV=production加上 全局的环境变量需要以VUE_APP_ 开头 process.env.VUE_APP_ENV 会读取不到值 .env 文件配置 NODE_ENV=production 才会按照hash模式去…

利用数据分析提升SEO排名的7种方法

我们都听过“大数据分析”这个词。科技让我们能够清晰地了解我们的活动和内容的表现——向我们提供了关于受众的宝贵信息&#xff0c;甚至可以精确到他们在Google和其他搜索引擎上使用的具体搜索词。 你已经在你的业务中使用数据分析了吗&#xff1f;如果是&#xff0c;你有利…

漏水监测报警摄像机

漏水监测报警摄像机 是一种智能设备&#xff0c;专门用于监测管道或设备的漏水情况&#xff0c;并能在检测到漏水时发出警报&#xff0c;帮助用户及时发现并处理水患。这种摄像机通常配备高清摄像头和敏感的水滴传感器&#xff0c;能够全天候地监测管道周围的情况。 当漏水摄像…

【ARM compiler】生成ELF文件中包含了那些内容

【更多软件使用问题请点击亿道电子官方网站】 文档目标&#xff1a;用于了解ARM compiler生成的ELF文件中存储的内容进行了解 问题场景&#xff1a;ELF文件主要用于通过调试软件对于代码的运行顺序和数据链接等内容进行分析。了解一下ARM compiler生成ELF文件包含那些内容。 软…

蓝牙--关于bta_av_main.cc文件的讲解

简单概要下: BTIF:提供bluedroid对外的接口 BTA:提供各种profile的实现 stack:协议实现与连接管理 上层在建立A2dp connect连接的时候,先调用到btif层的btif_av.cc中函数src_connect_sink,接着调用bta层bta_av_api.cc中函数BTA_AvOpen,经过内部state machine处理,最…

ROPS 自动化快速构造缓冲区溢出ROP链工具

项目地址:https://github.com/MartinxMax/ROPS ROPS 快速自动化构造ROP&#xff08;Return-Oriented Programming&#xff09;链的脚本&#xff0c;用于生成ROP攻击的有效载荷。 Usage $ ./rops.sh $ ./rops.sh /home/ayush/.binary/rop 该脚本将根据提供的二进制文件自动生…

【C语言数据结构】

一. 线性表 通俗的讲&#xff0c;线性表是具有相同特性的数据结构的集合 逻辑结构&#xff08;人为想象出来的数据的组织形式&#xff09;&#xff1a;都是线性的 物理结构&#xff08;数据在内存中的存储形式&#xff09;&#xff1a;不一定是线性的 二. 顺序表 顺序表是…

构建高效AI中台:解析人工智能中台架构的五大核心层

在人工智能技术蓬勃发展的今天&#xff0c;企业迫切需要一种高效、灵活的方式来整合、管理和应用AI技术。人工智能中台&#xff08;AI Middle Platform&#xff09;应运而生&#xff0c;它为企业提供了一个统一的技术平台&#xff0c;能够有效支撑多样化的业务需求&#xff0c;…

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础&#xff1a;WAV专题&#xff08;6&#xff09;——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道&#xff0c;通过FFprobe命令可以打印WAV音频文件每个packet&#xff08;也称为数据包或多媒体包&#xff09;的信息&#xff0…

无人机动力系统设计之桨叶推力计算

无人机动力系统设计之桨叶推力计算 1. 源由2. 关键参数2.1 特性参数2.1.1 材质&#xff08;Material&#xff09;2.1.2 叶片数量&#xff08;Number of Blades&#xff09;2.1.3 重量&#xff08;Weight&#xff09; 2.1.4 噪音水平&#xff08;Noise Level&#xff09;2.2 安装…

开敞式屋脊通风天窗,“0”差评厂房通风换气设备!

开敞式屋脊通风天窗作为常见的通风设备&#xff0c;在现代建筑设计中尤其是在工业厂房中扮演着重要角色。 开敞式屋脊通风天窗是安装在建筑屋顶屋脊位置且处于常开状态&#xff0c;没有安装启闭阀板的通风天窗。这种设计允许空气自由流通&#xff0c;无需依赖机械动力&#xff…

乱弹篇(46)白露闲谈

昨&#xff08;7日&#xff09;天11时11分&#xff0c;已经进入2024年的白露节气&#xff0c;今天本“人民体验官”推广人民日报官方微博文化产品《诗句里的秋天》&#xff0c;旨在提醒亲友已是“秋风何冽冽&#xff0c;白露为朝霜”时令&#xff0c;天气开始转凉&#xff0c;早…

AI模型应根据应用场景选择全能型或者专精型

文章目录 一、前言二、选择全能型2.1 优势2.2 劣势 三、选择专精型3.1 优势3.2 劣势 四、权衡选择五、总结 一、前言 AI模型的发展方向&#xff0c;在追求全能与专精之间并非简单的二选一&#xff0c;都取决于其应用场景、设计目标以及技术可行性等多个因素。这两种策略各有优…

CodeFormer——卓越的AI照片修复工具,能够轻松消除图片以及视频中的马赛克,还原清晰画质。

CodeFormer是什么 CodeFormer是一款由南洋理工大学和商汤科技联合开发的AI照片和视频修复工具。融合了变分自动编码器&#xff08;VQGAN&#xff09;和Transformer技术&#xff0c;对模糊和马赛克的照片或视频进行高质量的修复。CodeFormer通过先进的算法优化图像细节&#xf…

【软考中级攻略站】-软件设计师(5)- 软件工程

软件生存周期 什么是软件生存周期&#xff1f; 软件生存周期指的是一个软件从开始构思到最终停止使用&#xff08;或被替换&#xff09;的整个过程。就像人的生命一样&#xff0c;软件也有一个从出生到死亡的过程。 软件生存周期的几个阶段 软件生存周期通常可以分为以下几…

LabVIEW步进电机控制方式

在LabVIEW中控制步进电机可以通过多种方式实现。每种方法都有其独特的优缺点&#xff0c;适用于不同的应用场合。下面详细介绍几种常见的步进电机控制方式&#xff0c;并进行比较。 1. 开环控制&#xff08;Open-Loop Control&#xff09; 特点 通过定期发出脉冲信号来控制步进…

基于SSM的流浪动物管理系统的设计与实现82901

摘要 随着移动互联网的快速发展&#xff0c;小程序作为一种新型的应用形态&#xff0c;已经深入到人们的生活中。在高校中&#xff0c;实验室领养管理是一个重要的环节&#xff0c;但传统的领养方式存在着诸多问题&#xff0c;如领养流程繁琐、信息不透明等。因此&#xff0c;本…