To import OSM spatial data into R, you can either make direct queries in
the OSM’s API or you can download an OSM file an then open it into R.
The first alternative only operates for small bounding boxes (0.25 x
0.25 coordinates range), whereas the second alternative allows bigger
bounding boxes. For either alternative, we will need the package
osmar
.
When importing OSM spatial data, the key is knowing which file format
you are dealing with. In this tutorial we will work with .osm
, the
native OSM file extension and geoJSON
, the default file extension in
the platform Overpass Turbo. We will open .osm
files with the package
osmar
, whereas we will open .geoJSON
files with the package rgdal
.
library(osmar)
## Loading required package: XML
## Loading required package: RCurl
## Loading required package: geosphere
##
## Attaching package: 'osmar'
## The following object is masked from 'package:utils':
##
## find
library(rgdal)
## Loading required package: sp
## rgdal: version: 1.4-8, (SVN revision 845)
## Geospatial Data Abstraction Library extensions to R successfully loaded
## Loaded GDAL runtime: GDAL 2.2.3, released 2017/11/20
## Path to GDAL shared files: C:/Users/rente/OneDrive/Documents/R/win-library/4.0/rgdal/gdal
## GDAL binary built with GEOS: TRUE
## Loaded PROJ.4 runtime: Rel. 4.9.3, 15 August 2016, [PJ_VERSION: 493]
## Path to PROJ.4 shared files: C:/Users/rente/OneDrive/Documents/R/win-library/4.0/rgdal/proj
## Linking to sp version: 1.4-1
We will use the Open Street Map API, which URL is
https://api.openstreetmap.org/api/0.6/
(an alternative is this mirror:
http://overpass-api.de/api/
). As this alternative has a limited
bounding box span, first, we will define our bounding box. In this
example, I am creating an object with the bounding box for the
Washington Park in Albany, NY by using the function corner_bbox()
.
box.wpark = corner_bbox(-73.7774,42.6530,-73.7652,42.6623)
Next, I will create an object with the API’s URL with the function function osmsource_api().
api.wpark = osmsource_api(url = "https://api.openstreetmap.org/api/0.6/")
The function get_osm
will download the map wpark
for the bounding
box box.wpark
from the repository api.wpark
.
wpark = get_osm(box.wpark, source = api.wpark)
class(wpark)
## [1] "osmar" "list"
You can now manage the map in R as an OSM object. However, this object
is not rendered yet as a map (try, for example, typing plot(wpark)
). A
great value of OSM and GeoJSON files is that they comprise multiple
layers (e.g., points, lines and polygons) in the same file, but this
complicates the processing of maps in R. Every layer should be in a
separate object. Therefore, to effectively use OSM data, we need to
transform the .osm
file into a spatial object. To do so, we must use
the function as_sp()
.
area.wpark = as_sp(wpark,what="polygons") # Extract the polygons
street.wpark = as_sp(wpark,what="lines") # Extract the lynes
attr.wpark = as_sp(wpark,what="points") # Extract the points
Now we have spatial data. As an example, I will plot the three types of
spatial data that were residing in the .osm
:
class(area.wpark)
## [1] "SpatialPolygonsDataFrame"
## attr(,"package")
## [1] "sp"
plot(area.wpark, col = "gray")
plot(area.wpark, col = "gray")
plot(street.wpark, add = TRUE, col = "blue")
plot(area.wpark, col = "gray")
plot(attr.wpark, add = TRUE, col="red", pch = 1)
To follow this example, you must download into your computer the
follwing file
https://github.com/crenteriam/crenteriam.github.io/blob/master/files/tutorials/tutorial-osm/_albany.osm
.
Once you have downloaded the file, set the working directory and open
the file by using the function osmsource_file()
.
source.albany=osmsource_file("_albany.osm")
Next, we wil ltransform the file into an osmar
object. In this case,
since the file already contains the bounding box, we replace the
information of the bounding box by complete_file()
and transform the
osmar
object into spatial objects.
albany = get_osm(complete_file(), source = source.albany)
area.albany = as_sp(albany, what = "polygons")
street.albany = as_sp(albany,what = "lines")
Plot the results.
plot(area.albany)
plot(street.albany,add=TRUE,col="green")
To follow this example, you must download into your computer the
follwing file
https://github.com/crenteriam/crenteriam.github.io/blob/master/files/tutorials/tutorial-osm/_highways.geojson.osm
.
This file was downloaded from Overpass Turbo (OT).
In this case, you will need the rgdal
package. In the firs line below,
I inspect the structure of the GeoJSON file with ogrListLayers()
. In
the second line I inspect the attributes for each layer by using
ogrInfo()
. You need to specify the file, the extension (“OGRGeoJSON”).
The option wkbLineString
provides the attributes for the lines layer.
ogrListLayers("highways.geojson")
ogrInfo("highways.geojson", "OGRGeoJSON", require_geomType = "wkbLineString")
# The alternative layers are require_geomType="wkbPoint" OR require_geomType="wkbPolygon"
Then, I will convert this file into a spatial object. To do so, I will
use the function readOGR
, I will define the object highways.geojson
as the source, "OGRGeoJSON"
to tell R that the source is a GeoJSON
file and require_geomType="wkbLineString"
to extract only the lines
layer.
highways = readOGR("highways.geojson", "OGRGeoJSON", require_geomType = "wkbLineString")
class(highways)
With the information provided above you would be allowed to do your spatial analysis. However, if you need to export the objects as ESRI’s Shapefiles, use one of the two following lines:2
write a new shapefile with package rgdal (including .prj component)
writeOGR(highways, ".", "highways_prj", driver="ESRI Shapefile")
Further details in Reading and writing GeoJSON files in R ↩
See further details in RPOS 619 tutorialor Read and write ESRI Shapefiles with R ↩