使用 gdal 和 qt 打开相同的 tif 两次显示空白

Opening the same tif twice with gdal and qt shows it blank

本文关键字:两次 空白 显示 tif qt gdal 使用      更新时间:2023-10-16

注意:自从我尝试使用C++版本和C版本的API以来,我添加了CC++标签。

我必须加载一个geotiff文件才能沿汽车轨迹显示它。首先,我使用 API 打开文件gdal C++从中提取一些信息:

double  geo_transform[6];
GDALDataset* data = (GDALDataset*) GDALOpenShared( "MyRaster.tif", GA_ReadOnly );
if(data) {
  size[0] = data->GetRasterXSize();
  size[1] = data->GetRasterYSize();
  qDebug() << "RASTER TOTAL BANDS:" << data->GetRasterCount();
  if( CE_None == data->GetGeoTransform( geo_transform ) ) {
    qDebug() << "RASTER TL:" << geo_transform[0] << geo_transform[3];
    qDebug() << "RASTER SIZE:" << size[0] << size[1];
    qDebug() << "RASTER ROTATIONS:" << geo_transform[2] << geo_transform[4];
    qDebug() << "PIXEL SIZE:" << geo_transform[1] << geo_transform[5];
    toret = true;
  }
  /*
  *  Retrieve the pixel size and top left corner and store it in a proper variable.
  */
  GDALClose(data);

然后,在不同的线程(通过QThread启动)中,我将图像"加载"到QPixmap(这是我加载栅格的类的变量。在构造函数中,它被初始化为空的像素图):

temp_pixmap.load( "MyRaster.tif" );

这似乎有效,因为显示了光栅,我可以缩放它、平移它等。

问题是我只能打开同一个文件一次。如果我想将栅格加载到两个不同的像素图中,那么第一个可以附加到轨迹,第二个可用于进行注释,第二个以空白加载。

我尝试了这些变体,但没有成功:

变体 1:GDALDataSource 指针作为类的变量并在析构函数中调用GDALClose

变化 2:我没有用GDALOpen打开栅格,而是用GDALOpenShared尝试了一下,然后在析构函数中关闭了它。

变化 3:使用 C 版本:

  GDALDatasetH  hDataset;
  hDataset = GDALOpen( Element::getFilePath().c_str(), GA_ReadOnly );
  if( hDataset != NULL ) {
    GDALDriverH   hDriver;
    hDriver = GDALGetDatasetDriver( hDataset );
    if( GDALGetGeoTransform( hDataset, geo_transform ) == CE_None ) {
     // Get the size and top left corner...
    }
  }
  GDALClose(hDataset);

在 API 教程的关闭数据集部分中,有以下内容:

Forgetting to call GDALClose on a dataset opened in update mode in a popular format like GTiff will likely result in being unable to open it afterwards

如果READ_ONLY模式,我已经打开了数据集,并确保始终调用Close。那么,当它将栅格加载到像素图中时,问题是否出在Qt端?

新增功能:

在与遇到相同问题的同事交谈后,我们认为问题出在gdal方面,因为栅格似乎没有正确关闭,这迫使 API 教程中解释的行为。我会继续调查...

注意:这是暂时的,并不令人满意。我仍在寻找更好的解决方案。因此,如果有人知道一种方法,请发布答案,我将感激地接受并投赞成票。

我现在使用的解决方案是在需要检查另一个栅格时关闭栅格。我们的应用程序有一个树小部件,显示我们打开了多少项目(及其类型)。因此,当我们选择链接到轨迹的栅格时,只需在加载时将其关闭(例如在本例中,我们需要将其打开两次)并重新打开即可。

然后,当我们需要单独处理栅格时,我们必须在链接节点中关闭它,然后在我独自一人在这里节点中重新打开它。

真的很痛苦。