2015-04-13 4 views
5

В настоящее время я ищу файлы с картами, размеры которых не превышают размеры муниципалитетов в Мексике (по величине, около 3 градусов по долготе/широта). Однако при попытке сделать это я столкнулся с проблемами памяти (по крайней мере). Размер файла для объекта OSM XML составляет 1,9 ГБ для справки.Как делить очень большой файл OpenStreetMap на более мелкие файлы в R, не заканчивая память?

library(osmar) 
get.map.for.municipality<-function(province,municipality){ 
    base.map.filename = 'OpenStreetMap/mexico-latest.osm' 
    #bounds.list is a list that contains the boundaries 
    bounds = bounds.list[[paste0(province,'*',municipality)]] 
    my.bbox = corner_bbox(bounds[1],bounds[2],bounds[3],bounds[4]) 
    my.map.source = osmsource_file(base.map.filename) 
    my.map = get_osm(my.bbox,my.map.source) 
    return(my.map) 
} 

Я запускаю это внутри цикла, но он не может даже пройти мимо первого. Когда я попытался запустить его, мой компьютер застыл, и я смог снять снимок экрана с телефона. Память неуклонно наклонена в течение нескольких минут, а затем она быстро поднялась, и я не мог реагировать, прежде чем мой компьютер застыл.

Что является лучшим способом сделать это? Я ожидаю, что этот цикл займет около 100-150 раз, поэтому любой способ, который более эффективен с точки зрения памяти, поможет. Я бы предпочел не загружать файлы меньшего размера из службы API. В случае необходимости, я бы хотел использовать другой язык программирования (желательно Python или C++), но я предпочитаю держать это в R.

enter image description here

+4

Одна вещь, которая удивляет меня от изучения кода пакета «osmar», заключается в том, что он никогда не использует ограничительную рамку в * all * в 'get_osm'. Введите 'get_osm', и вы увидите, что' x' передается как второй аргумент 'get_osm_data' и не использует его впоследствии. Но посмотрите на 'osmar ::: get_osm_data.osmfile', и это просто' readLines (source $ file) '. Он полностью игнорирует ограничивающий прямоугольник. Неудивительно, что у него заканчивается память! –

+3

В качестве еще одного доказательства, создайте образец небольшого OSM-файла с именем 'test.osm'. Затем попробуйте 'get_osm (blablabla, source = osmsource_file (" test.osm "))'. (Это не пример псевдокода: буквально введите 'blablabla'). Функция работает нормально. Он никогда не использует ограничительную рамку, чтобы аргумент никогда не оценивался! (Он использует поле только тогда, когда он запрашивает API). –

+3

В любом случае вам необходимо проанализировать XML-файл итеративно, выкинув узлы, которые не попадают в ограничительную рамку. Насколько я знаю, R не имеет инструментов для этого. У Python есть [iterparse] (http://effbot.org/zone/element-iterparse.htm), который вам больше повезет с –

ответ

2

Я предлагаю не использовать R для этого.

Есть лучшие инструменты для этой работы. Много способов разделить, фильтровать материал из командной строки или использовать DBMS.

Вот некоторые варианты, извлеченные из OSM Wiki http://wiki.openstreetmap.org:

Filter your osm files using osmfilter: «osmfilter используется для фильтрации файлов данных OpenStreetMap для конкретных тегов Вы можете определить различные виды фильтров, чтобы получить объекты OSM (то есть узлы, пути. , отношения), включая их зависимые объекты, например узлы путей, пути отношений, отношения других отношений ».

Отсечение на основе многоугольников или границ с использованием osmconvert: http://wiki.openstreetmap.org/wiki/Osmconvert#Applying_Geographical_Borders

Вы можете написать Баш скрипты для обоих osmfilter и osmconvert, но я бы рекомендовал использовать СУБД. Просто импортируйте в PostGIS, используя osm2pgsql, и соедините свой R-код с любым драйвером Postgresql. Это оптимизирует операции чтения/записи.