2026/2/18 11:39:40
网站建设
项目流程
教做宝宝衣服的网站,做毕业网站的流程,商务网站前台模板,襄阳网站建设楚翼网络GIS 栅格数据只是一张普通图片吗#xff1f;其实它可以是高程、降雨量、土地类型#xff0c;甚至是二维空间信号。本文节选自新书《GIS基础原理与技术实践》第5章#xff0c;带你穿透表象#xff0c;掌握栅格数据的本质与 GDAL 开发核心技能。第5章 地理空间数据之栅格
导言…GIS 栅格数据只是一张普通图片吗其实它可以是高程、降雨量、土地类型甚至是二维空间信号。本文节选自新书《GIS基础原理与技术实践》第5章带你穿透表象掌握栅格数据的本质与 GDAL 开发核心技能。第5章 地理空间数据之栅格导言在上一章节中我们对地理空间数据进行了初步的介绍并详细的论述了其表现形式之一的矢量数据。而在本章中我们会详细论述地理空间数据的另外一种表现形式也就是栅格数据。矢量和栅格是GIS地理空间数据最基础的两种数据类型是一定需要理解和掌握的。5.1 栅格数据的深入认识通过第4.1节中的介绍我们对栅格数据有了一个初步的认识栅格是地理空间连续实体的表达。接下来在本节中我们会进一步探索栅格的技术细节加深对栅格数据的理解。5.1.1 离散还是连续记得笔者有一次跟同事争论图像数据也就是栅格数据到底是离散的还是连续的当时笔者还是个GIS菜鸟认为图像是离散的。从前面介绍的知识来说很显然栅格是地理的连续表达。与矢量只能知道具体的要素的坐标不同我们可以很容易获取每一个栅格单元具体的地理坐标体现了数据的连续性。然而当我们把一张图像放大我们很容易会看到一个个具体的栅格单元如下图5.1所示这些栅格单元中突变的颜色表明栅格数据并不是我们想象的那样单纯的具有连续性。栅格数据对地理空间的表达总是会受制于采样频率最直观的体现就是分辨率。如同现实中显示器一样分辨率越高意味着像素的数目越多显示效果就越精细。但是无论多精细其实都是由离散的栅格单元在二维平面上连续铺盖成的格网组成的。如此说来笔者在菜鸟时期认为栅格数据是离散的可以说还是具有一定的正确性的尽管是误打误撞。离散还是连续并不是绝对的关键还在于是如何看待和认知在宏观意义上栅格数据毫无疑问是连续的这是区别与矢量数据的根本特性。只要是在栅格数据的范围之内就可以获取任意位置的地理对象值。在微观意义上栅格数据也可以认为是离散的。受制于数据表达的载体总会在一个无法细分的尺度上用一个离散的栅格单元来代表一定连续范围内的地理对象值。栅格数据关于离散还是连续的讨论我们在后面还会涉及到。5.1.2 栅格的表现形式我们在4.1节中介绍过栅格数据的一种具体表现形式就是我们经常见到的图片有时称为图像或者影像。但是认为图片就是栅格这种理解并不全面栅格数据的内涵要丰富得多。我们最常见的图片是24位真彩色图片因为每个像素都由红绿蓝RGB3种颜色值混合而成而每个波段的颜色值都由而一个8位整型表示。这样真彩色图片能表示的颜色就有 256 X 256 X 256 16777216 种不同颜色这恰好大于人类能识别1000万种颜色的限制。另外出于数据叠加显示等目的还会将第4个波段设置成透明度。其实透明度并不是一个颜色值其是当前颜色值与背景颜色值的混合。在遥感领域很多传感器并不是只能接受红绿蓝这三种可见光的波段一些不可见的波段也可以接收到比如红外波段这主要取决于传感器的波长分辨率。因此第4个波段也不一定就是透明度而是其光谱的反射值或者辐射值。甚至于可以存在4个以上的波段。光谱的反射值也不一定就是8位整型用于遥感探测的传感器要敏感的多因此每个波段的光谱反射值是16位、32位甚至64位数值都是有可能的。栅格数据中格网单元的取值可以是可见光的颜色也可以是遥感获取的具体探测值。那么存放其他类型的数据是可以的吗?当然也是可以的比如我们可以在栅格数据中储存高程值就可以表达地形成为栅格形式的DEMDigital Elevation Model数字高程模型数据。这一点我们会在后续的地形章节中专门论述它。既然栅格单元可以存放高程那么存放一些诸如表达降雨量污染浓度这样的测量值或者土地类型这样的分类值也是可以的——此类数据就是与业务紧密关联的专题栅格数据具有很大的实用价值可以在其基础之上进行专题分析例如利用降雨量专题数据进行淹没分析。当然专题栅格数据如果需要进行可视化的话就需要进行转换。栅格数据图像还可以看成是信号。在常规的认知中我们通常认为信号是随时间t变化的一种东西比如电磁波或者声波。实际上栅格数据图像可以认为是一个沿着空间分布、随着X空间轴和Y空间轴变化的二维信号。有这一点认知非常重要因为很多栅格数据处理的算法都需要借助于信号的理论比如我们后续会介绍的滤波。最后在数学中可以认为栅格数据就是一个很大的矩阵可以进行复杂的矩阵运算。很多运算数据都可以转换成矩阵从而被转换成图片格式来保存这也与我们认知的常规图片不同。5.1.3 正射还是透视以GIS中最常用的地图来说我们至少有这样一个认识地图上每一段相同距离所代表的实际距离都相等。如果不具备这样的特性地图就不可能辅助我们进行导航等空间位置上的决策。在GIS中大部分栅格数据就是这种具备相同比例尺的光学影像数据它好像是很多道平行的光线同时反射到摄像机成像生成的所以通常被称为数字正射影像图DOMDigital Orthophoto Map。但是在现实中理想的正射成像模型几乎不存在大多数摄像机都是透视成像模型其生成的图像最大的特点就是近大远小并且投影的光线会聚于一点。这也是真实的人眼成像的特点。其实数字正射影像图就是通过透视成像模型的图片做几何纠正生成的这一点在GIS的关联学科《摄影测量学》中有详细的介绍。如下图5.6所示为正射成像模型和透视成像模型示意图正射还是透视只是图像的生成的两种不同的方式并不会影响图像或者栅格数据本身的性质。在GIS中的栅格数据大多数指的是数字正射影像图能够使用专业的GIS方法进行处理这是常规的基于透视成像模型的图片所不具备的。5.2 栅格数据开发基础5.2.1 栅格数据读取与矢量数据一样可以使用第三方开源库GDAL来实现栅格数据的基础开发。GDAL提供了市面上绝大多数常见栅格数据的支持并将其抽象成一个数据集对象。读取栅格数据的示例如下例5.1所示/* by yours.tools - online tools website : yours.tools/zh/camelcase.html */ // 例5.1 使用GDAL读取栅格数据 #include gdal_priv.h #include iostream using namespace std; int main() { GDALAllRegister(); string srcFile getenv(GISBasic); srcFile srcFile /../Data/Raster/berry_ali_2011127_crop_geo.tif; GDALDataset* img (GDALDataset*)GDALOpen(srcFile.c_str(), GA_ReadOnly); if (!img) { return 1; } int imgWidth img-GetRasterXSize(); //图像宽度 int imgHeight img-GetRasterYSize(); //图像高度 int bandNum img-GetRasterCount(); //波段数 int depth GDALGetDataTypeSize(img-GetRasterBand(1)-GetRasterDataType()) / 8; //图像深度 cout 宽度 imgWidth \n; cout 高度 imgHeight \n; cout 波段数 bandNum \n; cout 深度 depth \n; GDALClose(img); img nullptr; }在这个示例中从栅格数据文件中创建了一个数据集对象并且获取了影像的宽度、高度和波段数通道数和深度。深度有点难以理解指的是栅格存储数据类型的字节数。常规的影像数据都采用8位无符号整型进行存储因此深度都为1。本例运行结果如下/* by yours.tools - online tools website : yours.tools/zh/camelcase.html */ 宽度4000 高度7200 波段数4 深度15.2.2 栅格数据创建另一方面也可以根据一个数据集对象创建栅格数据文件也就是栅格数据的写出操作。与第4.4.2节中创建矢量的步骤类似同样通过GDAL的数据驱动GDALDriver传入数据类型的名称来创建对应格式的栅格文件如下例5.2所示创建了一个tif格式的栅格数据// 例5.2 使用GDAL创建栅格数据 #include gdal_priv.h #include iostream using namespace std; int main() { GDALAllRegister(); //注册格式 string dstFile getenv(GISBasic); dstFile dstFile /../Data/Raster/dst.tif; GDALDriver* pDriver GetGDALDriverManager()-GetDriverByName(GTiff); //图像驱动 char** ppszOptions NULL; ppszOptions CSLSetNameValue(ppszOptions, BIGTIFF, IF_NEEDED); //配置图像信息 int imgWidth 256; int imgHeight 256; int bandNum 3; GDALDataset* dst pDriver-Create(dstFile.c_str(), imgWidth, imgHeight, bandNum, GDT_Byte, ppszOptions); if (!dst) { printf(Cant Write Image!); return 1; } GDALClose(dst); return 0; }上例中我们创建了一个宽256高256波段数3byte类型8位深度1的栅格数据文件GDALDriver* pDriver GetGDALDriverManager()-GetDriverByName(GTiff); //图像驱动 //... GDALDataset* dst pDriver-Create(dstFile.c_str(), imgWidth, imgHeight, bandNum, GDT_Byte, ppszOptions);数据类型的名称“GTIFF”是GDAL定义的驱动名表示创建的数据集对象是一个tif格式的栅格数据文件。一些常用栅格数据格式在GDAL中数据驱动如下表5.1所示名称全称JPEGJPEG JFIF File FormatPNGPortable Network GraphicsBMPMicrosoft Windows Device Independent BitmapGTiffGeoTIFF File FormatHFAErdas Imagine .imgENVIENVI .hdr Labelled Raster其中JPEG、PNG和BMP就是我们经常见到的图像数据格式GTiffGeoTIFF、HFAErdas Imagine .img和ENVIENVI .hdr Labelled Raster则是专业的GIS栅格数据。前者通用性更强能被常规的图片软件所识别而后者专业性更高一些栅格数据的特性常规图像数据无法支持例如存在数据量大小限制因此只能使用专业GIS栅格数据一般情况仅被GIS相关的软件支持。另一点值得注意的是在创建特定数据集对象时可以根据特定格式的需求进行配置char** ppszOptions NULL; ppszOptions CSLSetNameValue(ppszOptions, BIGTIFF, IF_NEEDED); //配置图像信息 //... GDALDataset* dst pDriver-Create(dstFile.c_str(), imgWidth, imgHeight, bandNum, GDT_Byte, ppszOptions);这里配置参数的意思是在需要的时候使用“BIGTIFF”格式而不是“TIFF”以避免当栅格数据文件的大小超过4G的时候会创建失败。最后在创建数据集完成之后不要忘了关闭数据集GDALClose(dst);此时创建的数据集文件就是一张黑色的栅格图片因为关闭后默认填充0像素值如下图5.7所示本文节选自作者新书《GIS基础原理与技术实践》第5章。书中系统讲解 GIS 核心理论与多语言实战适合开发者与高校师生。配套资源开源GitHub | GitCode支持正版京东当当