2015-04-13 5 views
5

Ich bin derzeit auf der Suche nach Kartendateien, die nicht größer als die Größen der Gemeinden in Mexiko sind (am größten, etwa 3 Grad Länge/Breite über). Ich habe jedoch (zumindest) Probleme mit dem Speicher bekommen, als ich das versuchte. Die Dateigröße des OSM-XML-Objekts beträgt 1,9 GB.Wie unterteile ich eine sehr große OpenStreetMap-Datei in kleinere Dateien in R, ohne den Arbeitsspeicher zu verlieren?

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) 
} 

Ich laufe das innerhalb einer Schleife, aber es kann nicht einmal über die erste hinaus. Als ich es versuchte, lief mein Computer und ich konnte nur einen Screenshot mit meinem Handy machen. Die Erinnerung nahm im Laufe von ein paar Minuten stetig zu, und dann schoss es wirklich schnell hoch, und ich konnte nicht reagieren, bevor mein Computer erstarrte.

Was ist ein besserer Weg, dies zu tun? Ich gehe davon aus, dass ich diese Schleife ungefähr 100-150 Mal ausführen muss, also würde jede Art von Speicher, die effizienter ist, helfen. Ich würde es vorziehen, kleinere Dateien von einem API-Dienst nicht herunterzuladen. Wenn nötig, würde ich bereit sein, eine andere Programmiersprache zu verwenden (vorzugsweise Python oder C++), aber ich ziehe diese

enter image description here

+4

Eine Sache, die mich davon überrascht, den Code des 'osmar'-Pakets zu erforschen, ist, dass es nie die Begrenzungsbox bei * all * in' get_osm' benutzt. Geben Sie 'get_osm' ein und Sie werden sehen, dass' x' als zweites Argument von 'get_osm_data' übergeben wird und danach nicht mehr verwendet wird. Aber sieh dir 'osmar ::: get_osm_data.osmfile' an und es ist nur' readLines (source $ file) '. Es ignoriert die Begrenzungsbox vollständig. Kein Wunder, dass es keine Speicher mehr hat! –

+3

Als weiteren Beweis erstellen Sie eine kleine Beispiel-OSM-Datei mit dem Namen 'test.osm'. Dann versuche 'get_osm (blablabla, source = osmsource_file (" test.osm "))' '. (Das ist kein Pseudocode-Beispiel: wörtlich "blablabla" eingeben). Die Funktion funktioniert einwandfrei. Es verwendet nie die Bounding Box, so dass das Argument nie ausgewertet wird! (Es verwendet die Box nur, wenn es eine API abfragt). –

+3

In jedem Fall müssen Sie die XML-Datei iterativ analysieren und Knoten auswerfen, die nicht in die Bounding Box fallen. Soweit ich weiß, hat R dafür kein Werkzeug. Python hat [iterparse] (http://effbot.org/zone/element-iterparse.htm), womit Sie mehr Glück haben sollten mit –

Antwort

2

in R. halten würde ich dafür verwenden R empfehlen nicht.

Es gibt bessere Werkzeuge für diesen Job. Viele Möglichkeiten zum Teilen, filtern Sie Zeug von der Befehlszeile oder mit einem DBMS.

Hier sind einige aus der OSM extrahiert Alternativen Wiki http://wiki.openstreetmap.org:

Filter your osm files using osmfilter: „osmfilter verwendet OpenStreetMap Datendateien nach bestimmten Tags filtern Sie verschiedene Arten von Filtern definieren können OSM Objekte zu erhalten (dh Knoten, Wege. Beziehungen), einschließlich ihrer abhängigen Objekte, zB Knoten von Wegen, Wegen von Beziehungen, Beziehungen anderer Beziehungen. "

Clipping auf Basis von Polygonen oder Grenzen mit osmconvert: http://wiki.openstreetmap.org/wiki/Osmconvert#Applying_Geographical_Borders

Sie können sowohl Bash-Skripte für osmfilter und osmconvert schreiben, aber ich würde empfehlen, ein DBMS verwenden. Importieren Sie einfach mit osm2pgsql in PostGIS und verbinden Sie Ihren R-Code mit einem beliebigen Postgresql-Treiber. Dies optimiert Ihre Lese-/Schreiboperationen.