本文将介绍一种 Python 实现,该实现不借助numpy读取tif文件。
平常使用gdal和numpy就可以轻松实现读写tif文件。
假设,在不使用numpy情况下,如何去读取tif的信息呢?
首先,介绍一下什么是gdal和numpy。
gdal是什么
GDAL(Geospatial Data Abstraction Library,地理空间数据抽象库)是一个开源的库,用于读取和写入栅格地理空间数据格式,它提供了一种统一的数据模型来处理这些格式的数据。GDAL支持40多种主流的栅格数据格式,包括GeoTIFF、JPEG、PNG等。
GDAL还提供了一系列的命令行工具来进行地理空间数据转换和处理。例如,gdal_translate
可以用来转换栅格数据格式,gdalwarp
可以用来重投影和裁剪栅格数据,gdalinfo
可以用来查看栅格数据的元数据信息等。
除了栅格数据处理,GDAL的子项目OGR提供了对矢量地理空间数据格式的支持,包括ESRI Shapefiles、GeoJSON、KML等。
行业内的大型软件,如google earth、arcgis的底层都借用了大量的gdal的代码。
总的来说,GDAL是一个非常强大的库,对于地理空间数据的处理和分析工作有着广泛的应用。
numpy是什么
NumPy(Numerical Python的简称)是Python编程语言的一个开源库,用于处理大型多维数组和矩阵,以及一个大集合的高级(数学)函数库。NumPy是SciPy、Pandas等数据处理或科学计算库的基础。
NumPy的主要对象是同构多维数组。它是一个元素表(通常是数字),所有类型都相同,由非负整数元组索引。在NumPy中维度被称为轴。
例如:
import numpy as np a = np.array([1, 2, 3]) # 创建一个一维数组 print(a)
输出:
array([1, 2, 3])
NumPy的数组类被称作ndarray。通常被称作数组。注意numpy.array和标准Python库类array.array并不相同,后者只处理一维数组和提供少量功能。而numpy.array是用来处理多维数组的。
NumPy提供了大量的数学函数库,如:三角函数、指数函数、对数函数、矩阵运算等,这对于科学计算非常有用。
Python 实现
具体代码如下:
#! /usr/bin/env python3 # -*- coding:utf-8 -*- from osgeo import gdal, ogr import struct def read_tif_without_numpy(src_filename): # 使用GDAL库打开GeoTIFF文件 src_ds = gdal.Open(src_filename) # 获取GeoTIFF文件的第一个光栅带 rb = src_ds.GetRasterBand(1) # 获取光栅带的数据类型 data_type = rb.DataType # 获取GeoTIFF文件的列数 cols = src_ds.RasterXSize # 获取GeoTIFF文件的行数 rows = src_ds.RasterYSize if data_type == gdal.GDT_Byte: # 如果数据类型是8位无符号整数 structval = rb.ReadRaster(0, 0, cols, rows, buf_type=gdal.GDT_Byte) # 将读取的数据转换为Python的整数类型 intval = struct.unpack('B' * cols * rows, structval) print("The GeoTIFF is 8-bit.") elif data_type == gdal.GDT_UInt16 or data_type == gdal.GDT_Int16: # 如果数据类型是16位无符号整数或16位有符号整数 structval = rb.ReadRaster(0, 0, cols, rows, buf_type=gdal.GDT_Int16) # 将读取的数据转换为Python的整数类型 intval = struct.unpack('h' * cols * rows, structval) print("The GeoTIFF is 16-bit.") else: # 如果数据类型既不是8位也不是16位 print("The GeoTIFF is neither 8-bit nor 16-bit.") # 打印第一行第一列的数值 print(intval[0]) if __name__ == '__main__': src_filename = r'test_16.tif' read_tif_without_numpy(src_filename)
我们可以使用GDAL库中的Dataset或Band的ReadRaster方法来读取栅格数据。这些方法在GDAL和OGR的API教程中有详细的介绍。ReadRaster并不需要NumPy,它返回的是原始的二进制数据,这就需要我们使用Python的标准struct库来解析这些数据。
一般情况下,使用gdal和numpy足以读取TIF文件,这篇内容针对的是特殊情况下的对应处理。
之后会在讲解不使用gdal库的情况去读写TIF文件。
为什么要写这些内容?
答:这里只是在探索、拓展思路,并没有建议只使用gdal或者只使用numpy。假设你在linux上安装不了gdal,或者安装不了numpy。这时候这些内容是不是很有价值?
当然,在日常使用中,大家最好把gdal和numpy都安装好。