GDAL 读取影像元数据

前言

元数据是用来描述数据的数据,其作为数据的"说明书",是实现空间数据有效管理与深度应用的基础支撑。它通过记录数据来源、投影信息、属性定义、采集精度等核心要素,确保GIS数据的可理解性与可追溯性,为数据使用者提供准确的背景信息,在GIS开发中具有重要意义。

本篇教程在之前一系列文章的基础上讲解

  • GDAL 简介[1]
  • GDAL 下载安装[2]
  • GDAL 开发起步[3]

如果你还没有看过,建议从那里开始。

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 元数据

由于我未下载Python IDE,所以有关代码示例都以下步骤为准。

新建一个文本文件,然后将其后缀修改为.py,使用文本编辑器打开,在其中写入以下代码。

(一)打开GeoTIFF影像 通过调用Open方法打开影像数据集,参数为GeoTIFF数据路径。

ini 复制代码
from osgeo import gdal
# 打开GeoTIFF影像
dataset = gdal.Open("LC08_L1TP_130042_20210212_20210304_01_T1_B1.TIF")

在本示例中,当前GDAL版本会弹出警告信息。提示需要进行异常处理,可以调用异常方法或者忽略异常,而在GDAL 4.0版本中,将会默认开启异常处理。

FutureWarning: Neither gdal.UseExceptions() nor gdal.DontUseExceptions() has been explicitly called. In GDAL 4.0, exceptions will be enabled by default.

所以可以在代码中添加异常处理语句。

ini 复制代码
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方向像元数)

修改读取影像基本信息代码如下。

python 复制代码
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即可获取坐标系信息。

bash 复制代码
# 获取坐标系统信息
projection = dataset.GetProjection()
if projection:
    print("n坐标系统:",projection)

输出信息显示坐标系为WGS 84 / UTM zone 47N

(三)读取影像范围信息

接着以上代码添加如下内容,通过数据集方法GetGeoTransform获取坐影像范围信息。

bash 复制代码
# 读取地理范围信息
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可以获取元数据域信息。

python 复制代码
# 读取元数据域
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可以获取波段数据。

python 复制代码
  # 获取波段信息
  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的垃圾回收最终会处理,但显式关闭是好习惯。

ini 复制代码
dataset = None

参考资料

1\] [GDAL 简介](https://juejin.cn/post/7544949169640063010 "https://juejin.cn/post/7544949169640063010") \[2\] [GDAL 下载安装](https://juejin.cn/post/7545853099353833512 "https://juejin.cn/post/7545853099353833512") \[3\] [GDAL 开发起步](https://juejin.cn/post/7546216246126395432 "https://juejin.cn/post/7546216246126395432")

相关推荐
qb3 小时前
vue3.5.18源码-编译-入口
前端·vue.js·架构
小桥风满袖3 小时前
极简三分钟ES6 - 类与继承
前端·javascript
虫无涯3 小时前
【分享】基于百度脑图,并使用Vue二次开发的用例脑图编辑器组件
前端·vue.js·编辑器
子兮曰3 小时前
🚀99% 的前端把 reduce 用成了「高级 for 循环」—— 这 20 个骚操作让你一次看懂真正的「函数式折叠」
前端·javascript·typescript
wifi歪f3 小时前
📦 qiankun微前端接入实战
前端·javascript·面试
小桥风满袖3 小时前
极简三分钟ES6 - Symbol
前端·javascript
子兮曰4 小时前
🚀Map的20个神操作,90%的开发者浪费了它的潜力!最后的致命缺陷让你少熬3天夜!
前端·javascript·ecmascript 6
NewChapter °4 小时前
如何通过 Gitee API 上传文件到指定仓库
前端·vue.js·gitee·uni-app
练习时长两年半的Java练习生(升级中)4 小时前
从0开始学习Java+AI知识点总结-30.前端web开发(JS+Vue+Ajax)
前端·javascript·vue.js·学习·web