GDAL 读取影像元数据
前言
元数据是用来描述数据的数据,其作为数据的"说明书",是实现空间数据有效管理与深度应用的基础支撑。它通过记录数据来源、投影信息、属性定义、采集精度等核心要素,确保GIS数据的可理解性与可追溯性,为数据使用者提供准确的背景信息,在GIS开发中具有重要意义。
本篇教程在之前一系列文章的基础上讲解
- GDAL 简介
- GDAL 下载安装
- GDAL 开发起步
如果你还没有看过,建议从那里开始。
1. 开发环境
本文使用如下开发环境,以供参考。
时间:2025年
系统:Windows 10
Python:3.11.7
GDAL:3.7.3
2. GeoTIFF 元素据内容
2.1. 图像基本信息
元数据项 | 描述 |
图像宽度 | 水平方向像素数量 |
图像高度 | 垂直方向像素数量 |
数据类型 | 像素值的数据类型(如Byte、Int16、Float32等) |
波段数量 | 图像的光谱波段数 |
2.2. 坐标参考系统(CRS)信息
(1)地理坐标系参数
- 地理类型代码:指定地理坐标系类型(如WGS84、北京54等)
- 大地基准面代码:参考椭球体参数代码
- 本初子午线:起始经线定义(通常为格林威治)
- 线性单位:坐标单位(米、度等)
- 角度单位:角度测量单位(弧度、度等)
- 椭圆体参数:自定义椭圆体的长半轴、短半轴和扁率
(2)投影坐标系参数
- 投影编码:投影类型代码(如UTM、兰伯特等)
- 标准纬线:投影的标准纬线纬度
- 中央经线:投影中心经线
- 原点坐标:投影原点的东向和北向坐标
- 比例因子:投影的缩放比例
- 假东距/假北距:东向和北向偏移值
2.3. 地理空间信息
地理范围
- 最小X坐标:图像西边界坐标
- 最大X坐标:图像东边界坐标
- 最小Y坐标:图像南边界坐标
- 最大Y坐标:图像北边界坐标
- 角点坐标:四个角点的精确地理坐标
3. GDAL 读取 GeoTIFF 元数据
:::block-1
由于我未下载Python IDE,所以有关代码示例都以下步骤为准。
:::
新建一个文本文件,然后将其后缀修改为.py
,使用文本编辑器打开,在其中写入以下代码。
(一)打开GeoTIFF影像通过调用Open
方法打开影像数据集,参数为GeoTIFF数据路径。
from osgeo import gdal
# 打开GeoTIFF影像
dataset = gdal.Open("LC08_L1TP_130042_20210212_20210304_01_T1_B1.TIF")
在本示例中,当前GDAL
版本会弹出警告信息。提示需要进行异常处理,可以调用异常方法或者忽略异常,而在GDAL 4.0
版本中,将会默认开启异常处理。
:::block-1
FutureWarning: Neither gdal.UseExceptions() nor gdal.DontUseExceptions() has been explicitly called. In GDAL 4.0, exceptions will be enabled by default.
:::
所以可以在代码中添加异常处理语句。
from osgeo import gdal# 启用异常处理(推荐)
gdal.UseExceptions()# 打开GeoTIFF影像
dataset = gdal.Open("LC08_L1TP_130042_20210212_20210304_01_T1_B1.TIF")
(二)读取影像基本信息
可以通过以下方法或者属性获取影像基本信息。
- dataset.GetDescription():影像描述信息(通常为文件路径)
- dataset.RasterCountprint:波段数量
- dataset.RasterXSize:影像宽度(X方向像元数)
- dataset.RasterYSize:影像高度(Y方向像元数)
修改读取影像基本信息代码如下。
from osgeo import gdal# 启用异常处理(推荐)
gdal.UseExceptions()# 打开影像文件
dataset = gdal.Open("D:AppLC81300422021043LGN00LC08_L1TP_130042_20210212_20210304_01_T1_B1.TIF")if dataset is None:print("无法打开GeoTIFF文件,请检查数据")
else:# 获取影像基本信息print("影像描述(通常为文件路径):", dataset.GetDescription())print("波段数量:",dataset.RasterCount)print("影像宽度(X方向像元数):",dataset.RasterXSize)print("影像高度(Y方向像元数):",dataset.RasterYSize)
程序输出信息如下:
(三)读取影像坐标系统
接着以上代码添加如下内容,通过数据集方法GetProjection
即可获取坐标系信息。
# 获取坐标系统信息
projection = dataset.GetProjection()
if projection:print("n坐标系统:",projection)
输出信息显示坐标系为WGS 84 / UTM zone 47N
。
(三)读取影像范围信息
接着以上代码添加如下内容,通过数据集方法GetGeoTransform
获取坐影像范围信息。
# 读取地理范围信息
geotransform = dataset.GetGeoTransform()
if geotransform:print("n范围参数:",geotransform)print("左上角X坐标:",geotransform[0])print("水平分辨率:",geotransform[1])print("左上角Y坐标:",geotransform[3])print("垂直分辨率:",geotransform[5])
输出信息显如下。
(四)读取元数据域
可以通过以下方法获取元数据域信息。
GetMetadataDomainList()
:获取元数据域名列表GetMetadata()
:获取默认元素据域,相当于dataset.GetMetadata("")
GetMetadataItem()
:获取特定元数据项
接着以上代码添加如下内容,通过数据集方法GetMetadata
可以获取元数据域信息。
# 读取元数据域
print("n读取所有元数据域:",dataset.GetMetadataDomainList())
# 获取默认域的元数据,等价于 dataset.GetMetadata("")
meta_default = dataset.GetMetadata()
if meta_default:print("n默认域元数据:")for key,value in meta_default.items():print(f"{key}:{value}")
# 获取特定域(如 'EXIF')的元数据
meta_exif = dataset.GetMetadata("EXIF")
print("n特定域信息:",meta_exif)
if meta_exif:print("nEXIF 域元数据:")for key,value in meta_exif.items():print(f"{key}:{value}")# 获取特定元数据项,例如获取默认域中的 'AREA_OR_POINT'
point_meta = dataset.GetMetadataItem('AREA_OR_POINT')
if point_meta:print(f"n点数据信息:{point_meta}")
输出信息显如下。
(四)读取波段信息
可以通过以下方法或属性获取波段信息。
GetRasterBand()
:获取波段数据DataType
:获取波段数据类型GetNoDataValue()
:获取无数据值ComputeStatistics
:获取统计数据
接着以上代码添加如下内容,通过数据集方法GetRasterBand
可以获取波段数据。
# 获取波段信息for i in range(1,dataset.RasterCount+1): # 波段索引从1开始band = dataset.GetRasterBand(i)print(f"n波段 {i}:")print(" 数据类型:", band.DataType)print(" 无数据值:", band.GetNoDataValue())# 计算统计信息(如果不存在则会计算,approx_ok=False表示精确计算)min_val, max_val, mean_val, std_val = band.ComputeStatistics(False)print(f" 最小值: {min_val}, 最大值: {max_val}, 平均值: {mean_val}, 标准差: {std_val}")
输出信息显如下。
最后记得手动关闭数据集,虽然Python
的垃圾回收最终会处理,但显式关闭是好习惯。
dataset = None