在GDAL C++API中获取内存中数据集的原始缓冲区



我使用GDALTranslate()/vsimem/文件路径在内存中生成了一个GeoTiff数据集。我需要访问实际GeoTiff文件的缓冲区,以便将其放入外部API的流中。我的理解是,VSIGetMemFileBuffer()应该可以实现这一点,但除了nullptr之外,我似乎无法返回任何其他内容。

我的代码基本如下:

//^^ GDALDataset* srcDataset created somewhere up here ^^
//psOptions struct has "-b 4" and "-of GTiff" settings.
const char* filep = "/vsimem/foo.tif";
GDALDataset* gtiffData = GDALTranslate(filep, srcDataset, psOptions, nullptr);
vsi_l_offset size = 0;
GByte* buf = VSIGetMemFileBuffer(filep, &size, true); //<-- returns nullptr

gtiffData似乎是一个真正的检查数据集,它具有所有适当的属性(带的数量、光栅大小等(。当我向GDALTranslate()而不是/vsimem/路径提供一个真实的文件系统位置,并将其加载到QGIS中时,它也会正确呈现。

查找VSIGetMemFileBuffer()的源,实际上应该只有在找不到文件的情况下才返回nullptr。这表明我用错了。有人知道什么是正确的用法吗?

加分:有没有更好的方法(流式传输文件(?

谢谢!

我对C++API一无所知。但在Python中,我有时会使用下面的片段来获取in-mem文件的内容。在我的情况下,主要是VRT,但对于其他格式应该没有任何不同。

但是如前所述,我不知道VSI api是否将1对1转换为C++。

from osgeo import gdal
filep = "/vsimem/foo.tif"
# get the file size
stat = gdal.VSIStatL(filep, gdal.VSI_STAT_SIZE_FLAG)
# open file
vsifile = gdal.VSIFOpenL(filep, 'r')
# read entire contents
vsimem_content = gdal.VSIFReadL(1, stat.size, vsifile)

在VRT的情况下,内容将是文本,显示为类似print(vsimem_content.decode())的内容。对于tiff,它当然是二进制数据。

我在找到解决方法后又回到了这个问题上,在重新交换后,它似乎工作得很好@mmomtchev建议查看CPL_DEBUG的输出,它没有显示任何异常(在实际的VSIGetMemFileBuffer调用过程中是静默的(。

特别是,由于其他原因,我不得不在调用GDALTranslate和访问缓冲区之间放入一个GDALWarp调用,这似乎就是区别所在。我的猜测是GDALWarp在内部调用VSIFOpenL——尽管我在源代码中找不到——这对VSIGetMemFileBuffer进行了某种初始化。为其他遇到这种情况的人尝试一下。

最新更新