如何在R语言中读取GeoTIFF文件并返回指定raw数据类型?
解决R读取大尺寸无符号字节GeoTIFF为raw类型的内存问题
方法1:使用terra包(推荐,高效且维护活跃)
terra是raster包的替代者,支持直接指定读取的数据类型,后续可转换为raw类型:
library(terra) # 读取GeoTIFF,指定数据类型为无符号字节(INT1U对应GDAL的GDT_Byte) tif_rast <- rast("your_large_file.tif", datatype = "INT1U") # 将栅格数据转为raw向量(每个元素占1字节) raw_data <- as.raw(values(tif_rast))
说明:values(tif_rast)返回的integer类型数据占4字节,转成raw后直接压缩为1字节,内存占用仅为numeric类型的1/8,大幅降低内存压力。
方法2:通过Rcpp直接调用GDAL API读取(最底层,内存最优)
如果需要完全跳过R的中间数据类型转换,直接读取为raw向量,可以用Rcpp调用GDAL的原生API:
- 编写Rcpp代码(保存为
read_geotiff_raw.cpp):
#include <Rcpp.h> #include <gdal.h> #include <gdal_priv.h> using namespace Rcpp; // [[Rcpp::export]] RawVector read_geotiff_raw(std::string filename) { // 初始化GDAL GDALAllRegister(); // 打开文件 GDALDataset *poDataset = (GDALDataset *)GDALOpen(filename.c_str(), GA_ReadOnly); if (poDataset == NULL) { stop("无法打开指定的GeoTIFF文件"); } // 获取栅格参数 int n_bands = poDataset->GetRasterCount(); int n_rows = poDataset->GetRasterYSize(); int n_cols = poDataset->GetRasterXSize(); // 初始化raw向量,大小为总像素数 RawVector raw_data(n_rows * n_cols * n_bands); GByte *buf_ptr = (GByte *)raw_data.begin(); // 逐波段读取数据到raw向量 for (int i = 0; i < n_bands; i++) { GDALRasterBand *po_band = poDataset->GetRasterBand(i + 1); po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, buf_ptr + i * n_rows * n_cols, n_cols, n_rows, GDT_Byte, 0, 0); } // 关闭数据集 GDALClose((GDALDatasetH)poDataset); return raw_data; }
- 在R中编译并调用:
library(Rcpp) sourceCpp("read_geotiff_raw.cpp") # 直接读取为raw向量 raw_data <- read_geotiff_raw("your_large_file.tif")
说明:这种方式直接从GDAL读取原始字节数据,没有任何中间类型转换,内存占用完全等于原始文件的无符号字节数据大小(约12GB),是内存效率最高的方案。
方法3:使用rgdal包(旧方法,已逐步弃用)
如果仍在使用已弃用的rgdal包,可以通过底层函数读取为raw类型:
library(rgdal) # 打开数据集 ds <- GDAL.open("your_large_file.tif") # 获取总波段数 n_bands <- GDAL.getRasterCount(ds) # 读取所有波段为raw数据 raw_data <- getRasterData(ds, band = 1:n_bands, type = "raw") # 关闭数据集 GDAL.close(ds)
说明:rgdal已被terra和sf替代,官方不再维护,仅建议用于旧项目兼容。
内容的提问来源于stack exchange,提问作者GG Bond
相关产品推荐
相关产品推荐

