使用Geotools从DEM数据中读取指定位置的高程实战
目录
前言
一、GridCoverage2D对象介绍
1、GridCoverage2D的属性
2、GridCoverage2D核心方法
3、GridCoverage2D中的高级操作
二、指定位置的高程获取
1、存储原理
2、相关属性的获取
3、获取高程的方法
三、总结
前言
在地理信息科学领域,高程数据是至关重要的基础信息之一。它广泛应用于地形分析、城市规划、土地管理、灾害预警与评估等多个重要方面。而数字高程模型(Digital Elevation Model,简称DEM)作为高程数据的主要载体,以数字化的形式精确记录了地表的高程信息,为我们理解和研究地球表面形态提供了有力支持。
随着地理信息系统的不断发展与普及,对DEM数据的高效处理和应用成为了众多科研工作者和工程技术人员关注的焦点。在实际项目中,常常需要从庞大的DEM数据集中快速准确地读取指定位置的高程值,以满足诸如地形剖面分析、建筑选址评估、洪水模拟等多样化的需求。在城市跑步或者骑行过程中,需要对路线进行高程变化的提取,用于规划路线的难易程度。在城市燃气的管道设计工作当中,根据城市的输气管道建设时,选择一条合理的路线,可以利用自然高程和重力的作用来实现能耗的降低。

Geotools作为一款功能强大且开源的地理工具库,为地理数据的处理和分析提供了丰富的类库和便捷的接口。它支持多种地理数据格式的读取与写入,具备完善的坐标转换功能以及空间分析能力,能够很好地满足从DEM数据中读取高程信息这一实战需求。通过运用Geotools,可以高效地实现对DEM数据的解析,精准定位到用户所需的地理坐标点,并快速获取该点的高程数据,为后续的地理信息分析和决策提供坚实的数据基础。
本实战内容将深入讲解如何利用Geotools这一强大工具,详细阐述从获取DEM数据到成功读取指定位置高程信息的全过程。包括对DEM数据格式的解析、Geotools环境的搭建与配置,以及核心代码的编写与调试等关键环节。通过本实战,读者将能够掌握使用Geotools处理DEM数据的实用技能,为在地理信息领域的深入研究和实际应用奠定坚实的基础。
一、GridCoverage2D对象介绍
GridCoverage2D是Geotools库中用于表示二维栅格覆盖数据的核心类,广泛应用于地理信息系统(GIS)开发中,特别是在处理遥感影像、数字高程模型(DEM)等栅格数据时发挥着关键作用。以下是关于GridCoverage2D的详细介绍,包括其属性和方法。
1、GridCoverage2D的属性
GridCoverage2D是继承自AbstractGridCoverage的一个子类,GridCoverage2D子类定义的属性不多,分别是:
-
image:表示栅格数据的
PlanarImage对象,包含了栅格的像素数据。 -
gridGeometry:表示栅格几何信息的
GridGeometry2D对象,包括网格坐标的有效范围和地理参考。

2、GridCoverage2D核心方法
-
获取坐标参考系(CRS)
-
getCoordinateReferenceSystem2D():返回栅格覆盖的二维坐标参考系。
-
-
获取范围
-
getEnvelope():返回栅格覆盖在坐标参考系中的边界范围。 -
getEnvelope2D():返回栅格覆盖在坐标参考系中的二维边界范围。
-
-
获取几何信息
-
getGridGeometry():返回栅格覆盖的几何信息。
-
-
获取栅格数据
-
getRenderedImage():将栅格覆盖数据作为RenderedImage获取。
-
-
评估指定位置的值
-
evaluate(Position point):在指定的地理坐标处获取栅格值。 -
evaluate(Point2D coord, double[] dest):在指定的地理坐标处获取double类型的栅格值。 -
evaluate(Point2D coord, float[] dest):在指定的地理坐标处获取float类型的栅格值。 -
evaluate(Point2D coord, int[] dest):在指定的地理坐标处获取int类型的栅格值。 -
evaluate(GridCoordinates2D coord, double[] dest):在指定的网格坐标处获取double类型的栅格值。 -
evaluate(GridCoordinates2D coord, float[] dest):在指定的网格坐标处获取float类型的栅格值。 -
evaluate(GridCoordinates2D coord, int[] dest):在指定的网格坐标处获取int类型的栅格值。
-
-
获取样本维度信息
-
getNumSampleDimensions():获取栅格覆盖的样本维度(波段)数量。 -
getSampleDimension(int index):获取指定索引的样本维度信息。 -
getSampleDimensions():获取栅格覆盖的所有样本维度信息。
-
-
获取插值方法
-
getInterpolation():获取用于所有evaluate(...)方法的插值方法
-
3、GridCoverage2D中的高级操作
-
重采样
-
Operations.DEFAULT.resample():将栅格覆盖重采样到新的网格几何或坐标参考系中。
-
-
插值
-
Operations.DEFAULT.interpolate():对栅格覆盖进行插值操作,指定插值方法如双线性插值。
-
-
裁剪
-
使用裁剪操作来获取栅格覆盖的子区域,通过指定一个
Envelope来定义裁剪范围。
-
-
isDataEditable():判断栅格数据是否可编辑。
-
getOptimalDataBlockSizes():获取访问栅格值时每个维度的最佳块大小。
-
getDebugString(Position coord):获取指定坐标的调试字符串。
以上是GridCoverage2D类的主要属性和方法的详细介绍,这些功能使其成为处理和分析栅格数据的强大工具,无论是基础的数据读取和查询,还是复杂的几何变换和数据处理,都能满足地理信息开发中的多样化需求。
二、指定位置的高程获取
在前面一节中重点介绍了GridCoverage2D的相关属性和方法,在了解了这些基本知识以后再来进行相关属性的具体获取实例以及根据一个经纬度位置获取其对应的高程(类似于海拔)信息。本节重点是相关代码的展示。
1、存储原理
在GeoTIFF格式的DEM中,高程值通常以规则格网(Regular Grid)的形式存储。具体来说,高程值被组织成一个二维的像素矩阵,每个像素代表一个特定地理坐标点的高程值。按行或列存储:高程值按行或列逐一记录,形成一个矩阵结构。每一行或列对应地理空间中的一个纬度或经度范围。数据类型:高程值可以是整数或浮点数格式,支持不同的位深度。例如,常见的有16位整数、32位浮点数等。
2、相关属性的获取
这里以GridCoverage2D中,我们来读取GridCoverage2D的相关属性信息,读取属性信息的关键方法如下:
// DEM 文件路径
File demFile = new File("C:/BaiduDownload/湖南省_DEM_30m分辨率_NASA数据.tif");
// 创建 GeoTiffReader
GeoTiffReader reader = new GeoTiffReader(demFile);
System.out.println("************************解析coverage对象开始*******************");
// 读取 GridCoverage2D
GridCoverage2D coverage = reader.read(null);
System.out.println("名称:"+coverage.getName());
for(String propertyName : coverage.getPropertyNames()) {System.out.println(propertyName + "<===>" + coverage.getProperty(propertyName));
}System.out.println("************************解析coverage对象结束*******************");
运行以上的代码后,得到的属性信息如下:
************************解析coverage对象开始*******************
名称:湖南省_DEM_30m分辨率_NASA数据
tile_cache_key<===>PlanarImage[minX=0 minY=0 width=19695 height=19750 tileGridXOffset=0 tileGridYOffset=0 tileWidth=19695 tileHeight=1 sampleModel=java.awt.image.PixelInterleavedSampleModel@14def00 colorModel=ColorModel: #pixelBits = 16 numComponents = 1 color space = java.awt.color.ICC_ColorSpace@6c2d4cc6 transparency = 1 has alpha = false isAlphaPre = false]
GC_NODATA<===>NoDataContainer [nodataR=RangeDouble[0.0, 0.0], array=[0.0], singleValue=0.0]
JAI.ImageReader<===>it.geosolutions.imageioimpl.plugins.tiff.TIFFImageReader@30865a90
image_height<===>19750
JAI.ImageReadParam<===>it.geosolutions.imageio.plugins.tiff.TIFFImageReadParam@6134ac4a
image_min_x_coord<===>0
PamDataset<===>it.geosolutions.imageio.pam.PAMDataset@777c9dc9
tile_cache<===>com.sun.media.jai.util.SunTileCache@71b1a49c: memoryCapacity = 1000000 memoryUsage = 0 #tilesInCache = 0
image_width<===>19695
image_min_y_coord<===>0
************************解析coverage对象结束*******************
在属性信息中,可以获取到tif文件的高度和宽度等信息。
3、获取高程的方法
从Dem中获取指定位置经纬度的高程的方法如下:
/**
* -根据coverage求解对应经纬度的高程值
* @param coverage
* @param lon 经度
* @param lat 纬度
* @return 高程值
*/
public double getHeightValue(GridCoverage2D coverage,double lon,double lat) {// 获取 DEM 的坐标参考系统CoordinateReferenceSystem crs = coverage.getCoordinateReferenceSystem2D();DirectPosition position = new DirectPosition2D(crs, lon, lat);// 评估高程值double[] elevation = (double[]) coverage.evaluate(position, new double[1]);System.out.println("Elevation at (" + lon + ", " + lat + "): " + elevation[0]);return elevation[0];
}
然后使用Junit方法来进行对应的位置的测试。本例中所采用的是湖南省30米的DEM数据,因此这里可以读取的高程位置范围仅限于湖南省内。为了验证这种情况,我们使用贵州省铜仁的一个经纬度,在此情况下无法获取相应的高程信息。
System.out.println("老屋背高程:" + getHeightValue(coverage,109.281998D,27.204116D));
System.out.println("岳麓山高程:" + getHeightValue(coverage,112.927952D,28.188622D));
System.out.println("楠木寺高程:" + getHeightValue(coverage,112.859802D,28.169707D));
System.out.println("武陵源高程:" + getHeightValue(coverage,110.484695D,29.342379D));
System.out.println("贵州省铜仁高程:" + getHeightValue(coverage,109.160156D,27.683528D));
System.out.println("----------------------从dem获取高程-----------------------------");
运行之后可以在控制台看到以下高程输出:

与我们的预期一致,成功的通过经纬度位置获取位置信息。 同时针对省外的铜仁地区,我们无法获取指定区域的高程信息。
三、总结
以上就是本文的主要内容, 本实战内容将深入讲解如何利用Geotools这一强大工具,详细阐述从获取DEM数据到成功读取指定位置高程信息的全过程。包括对DEM数据格式的解析、Geotools环境的搭建与配置,以及核心代码的编写与调试等关键环节。通过本实战,读者将能够掌握使用Geotools处理DEM数据的实用技能,为在地理信息领域的深入研究和实际应用奠定坚实的基础。通过本文的讲解,相信你一定掌握了GridCoverage2D的相关知识,同时掌握了如何读取GridCoverage2D的属性信息以及如何从DEM中获取我们需要的高程信息。通过一个位置点的高程获取可以让您掌握一条线的高程信息如何获取,也就是循环坐标点,然后依次来获取相应的高程信息,从而可以得到一条路线的连续高程信息。有了数据之后,相信您一定可以快速的获取相关信息。行文仓促,难免有许多不足之处,如有不足,在此恳请各位专家博主在评论区不吝留言指出,不胜感激。
相关文章:
使用Geotools从DEM数据中读取指定位置的高程实战
目录 前言 一、GridCoverage2D对象介绍 1、GridCoverage2D的属性 2、GridCoverage2D核心方法 3、GridCoverage2D中的高级操作 二、指定位置的高程获取 1、存储原理 2、相关属性的获取 3、获取高程的方法 三、总结 前言 在地理信息科学领域,高程数据是至关重…...
uniapp 在app上 字体如何不跟着系统字体大小变
在UniApp开发中,默认情况下App的字体可能会跟随系统字体设置而变化。如果你希望保持固定的字体样式,不随系统字体设置改变,可以采用以下几种方法: 方法一:全局CSS设置 在App.vue的样式中添加以下CSS: /*…...
RAG优化:python从零实现GraphRag 一场文档与知识的“恋爱”之旅
嘿,亲爱的算法工程师们,准备好迎接一场文档与知识的“恋爱”之旅了吗?今天我们要介绍的 Graph RAG,就像是一位“红娘”,帮助文档和知识在图的世界里找到彼此,擦出智慧的火花! 文章目录 为什么需要 Graph RAG?Graph RAG 的“恋爱秘籍”准备好了吗?让我们开始吧!环境设…...
STM32F103_LL库+寄存器学习笔记05 - GPIO输入模式,捕获上升沿进入中断回调
导言 GPIO设置输入模式后,一般会用轮询的方式去查看GPIO的电平状态。比如,最常用的案例是用于检测按钮的当前状态(是按下还是没按下)。中断的使用一般用于计算脉冲的频率与计算脉冲的数量。 项目地址:https://github.…...
如何为你的github开源项目选择合适的开源协议?
如何为你的github开源项目选择合适的开源协议? 导言 在github开源世界中,选择一个合适的开源协议是至关重要的。它不仅定义了他人如何使用你的代码,还决定了你的项目能否被广泛接受和传播,还能避免侵权问题。 然而,面…...
【深度破解】爬虫反反爬核心技术实践:验证码识别与指纹伪装
一、反爬技术体系全景图 现代Web应用的常见反爬手段: mermaid: graph TDA[反爬体系] --> B[行为特征检测]A --> C[验证码体系]A --> D[指纹追踪]B --> B1[请求频率]B --> B2[鼠标轨迹]B --> B3[页面停留时间]C --> C1[图形验证码…...
dynamic_cast的理解
dynamic_cast:(具体使用就不详细说明了) C 中用于 安全的类层次结构转换 的类型转换运算符,主要用于 多态类型(即包含虚函数的类)的指针或引用之间的转换 前提条件: 必须要有虚函数才能使用 dy…...
MATLAB 编写的函数或算法生成可供 C++ 调用的库或组件
MATLAB 编写的函数或算法生成可供 C 调用的库或组件 使用 MATLAB Coder 生成 C/C 代码: MATLAB Coder 允许您将 MATLAB 函数转换为可移植的 C 或 C 代码。生成的代码可以作为静态库、动态库或源代码,供 C 项目直接调用。具体步骤包括: 准备…...
Java基础知识-反射
一、什么是反射? Java反射(Reflection)是Java语言的核心特性之一,它允许程序在运行时(Runtime)动态地操作类和对象。通过反射API,我们可以在程序运行期间: 获取任意类的Class对象构…...
【大模型学习】什么是具身智能
目录 一、技术背景与历史发展 二、什么是具身智能? 三、技术要点及具体实现细节 1. 感知技术: 2. 运动控制: 3. 学习机制: 4. 人机交互: 四、架构 五、应用 六、实际应用案例 一、技术背景与历史发展 人工智能的…...
直播预告 | TDgpt 智能体发布 时序数据库 TDengine 3.3.6 发布会即将开启
从海量监控数据,到工业、能源、交通等场景中实时更新的各类传感器数据,时序数据正在以指数级速度增长。而面对如此庞杂的数据,如何快速分析、自动发现问题、精准预测未来,成为企业数字化转型过程中的关键挑战。 TDengine 的答案是…...
服务器硬盘出现故障都有哪些解决方法?
服务器作为核心的硬件设施和互联网中必不可少的网络设备,承载着重要的数据信息和业务应用,但是服务器硬盘也会出现故障的情况,当服务器硬盘发生故障该如何进行解决呢,下面,我们就从以下几个方面进行探讨一下吧…...
vscode 通过Remote-ssh远程连接服务器报错 could not establish connection to ubuntu
vscode 通过Remote-ssh插件远程连接服务器报错 could not establish connection to ubuntu,并且出现下面的错误打印: [21:00:57.307] Log Level: 2 [21:00:57.350] SSH Resolver called for "ssh-remoteubuntu", attempt 1 [21:00:57.359] r…...
【JavaScript 简明入门教程】为了Screeps服务的纯JS入门教程
0 前言 0-1 Screeps: World 众所不周知,Screeps: World是一款面向编程爱好者的开源大型多人在线即时战略(MMORTS)沙盒游戏,其核心机制是通过编写JavaScript代码来控制游戏中的单位(称为“Creep”)&#…...
Prometheus stack命令行接入springboot服务metrics
使用Prometheus Stack监控SpringBoot应用 本文将详细介绍如何使用Prometheus Stack监控SpringBoot应用的metrics。假设你已经安装了Kubernetes集群,并使用Helm安装了Prometheus Stack全家桶。SpringBoot应用已经配置好,暴露了相应的metrics端点。 Sprin…...
Git Bash 设置Notepad++作为默认编辑器
网上搜的时候发现别人搞得有点复杂 (绝对正确的方法)Git Bash 设置Notepad作为默认编辑器_git 通过notpad 编辑器-CSDN博客 最简单的方式就是重新安装git,然后在选择编辑器的时候,勾选notepad即可...
Qt 制作验证码
Qt 制作验证码 #include <QRandomGenerator> #include <QPainterPath> #include <QPainter>// 生成随机数 int r(int a,int b0){return b ? QRandomGenerator::global()->bounded(a, b): QRandomGenerator::global()->bounded(a); }// 生成随机多边形…...
WPF InkCanvas 控件详解
1. InkCanvas 是什么? InkCanvas 是 WPF 提供的一个手写绘图控件,它允许用户使用鼠标、触摸屏或手写笔在界面上进行绘图、标注等操作。 核心特点: ✅ 具备笔迹存储和管理功能。 ✅ 提供 Children 和 Strokes 两个集合,分别用于管理子控件和绘制的笔迹。 ✅ 通过 EditingM…...
【数据结构】二叉树 — 经典OJ面试题剖析!!!
目录 二叉树相关oj题 1. 检查两颗树是否相同 2. 另一棵树的子树 3. 翻转二叉树 4. 判断一颗二叉树是否是平衡二叉树 5. 对称二叉树 6. 二叉树的构建及遍历 7. 二叉树的层序遍历 8. 判断一棵树是不是完全二叉树 9. 二叉树的最近公共祖先 10. 根据前序与中序遍历序列构…...
【MySQL】用户账户、角色、口令、PAM
目录 查看用户账户设置 连接 1.本地连接 2.远程连接 账户 角色 操作用户账户和角色 配置口令和账户有效期限 手工使口令过期 配置口令有效期限 PAM身份验证插件 客户端连接:使用 PAM 账户登录 在连接到MySQL服务器并执行查询时,会验证你的身…...
Linux之 权限提升(Linux Privilege Escalation)
Linux 之权限提升 系统信息 1.获取操作系统信息 2.检查PATH,是否有任何可写的文件夹? 3.检查环境变量,有任何敏感细节吗? 4.使用脚本(DirtyCow?)搜索内核漏洞 5.检查sudo 版本是否存在漏洞…...
贪心算法经典应用:最优答疑调度策略详解与Python实现
目录 引言:从现实场景到算法设计 一、问题背景与数学建模 1.1 现实场景抽象 1.2 时间线分析 二、贪心策略的数学证明与选择依据 2.1 贪心选择性质 2.2 证明过程 三、算法实现与代码解析 3.1 算法步骤分解 3.2 代码亮点解析 四、测试案例与结果验证 4.1 …...
SpringBoot 3+ Lombok日志框架从logback改为Log4j2
r要将Spring Boot 3项目中的日志框架从Logback切换到Log4j2,并配置按日期滚动文件和控制台输出,请按照以下步骤操作: 步骤 1:排除Logback并添加Log4j2依赖 在pom.xml中修改依赖: <dependencies><!-- 排除默…...
【bug】[42000][1067] Invalid default value for ‘xxx_time‘
MySQL错误解决:Invalid default value for xxx_time’问题分析与修复方案 问题描述 在MySQL数据库操作中,当尝试创建或修改表结构时,可能会遇到以下错误信息: [bug] [42000][1067] Invalid default value for xxx_time这个错误…...
网站安全专栏-------浅谈CC攻击和DDoS攻击的区别
CC攻击和DDoS攻击都是网络攻击的类型,但它们在攻击方式、目标和效果上有所不同。以下是它们之间的一些主要区别: ### 1. 定义 - **DDoS攻击(分布式拒绝服务攻击)**: DDoS攻击是指攻击者通过大量的分布式计算机&#x…...
【Tauri2】002——Cargo.toml和入口文件
目录 前言 正文 toml文件的基础 注释——# Comment 键值对——Key/Value 表——[table] 内联表——Inline Table 数组——Array package和crate Cargo.toml文件 Cargo.toml——dependencies Cargo.toml——lib crate-type main.rs 前言 【Tauri2】001——安装及…...
二叉树相关算法实现:判断子树与单值二叉树
目录 一、判断一棵树是否为另一棵树的子树 (一)核心思路 (二)代码实现 (三)注意要点 二、判断一棵树是否为单值二叉树 (一)核心思路 (二)代码实现…...
CSS 美化页面(一)
一、CSS概念 CSS(Cascading Style Sheets,层叠样式表)是一种用于描述 HTML 或 XML(如 SVG、XHTML)文档 样式 的样式表语言。它控制网页的 外观和布局,包括字体、颜色、间距、背景、动画等视觉效果。 二、CS…...
23种设计模式-组合(Composite)设计模式
组合设计模式 🚩什么是组合设计模式?🚩组合设计模式的特点🚩组合设计模式的结构🚩组合设计模式的优缺点🚩组合设计模式的Java实现🚩代码总结🚩总结 🚩什么是组合设计模式…...
LSTM创新点不足?LSTM + Transformer融合模型引领Nature新突破
LSTM创新点不足?LSTM Transformer融合模型引领Nature新突破 2024年LSTM真的没有创新空间了吗? 最新研究表明,通过将LSTM与Transformer巧妙融合,依然能创造出Nature级别的突破性成果。LSTM擅长处理短期时序模式,但在…...
