15

I was looking for a road shapefile for Australia today. I ended up going to Geofabrik. Open Street Map has data in .osm format. But they do not have one in .shp for Australia.

If possible, I want to convert the osm files to shapefiles using R. I have searched around, but I have not found solutions yet. Is there any way to to this? Alternatively, is it possible to read osm files into R and convert the data to data frame so that I can draw figures using ggplot2?

I have achieved the following graphic of NZ using two shapefiles with maptoolsand ggplot2. Ideally, I want to produce a similar map of Australia.

enter image description here

  • What do you want to do with the road files - just display them on a map, or some kind of analysis? Shapefiles have some limitations; you may be better off using another format! – Simbamangu Oct 2 '14 at 4:58
  • @Simbamangu I want to initially display roads on a map. If not shapefile, what format do you recommend to use with R? – jazzurro Oct 2 '14 at 5:03
10

This is not an R solution, but Quantum GIS (QGIS) is a great way to achieve what you want.

You can simply load the .osm file (Add Vector tool), right-click it in the Table of Contents and Save As ESRI Shapefile.

QGIS may crash with such a large extract, so to avoid this you can uses OSM Tools like the OverPass API to download only what you need using bounding boxes.

The OverPass-Turbo Api is also available to obtain extracts, a short tutorial on that is Here!

I ran a quick example based on highway=primary and highway=primary_link tags (The OSM Highway Tagging Scheme can be see Here!) using the Wizard on Overpass-Turbo and the image below was the result for Victoria.

I then exported the data as GeoJSON, loaded that into QGIS then saved the result as a shape file. (The second image shows the lines and polys loaded into QGIS)

The other alternative is to download the PBF or OSM file for the area from GeoFabrik and subset the data by extracting the highway=* tags using Osmosis. If you wish to update yor data on a regular basis, then Osmosis would be the recommended way to proceed. If it is a one off extract, the Overpass would probably be easier, even though you have to do it in smaller bounding boxes because of memory limitations. You would just apply the same Overpass queries do different bounding boxes.

Highway=Primary OverPass-Turbo Results

Exported GeoJSON loaded into QGIS

  • 2
    Nat as simple as you think: the australia.osm.pbf is 195MB large (compressed), so I assume it will crash QGIS to load all data. I suggest to filter the desired road information with osmfilter or osmosis before feeding QGIS with the data. – AndreJ Oct 2 '14 at 5:11
  • @Andre, valid point, will update the answer appropriately! – Mark Cupitt Oct 2 '14 at 5:14
  • 1
    Thank you very much letting me know another way to handle my task. I learned something new from you. Cheers. – jazzurro Oct 3 '14 at 0:40
10

@jazzurro, you perfectly can do this with R, just look up osmar package! Read the osmar documentation (osmar.r-forge.r-project.org/RJpreprint.pdf). At pages 11 pp. you can find a detailed example for extracting roads/highways by the according tags for munich.osm! After pulling and extracting the data from a planet file for Australia you can convert to any format you wish!

Edit:

As some commentators were complaining about lacking examples I'll post an example from the docs. IMHO it wouldn't be necessary to retype existing examples here, would it?

library(maptools)
library(osmar)
url <- "http://osmar.r-forge.r-project.org/"
file <- "muenchen.osm.gz"
download.file(sprintf("%s%s", url, file), file)
unzip("gzip -d muenchen.osm.gz") # gzip is linux only, on windows I unzipped this manually with 7zip!

src <- osmsource_osmosis(file = "muenchen.osm")
muc_bbox <- center_bbox(11.575278, 48.137222, 3000, 3000)
muc <- get_osm(muc_bbox, src)
muc
summary(muc)

hw_ids <- find(muc, way(tags(k == "highway")))
hw_ids <- find_down(muc, way(hw_ids))
hw <- subset(muc, ids = hw_ids)

plot(muc)
plot_ways(hw, add = TRUE, col = "green")

# convert to spatial object (SpatialLinesDataFrame)
# and save to whatever format you like..
hw_line <- as_sp(hw, "lines")

enter image description here

  • Thank you very much for the link. I have seen one or two posts related to the package. But I was not sure if the package can convert .osm files to data frame. Having a quick look, it seems there is no direct way to convert .osm files to data frame. Or is there? – jazzurro Oct 2 '14 at 6:12
  • Read the osmar documentation (osmar.r-forge.r-project.org/RJpreprint.pdf).. At pages 11 pp. you can find a detailed example for extracting roads/highways by the according tags for munich.osm! After pulling and extracting the data from a planet file for Australia you can convert to any format you wish! ps: removed the other link from the OP as this didn't address dealing with osm-files.. – Kay Oct 2 '14 at 7:11
  • 1
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. – SS_Rebelious Oct 2 '14 at 8:10
  • @SS_Rebelious, It clearly does provide an answer. I don't know what you are trying to say. – Kay Oct 2 '14 at 11:38
  • @Kay To make this answer better, you could explain how to use the osmar package to obtain the desired results. – Zachary Oct 2 '14 at 12:13
7

OK, here comes the correct answer:

  • Make sure that rgdal (version >= 1.0.4) is installed

    install.packages('rgdal')
    packageVersion('rgdal')
    
    [1] ‘1.0.4’
    
  • Make sure that gdal (version >= 1.11.0) is installed

    library(rgdal)
    getGDALVersionInfo()
    
    [1] "GDAL 1.11.2, released 2015/02/10"
    
  • Make sure that gdal is compiled with Expat/OSM and SQLite support:

    c('SQLite', 'OSM') %in% ogrDrivers()$name
    
    [1] TRUE TRUE
    
  • Make sure that you know which layer you would like to save as shapefile:

    ogrListLayers('filename.osm.pbf')
    
    [1] "points" "lines" "multilinestrings" "multipolygons"
    attr(,"driver")
    [1] "OSM"
    attr(,"nlayers")
    [1] 4
    
  • We are ready to go:

    osm <- readOGR('filename.osm.pbf', 'lines')
    writeOGR(osm, 'myshapedir', 'mylayer', driver = 'ESRI Shapefile')
    

Once you read the file via readOGR, follow these guidelines to learn how to plot it with ggplot2.

Note that you can also read .osm files in XML format, just make sure that they are not compressed (i.e. extension is .osm not .osm.bz2) But try to use .osm.pbf file since they are much smaller.

1

osm2shp.ru here you can download openstreetmap data in shapefiles format. Data divided by regions: North and South America, Australia and Oceania, Africa, Europa and Asia.61 layers for download. Data filtered by "Map Features" conditions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.