Анализ данных osm.pbf с использованием модуля Python GDAL/OGR

Я пытаюсь извлечь данные из файла OSM.PBF с помощью модуля python GDAL/OGR.

В настоящее время мой код выглядит так:

import gdal, ogr

osm = ogr.Open('file.osm.pbf')

## Select multipolygon from the layer
layer = osm.GetLayer(3) 
# Create list to store pubs
pubs = []
for feat in layer:
    if feat.GetField('amenity') == 'pub':
         pubs.append(feat)

Хотя этот небольшой кусочек кода отлично работает с файлами small.pbf (15 МБ). Однако при разборе файлов размером более 50 Мб я получаю следующую ошибку:

 ERROR 1: Too many features have accumulated in points layer. Use OGR_INTERLEAVED_READING=YES MODE

Когда я включаю этот режим с помощью:

gdal.SetConfigOption('OGR_INTERLEAVED_READING', 'YES')

ogr больше не возвращает никаких функций, даже при разборе небольших файлов.

Кто-нибудь знает, что здесь происходит?

1 ответ

Благодаря ответу Скай, я смог понять это.

Специальный шаблон чтения, необходимый для чтения с чередованием, упомянутый в gdal.org/1.11/ogr/drv_osm.html, переведен в рабочий пример Python, который можно найти ниже.

Это пример того, как извлечь все функции в файле.osm.pbf, которые имеют тег "amenity=pub"

import gdal, ogr

gdal.SetConfigOption('OGR_INTERLEAVED_READING', 'YES')
osm = ogr.Open('file.osm.pbf')

# Grab available layers in file
nLayerCount = osm.GetLayerCount()

thereIsDataInLayer = True

pubs = []

while thereIsDataInLayer:

    thereIsDataInLayer = False

    # Cycle through available layers
    for iLayer in xrange(nLayerCount):

        lyr=osm.GetLayer(iLayer)

        # Get first feature from layer
        feat = lyr.GetNextFeature()

        while (feat is not None):

             thereIsDataInLayer = True

             #Do something with feature, in this case store them in a list
             if feat.GetField('amenity') == 'pub':
                 pubs.append(feat)

             #The destroy method is necessary for interleaved reading
             feat.Destroy()

             feat = lyr.GetNextFeature()

Насколько я понимаю, вместо цикла for необходим цикл while, потому что при использовании метода чтения с чередованием невозможно получить счет возможностей коллекции.

Будем весьма благодарны за разъяснение, почему этот фрагмент кода работает так, как он работает.

Другие вопросы по тегам