19

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

2
  • 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
    Commented Oct 2, 2014 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
    Commented Oct 2, 2014 at 5:03

5 Answers 5

13

@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

9
  • 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
    Commented Oct 2, 2014 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
    Commented Oct 2, 2014 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. Commented Oct 2, 2014 at 8:10
  • @SS_Rebelious, It clearly does provide an answer. I don't know what you are trying to say.
    – Kay
    Commented Oct 2, 2014 at 11:38
  • 1
    @Kay To make this answer better, you could explain how to use the osmar package to obtain the desired results.
    – Zachary
    Commented Oct 2, 2014 at 12:13
12

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

3
  • 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
    Commented Oct 2, 2014 at 5:11
  • @Andre, valid point, will update the answer appropriately! Commented Oct 2, 2014 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
    Commented Oct 3, 2014 at 0:40
8

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.

3
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.

1

This is an old question with some good old answers.

Here an updated, full R solution using the packages osmdata to fetch the OSM data and sf to manage and save the geometry:

# install.packages("osmdata")
library(osmdata)
#> Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright
library(sf)
#> Linking to GEOS 3.7.2, GDAL 2.4.2, PROJ 5.2.0
# Check the available features
osmdata::available_features() %>% head()
#> [1] "4wd only"  "abandoned" "abutters"  "access"    "addr"      "addr:city"
# In our case, we are interested in 'highway'
selected_feature = "highway"
# Check available tags for the selceted feature
osmdata::available_tags(selected_feature) %>% head()
#> [1] "bridleway"    "bus_guideway" "bus_stop"     "construction" "corridor"    
#> [6] "crossing"
# For simplicity,we are going to download all
selected_tags = osmdata::available_tags(selected_feature)
# Create the request for Overpass API
q = osmdata::getbb ("Baranduda",
           display_name_contains="Australia",
           # limit=1e04,
           format_out = "polygon") %>%
  osmdata::opq() %>%
  osmdata::add_osm_feature(selected_feature
                  ,selected_tags)
# Download the data
o = osmdata::osmdata_sf(q)
# Street geometry can be lines (roads) and polygons (loops, roundabouts, etc.)
# We are going to merge the two type of geometry
# converting polygons to linestrings
full_street = o$osm_polygons %>%
  sf::st_cast("LINESTRING", warn=FALSE) %>%
  rbind(o$osm_lines)

# Save the file (here in temporary file)
output_file = tempfile(fileext=".shp")
sf::st_write(full_street, output_file)

You will get a warning when you save the data, due to the fact that field names are abbreviated for the shapefile format. I suggest you use a more up to date format such as .gpkg:

sf::st_write(full_street, "your-file-name.gpkg")

You can visualise the results with mapview:

mapview::mapview(full_street)

enter image description here

Created on 2020-05-04 by the reprex package (v0.3.0)

1
  • Thanks for adding this answer. It is always nice to revisit old questions and update with current solutions. Commented May 4, 2020 at 13:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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