Upgrading one of my GIS Python tool which uses GDAL/OGR to read vectors and rasters datasets, I've installed the last GDAL pypi package in version 2.1.3.
Until now, I do:
driver = ogr.GetDriverByName(str("ESRI Shapefile"))
source_ogr = driver.Open(shp_path, 0)
# or directly source_ogr = ogr.Open(shp_path, 0)
print(type(source_ogr))
>>> <class 'osgeo.ogr.DataSource'>
But when I checked the help, I see:
print(help(driver.Open))
[...]
NOTE: Starting with GDAL 2.0, it is *NOT* safe to cast the returned
handle to OGRDataSource*. If a C++ object is needed, the handle should
be cast to GDALDataset*. Similarly, the returned OGRSFDriverH handle
should be cast to GDALDriver*, and NOT* OGRSFDriver*.
Deprecated Use GDALOpenEx() in GDAL 2.0
[...]
And looking for more information, RFC 46 says:
A global pass has been made to in-tree OGR drivers that have to open a
file to determine if they recognize it. They have been converted to
GDALDriver to accept a GDALOpenInfo argument and they now use its
pabyHeader field to examine the first bytes of files. The number of
system calls realated to file access (open/stat), in order to
determine that a file is not recognized by any OGR driver, has now
dropped from 46 in GDAL 1.11 to 1. The converted drivers are :
AeronavFAA, ArcGEN, AVCBin, AVCE00, BNA, CSV, DGN, EDIGEO, ESRI
Shapefile, GeoJSON, GeoRSS, GML, GPKG, GPSBabel, GPX, GTM, HTF, ILI1,
ILI2, KML, LIBKML, MapInfo? File, MySQL, NAS, NTF, OpenAIR, OSM, PDS,
REC, S57, SDTS, SEGUKOOA, SEGY, SOSI, SQLite, SUA, SVG, TIGER, VFK,
VRT, WFS
Indeed, using gdal.OpenEx it seems to work:
source_gdal = gdal.OpenEx(shp_path, 0)
pringt(type(source_gdal))
>>> <class 'osgeo.gdal.Dataset'>
And two objects are not identical:
print(source_ogr == source_gdal)
>>> False
Which method is better?
==== EDIT after first comments
# with OGR: note the GetName method
driver = ogr.GetDriverByName(str("OpenFileGDB"))
src = driver.Open(source_path, 0)
print(type(src), dir(src), len(dir(src)))
>>> <class 'osgeo.ogr.DataSource'> ['CommitTransaction', 'CopyLayer', 'CreateLayer', 'DeleteLayer', 'Dereference', 'Destroy', 'ExecuteSQL', 'FlushCache', 'GetDescription', 'GetDriver', 'GetLayer', 'GetLayerByIndex', 'GetLayerByName', 'GetLayerCount', 'GetMetadata', 'GetMetadataDomainList', 'GetMetadataItem', 'GetMetadata_Dict', 'GetMetadata_List', 'GetName', 'GetRefCount', 'GetStyleTable', 'GetSummaryRefCount', 'Reference', 'Release', 'ReleaseResultSet', 'RollbackTransaction', 'SetDescription', 'SetMetadata', 'SetMetadataItem', 'SetStyleTable', 'StartTransaction', 'SyncToDisk', 'TestCapability', '__class__', '__del__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__len__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__swig_destroy__', '__weakref__', 'name', 'this', 'thisown'] 59
# with GDAL: note that the method list is different and GetName method is missing
src = gdal.OpenEx(source_path, 0)
print(type(src), dir(src), len(dir(src)))
>>> <class 'osgeo.gdal.Dataset'> ['AddBand', 'BeginAsyncReader', 'BuildOverviews', 'CommitTransaction', 'CopyLayer', 'CreateLayer', 'CreateMaskBand', 'DeleteLayer', 'EndAsyncReader', 'ExecuteSQL', 'FlushCache', 'GetDescription', 'GetDriver', 'GetFileList', 'GetGCPCount', 'GetGCPProjection', 'GetGCPs', 'GetGeoTransform', 'GetLayer', 'GetLayerByIndex', 'GetLayerByName', 'GetLayerCount', 'GetMetadata', 'GetMetadataDomainList', 'GetMetadataItem', 'GetMetadata_Dict', 'GetMetadata_List', 'GetProjection', 'GetProjectionRef', 'GetRasterBand', 'GetStyleTable', 'GetSubDatasets', 'GetTiledVirtualMem', 'GetTiledVirtualMemArray', 'GetVirtualMem', 'GetVirtualMemArray', 'RasterCount', 'RasterXSize', 'RasterYSize', 'ReadAsArray', 'ReadRaster', 'ReadRaster1', 'ReleaseResultSet', 'RollbackTransaction', 'SetDescription', 'SetGCPs', 'SetGeoTransform', 'SetMetadata', 'SetMetadataItem', 'SetProjection', 'SetStyleTable', 'StartTransaction', 'TestCapability', 'WriteRaster', '__class__', '__del__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__swig_destroy__', '__weakref__', 'this', 'thisown'] 76
Best Answer
In GDAL 2 the OGRDatasource was merged with GDALDataset.
And now all classes inherited from one class - GDALDataset. The OpenEx is preferable to use in GDAL 2 and higher versions. The different between source_ogr and source_gdal is because python binding features.