栅格数据金字塔层级的地理变换信息

news/2025/1/31 0:17:42/文章来源:https://www.cnblogs.com/charlee44/p/18695547

1. 引言

笔者在实现栅格数据的可视化的时候遇到了一个问题,计算栅格数据金字塔层级的地理变换信息错误导致可视化的时候存在微小的误差。地理变换信息指的就是栅格数据的地理坐标起点和分辨率,笔者在另外一篇文章中《GDAL读取的坐标起点在像素左上角还是像素中心?》论述了栅格数据集中坐标起点位置存在半个像素差的问题。但是栅格数据集的金字塔层级影像是如何处理这个问题的呢?

2. 详论

2.1 连续还是离散

从《GDAL读取的坐标起点在像素左上角还是像素中心?》这篇文章继续引申一个问题:栅格数据究竟是连续的还是离散的?从GIS的角度来看,栅格数据就是真实世界地理实体的表达,肯定应该是连续的。但是问题在于,现实世界并不存在如此完美的载体能够表达连续的实体对象,大多数都会离散化为网格。比如图像、屏幕这些数据载体,它们本质上就是栅格,你将它们放大来看,就能看到一个个放大的格子。GIS的栅格数据就是通过这些离散的数据载体来表达的,那你能说栅格数据一定就是连续的吗?所以笔者有一句结论:

GIS的栅格数据在宏观上是连续的,在微观上是离散的

其实这个结论有的读者不一定能够接受,因为每个人都有自己的固有认知,强行接受别人的认知无异震碎自己的三观,比如笔者的前同事,就对我这个理论不以为然,总会纠结一个问题:如果栅格数据都离散成整数了,那么横坐标为0.6的像素在哪里?其实我觉得不妨这样理解,一个离散的像素网格确实对应了真实地理实体的一段长度,不过一个像素网格已经是最小的表达实体了,那么就只能使用像素网格中心的位置的值来表达代表整个像素网格的值。横坐标为0.6的像素确实在数据载体中不存在,但是其表达的数据中确实客观存在的,一定要获取这个值也有处理方法,那就是数值内插算法,比如《数字图像处理》中经常提到的最邻近、双线性以及三次卷积等内插算法。

2.2 起点位置问题

在笔者看来,栅格数据是连续的还是离散的看法其实关联着栅格数据中地理坐标起点的位置问题。tif数据内部存储的地理变换信息规定地理坐标起点在像素左上角,这是着重于栅格数据的连续性;tif外部数据tfw规定地理坐标起点在像素中心点,则着重于栅格数据的离散型。那么什么时候用像素左上角作为起点,什么时候用像素中心点作为起点呢?笔者的看法是,仅以GIS栅格数据来说:

进行空间计算的时候应该以像素左上角为起点;进行图像处理的时候应该以像素中心点为起点

举例来说,笔者这里有一个栅格数据dom.tif,通过gdalinfo查询信息如下:

Driver: GTiff/GeoTIFF
Files: dom.tifdom.tif.aux.xml
Size is 19312, 22531
Origin = (1967768.351536701666191,570294.132588228210807)
Pixel Size = (0.250000000000000,-0.250000000000000)
Metadata:AREA_OR_POINT=Area
Image Structure Metadata:COMPRESSION=LZWINTERLEAVE=PIXEL
Corner Coordinates:
Upper Left  ( 1967768.352,  570294.133)
Lower Left  ( 1967768.352,  564661.383)
Upper Right ( 1972596.352,  570294.133)
Lower Right ( 1972596.352,  564661.383)
Center      ( 1970182.352,  567477.758)
Band 1 Block=19312x32 Type=Byte, ColorInterp=RedMin=0.000 Max=255.000Minimum=0.000, Maximum=255.000, Mean=110.556, StdDev=57.195Overviews: 9656x11266, 4828x5633, 2414x2817, 1207x1409, 604x705, 302x353, 151x177Metadata:STATISTICS_MAXIMUM=255STATISTICS_MEAN=110.55552426626STATISTICS_MINIMUM=0STATISTICS_STDDEV=57.19535628196STATISTICS_VALID_PERCENT=100
Band 2 ...
Band 3 ...

这里的四至范围(Upper Left、Lower Left、Upper Right、Lower Right)的计算就是以像素左上角为起点(Origin)来进行计算的,有兴趣的读者可以进行验算一下。然而,如果你需要可视化这个栅格数据,通常需要将栅格值传递到GUI画布的Image对象值中,将栅格像素对齐GUI像素,每个像素的值应该是其像素中心的地理坐标的像素值,这时最好以像素中心作为起点进行计算。

2.3 金字塔层级影像

最后回到金字塔层级的地理变换信息计算的问题。在进行可视化的时候,使用像素中心作为起点进行空间坐标的计算,重采样出合适的像素值。但是首先,任何金字塔层级影像的四至范围是不能有变化的。以上例来说,原始图像的宽高是19312×22531,第一层金字塔影像是9656×11266,如果以像素左上角为起点,计算其地理变换信息:

起点位置不会变化,Origin = (1967768.351536701666191,570294.132588228210807)。
分辨率则需要重新计算,在X方向,(19312 * 0.25)/ 9656 = 0.5;在Y方向,(22531 * 0.25)/ 11266 = 0.49997780933783064。也就是Pixel Size = (0.500000000000000,-0.49997780933783064)。

这时会发生一个略显诡异的现象,就是原始栅格影像上X方向Y方向分辨率一致都是0.25,在第一级金字塔层级影像上却已经有微小的差异了。其实产生这个现象的原因并不奇怪,因为金字塔层级的宽高通常以2的倍数递减,但是原始栅格的宽高却不是偶数。在这种情况下,要优先保证地理坐标的四至范围的一致性。

接下来计算以像素中心为起点,地理变换信息:

分辨率不会发生变化,同样是Pixel Size = (0.500000000000000,-0.49997780933783064)。
起点位置则需要偏移半个像素,移动到像素中心,Origin = (1967768.601536701666191,570293.88259932354189168)

一定要注意,在以像素中心为起点的情况下,每个金字塔层级影像的起点坐标是会变化的,因为每个金字塔层级的分辨率不同。

3. 其他

通过上述方法,可以计算任意金字塔层级影像的地理变换信息。不止是金字塔层级影像,笔者在《GDAL关于读写图像的简明总结》这篇文章中介绍过GDAL读取栅格数据的时候可以重采样读取,如下所示:

//申请buf
size_t imgBufNum = (size_t) bufWidth * bufHeight * bandNum * depth;
size_t imgBufOffset = (size_t) bufWidth * (bufHeight-1) * bandNum * depth;
GByte *imgBuf = new GByte[imgBufNum];	
//读取
img->RasterIO(GF_Read, 0, 0, imgWidth, imgHeight, imgBuf + imgBufOffset, bufWidth, bufHeight,GDT_Byte, bandNum, nullptr, bandNum*depth, -bufWidth*bandNum*depth, depth);
//写入
dst->RasterIO(GF_Write, 0, 0, bufWidth, bufHeight, imgBuf + imgBufOffset, bufWidth, bufHeight,GDT_Byte, bandNum, nullptr, bandNum*depth, -bufWidth*bandNum*depth, depth);
//释放
delete[] imgBuf;
imgBuf = nullptr;

这里读取的影像块宽高imgWidth、imgHeight与buffer块宽高bufWidth、bufHeight是可以不一致的,并且GDAL会通过重采样自动处理这个过程。影像块的地理变换信息我们很清楚,但是buffer块地理变换信息则需要自己进行计算。原理也是一样的,要优先保证buffer块的四至范围与影像块的四至范围一致,先算分辨率,在偏移半个像素的距离算出具体的起点位置。

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

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

相关文章

独立开发经验谈:如何通过 Docker 让潜在客户快速体验你的系统

如果你的产品是和我的在线客服系统一样,100% 允许用户私有化部署的,那你一定要使用 Docker 技术,让用户能够快速体验到你的系统,以及能够在生产环境中非常轻松的把你的产品用起来。我在业余时间开发了一款自己的独立产品:升讯威在线客服与营销系统。陆陆续续开发了几年,从…

AP Physics C Mechanics Chapter 7 Rotation 1

RTVocabularyRigid body 刚体 Angular displacement 角位移 \(\Delta \theta\) Angular velocity 角速度 \(\omega\) Angular acceleration 角加速度 \(\alpha\) Rotational kinetic energy 旋转动能 \(KE_{\text{rotational}}\) Rotational inertia 转动惯量 \(I\) Torque 扭矩…

electrical, electric, electronic; comparison

electrical 3818 electric 2711 electronic 2422electrical vs electric left 4WORD 1: ELECTRICAL WORD W1 W2 PROFESSOR 118 0 , " said Charles Bouman, a Purdue professor of electrical and computer engineering.普渡大学电气和计算机工程教授查尔斯…

容斥与反演

容斥与反演 容斥 容斥原理 用于不重不漏地【表达/转化】某集合 广义容斥:合法方案数 = 总方案数 - 不合法方案数 狭义容斥: \[\left|\bigcup_{i = 1}^{n}S_i\right|=\sum_{x = 1}^{n}(-1)^{x - 1}\sum_{i_1<i_2<\cdots <i_x}\left|\bigcap_{j = 1}^{x}S_{i_j}\right…

数据库查询优化:提升性能的关键实践

title: 数据库查询优化:提升性能的关键实践 date: 2025/1/30 updated: 2025/1/30 author: cmdragon excerpt: 在当今数据驱动的商业环境中,数据库的性能直接影响着应用程序的响应速度和用户体验。查询优化是性能调优的重要组成部分,通过对 SQL 查询的分析与改进,减少查询…

记一次LLVM平行宇宙修包实战

最近加入了LLVM平行宇宙计划小组,在小组内提交了一定数量的PR。这个计划究竟是做什么的呢?LLVM平行宇宙计划是基于LLVM技术栈构建openEuler软件包,大白话讲就是原本一个软件包是用gcc/g++编译的,现在换成clang/clang++编译。虽然只是切换了编译工具,但是偶尔也有可能出现一…

spark--设置日志级别

修改前: Windows:修改后: Windows:对比: Windows:修改过程: Windows: C:\Users\Administrator\Documents\spark\spark-3.5.4-bin-hadoop3>copy conf\log4j2.properties.template conf\log4j2.properties 已复制 1 个文件。 rootLogger.level = info rootLogger.…

动手学大模型应用开发,第1天:学习大模型必知必会

一. 什么是LLM(大语言模型)? 1. 发展历程 语言建模的研究始于20世纪90年代,最初采用了统计学习方法,通过前面的词汇来预测下一个词汇。然而,这种方法在理解复杂语言规则方面存在一定局限性。 随后,研究人员不断尝试改进,其中在2003年,深度学习先驱Bengio在他的经典论文…

RevivedUnblockInstaller无法加载版本的一种解决方法

可以自己去Github仓库下一个 https://github.com/UnblockNeteaseMusic/server 打开RevivedUnblockInstaller目录,我这里是C:\betterncm\RevivedUnblockInstaller 把unblockneteasemusic-win-x64.exe改成UnblockNeteaseMusic-vx.xx.x.exe 我这里改成了UnblockNeteaseMusic-v0.2…

二分答案——时隔三个月的再次

暂且不提三个月未更新的主要原因(懒) 来自25年牛牛寒假营的一道寄巧题part1 仔细考虑,显然满足单调性:假设时间T恰好发生第k次碰撞,那么T之前都不能发生,T之后只会越来越多 据此,又回到了上一篇的二分答案模板,但这里仍需考虑几个问题,如何简化问题? 对于高中物理,无…

[SWPUCTF 2021 新生赛]easyupload1.0 Writeup

1.发现是一个文件上传的题目,先上传一个一句话木马hack.jpg(因为题目前端有格式控制只能上传jpg文件)2.用burp抓包后修改后缀名为.php绕过过滤3.发包后显示:4:再用蚁剑进行连接(注意url,文件在/upload中上传),发现连接成功后找到flag.php但是发现这是个假flag(个人认为…

DeepSeek-R1环境搭建推理测试

​ 引子 这两天国货之光DeepSeek-R1火爆出圈,凑个热闹。过来看看 aha moment(顿悟时刻)的神奇,OK,我们开始吧。 一、模型介绍 1月20日,中国AI公司深度求索(DeepSeek)发布的DeepSeek-R1模型,凭借其独特的强化学习(RL)训练方法,首次让AI展现出类人的“顿悟时刻”——…