3

GDAL version: 2.1.1

Language: C++

Given the path of a geospatial file, I want to know whether the file is a raster or vector format. The only way I have found so far to make that distinction is to attempt to open the file as vector format first. If that succeeds, then treat it as a vector file; otherwise, attempt to open the file as raster format. The following code snippet is an example.

This worked for GeoTIFF and shape files.

However, for a DTED file, opening it with the GDAL_OF_VECTOR flag gives me a valid dataset handle. So, my code incorrectly decides that it is a vector format.

Why did GDALOpenEx() open the DTED file when the GDAL_OF_VECTOR flag was used?

void test( string const & path )
{
  GDALDatasetH hDataset;
  bool isRaster = false;

  unsigned int openFlags = GA_ReadOnly | GDAL_OF_VECTOR;
  hDataset = GDALOpenEx( path.c_str(), openFlags, NULL, NULL, NULL );
  if ( hDataset )
  {
    printf( "Opened as vector\n" );
    isRaster = false;
  }
  else
  {
    openFlags = GA_ReadOnly;
    hDataset = GDALOpenEx( path.c_str(), openFlags, NULL, NULL, NULL );
    if ( hDataset )
    {
      printf( "Opened as raster\n" );
      isRaster = true;
    }
    else
    {
      printf( "Not opened, skip it\n" );
      return;
    }
  }

  // Process the file differently, depending on its format.
  if ( isRaster )
  {
    ...
  }
  else
  {
    ...
  }

  GDALClose( hDataset );
}
  • I already suspect that the answer is that the GDAL_OF_VECTOR flag does not mean what I think it means. The comment for that flag is, "Allow vector drivers to be used". So, using the GDAL_OF_VECTOR flag may not exclude raster drivers from being considered, it just includes the vector drivers. Which means I am at the mercy of the arbitrary order in which the drivers are considered. – Mike Finch Oct 22 '16 at 16:24
  • But then, why did it work for GeoTIFF and not for DTED? – Mike Finch Oct 22 '16 at 16:33
  • I suspect the DTED file extension and internal structure are too generic and like you say,, depending on which driver is considered first it could conform closely enough to some vector format to be considered as such. You could try running the block twice, the first time without the GDAL_OF_VECTOR flag... or putting some specific condition for that format – Mike Oct 22 '16 at 17:53
  • For future reference, GDAL_OF_VECTOR does mean what you thought it meant, i.e only try vector drivers. However when you attempted to open the DTED file with the GDAL_OF_VECTOR flag, the SEG-Y driver opens it "successfully". I think it's a bug in the SEG-Y driver. – user2856 May 4 '17 at 6:18
4

You can use GetRasterCount() to test if the dataset is raster and GetLayerCount() for vector.

http://osgeo-org.1560.x6.nabble.com/Discover-whether-a-GDALDataset-is-raster-or-vector-td5270223.html

For future reference, GDAL_OF_VECTOR does mean what you thought it meant, i.e only try vector drivers. However when you attempted to open the DTED file with the GDAL_OF_VECTOR flag, the SEG-Y driver opens it "successfully". I think it's a bug in the SEG-Y driver.

For example (in python):

from osgeo import gdal
print(gdal.__version__)

f = "n43.dt0"
ds = gdal.OpenEx(f, gdal.OF_VECTOR)

drv = ds.GetDriver()
print(drv.GetMetadata())

Output:

2.1.3
{'DCAP_OPEN': 'YES', 
 'DCAP_VECTOR': 'YES', 
 'DCAP_VIRTUALIO': 'YES', 
 'DMD_HELPTOPIC': 'drv_segy.html', 
 'DMD_LONGNAME': 'SEG-Y'}
2

The following is my new function for detecting whether the file is raster or vector. Based on the answer from @Luke. I call it at the beginning of the program, which will open and close the file once. Then I open the file again using the appropriate flags.

struct Format
{
  enum Enum
  {
    NONE = 0,
    RASTER,
    VECTOR,
  };
};

Format::Enum GetFileFormat( string const & path )
{
  Format::Enum format = Format::NONE;

  // When I just need to know the number of raster bands and layers,
  // opening the file with GDAL_OF_VECTOR is not necessary.
  unsigned int openFlags = GA_ReadOnly; // | GDAL_OF_VECTOR;

  GDALDataset * pDataset = static_cast<GDALDataset *>( GDALOpenEx( path.c_str(), openFlags, NULL, NULL, NULL ) );
  if ( pDataset )
  {
    int rasterCount = pDataset->GetRasterCount();
    int layerCount = pDataset->GetLayerCount();
    if ( rasterCount > 0 && layerCount == 0 )
    {
      format = Format::RASTER;
    }
    else if ( rasterCount == 0 && layerCount > 0 )
    {
      format = Format::VECTOR;
    }
  }

  GDALClose( pDataset );

  return format;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.