I have managed to import an OSM PBF file into QGIS using ogr2ogr -> SQLite and then importing layers using the GUI- (essentially as per the first step in this answer :
ogr2ogr -f "SQLite" -dsco SPATIALITE=YES texas.db texas-latest.osm.pbf
My version of GDAL and OGR2OGR is 2.4.1 (as reported by both - I checked)
That appears to work fine. I'm trying to duplicate this in a Python plugin without the SQLite intermediate step. Points, lines, and multilines appear to be readable fine (exact same numbers of features). However, the total number of multipolygon features is significantly less. Further investigation shows the missing features are things like buildings which have an osm_way_id
set. I.e. these have been encoded in the PBF file as closed ways.
Here is an example imported with ogr2ogr:
The GDAL library code does not see any features with osm_way_id
set! (although it recognizes this is a valid field name). Here is my code:
gdal.SetConfigOption("OGR_INTERLEAVED_READING", "YES")
input_pbfname = "C:/Data/QGIS/Texas/texas-latest.osm.pbf"
ds = gdal.OpenEx(input_pbfname, gdal.OF_VECTOR)
if ds is None:
QMessageBox.information(None, "open failed", "Open failed")
nly = ds.GetLayerCount()
#version_num = int(gdal.VersionInfo('VERSION_NUM'))
#QMessageBox.information(None, "Version", str(version_num))
nPoints = 0
nLines = 0
nMultiLines=0
nPolygons = 0
# GetNextFeature handles interleaved reading correctly
for ily in range (0,nly):
layer = ds.GetLayerByIndex(ily)
layer.ResetReading()
feat = layer.GetNextFeature()
while feat is not None:
if layer.GetName() == "points":
nPoints = nPoints+1
elif layer.GetName() == "lines":
nLines = nLines+1
elif layer.GetName() == "multilinestrings":
nMultiLines = nMultiLines+1
elif layer.GetName() == "multipolygons":
nPolygons = nPolygons+1
idx = feat.GetFieldIndex("osm_way_id")
if idx>=0:
wayid = feat.GetFieldAsString(idx)
if (wayid is not None and wayid!="" and wayid!="0" ):
nWayId=nWayId+1
idx = feat.GetFieldIndex("osm_way_id")
if idx>=0:
# tried both GetFieldAsInteger and GetFieldAsString
# also tried counting all multipolygon features with osm_way_id set
wayid = feat.GetFieldAsInteger(idx)
if wayid == 646651935:
QMessageBox.information(None,"646651935 building found","Layer:"+layer.GetName() )
feat = layer.GetNextFeature()
QMessageBox.information(None, "Count", "Points: %d Lines:%d MultiLine:%d Poly:%d" % (nPoints,nLines,nMultiLines, nPolygons) )
# close the temporary layer
ds = None
So why are these "closed ways" getting imported correctly by ogr2ogr but not the GDAL api? Is there a flag or setting that I'm missing? Or another subtlety with the interleaving that I have missed? (I'm aware of the reasons for this with OSM data - in the past I've coded an OSM PBF reader in C#...)
ogr2ogr is importing 3385834 multipolygons, but the gdal API is only importing 10896. The other layers (point, line, multiline all match)