Skip to main content

Section C.3 Open Street Map

Finally we want to mention the possibility of getting geographic data from Open Street Map. Open Street Map is a database of geospatial information built by a community of mappers, enthusiasts and members of the public, who contribute and maintain data about all sorts of environmental features, such as roads, green spaces, restaurants and railway stations, amongst many other things, all over the world ([261]).
You can view the information contributed to Open Street Map using their online mapping platform (https://www.openstreetmap.org/). The result of people’s contributions is a database of spatial information rich in local knowledge which provides invaluable information about places and their features, without being subject to strict terms on usage.
Open Street Map data can be accessed using its API which stands for Application Programming Interface. An API can be understood as a tool which defines an interface for a programme to interact with a software component. For example, it defines the kind of requests or calls which can be made, and how these calls and requests can be carried out. Here, we are using the term “API” to denote tools created by an open data provider to give access to different subsets of their content. Such APIs facilitate scripted and programmatic extraction of content, as permitted by the API provider ([279]). APIs can take many different forms and be of varying quality and usefulness ([276]). APIs may also have wrappers which refer to any interface which makes them easier to access. For example, Open Street Map has a graphical user interface called Overpass Turbo (https://overpass-turbo.eu/), which allows users to build queries using any internet browser, and download and save the result.
Another wrapper comes in the form of an R package called osmdata. This package allows us to query the Open Street Map API and return the results of our query directly into R. We used this in Chapter 2 of this book, to query the location of pubs in Manchester. But we can also use this to source our boundary data as well.
Let’s begin by loading the library:
library(osmdata)
Our first task is to create a bounding box, so that we return only those data that fall within this box. Let’s continue to try and source data about Uganda, but let’s narrow in to the capital of Kampala. To get a bounding box the shape of Kampala, we can use the getbb() function:
kampala_bb <- getbb("kampala", format_out = "sf_polygon")
We should check on this object to make sure it looks the way we would expect:
ggplot() + geom_sf(data = kampala_bb) + theme_void()
A grey outline of Kampala, shaded light grey.
Figure C.3.1. Boundary which follows the shape of Kampala
That’s looking Kampala-shaped to us, so we can continue. To query Open Street Map, we have to build an Overpass Query, Overpass being the Open Street Map API. We can create this with the opq() function (which stands for Overpass Query) where we specify our bounding box object we created above. We can then pipe (%>%) our query elements to this. In the next step, we specify what features we want with the add_osm_feature() function. The parameters should define what we want, following the Overpass query language. We can look for things (nodes, ways, or relations if we’re being specific) using key value pairs. For example, to return all post boxes within an area, we need to use the amenity key and the post box value, or to find a museum you would use the tourism key and the museum value. To learn more about this, visit the OSM wiki ([261]).
To get administrative boundaries, we can use the key of admin_level, and for the value, we pass a number which can be any number between 2 and 10, where bigger numbers mean more granular resolution. For example admin_level = 2 is almost always a de-facto independent country, and admin_level=4 is usually equivalent to a “province”. However, numbers higher than 4 values vary in meaning between countries. You can look up the country specific levels on [280]. In Uganda, we can see that level 2 represents the borders of the 112 districts of Uganda, 4 the boundary of counties, and level 8 the boundary of sub-counties. Let’s use admin level 8 to map sub-counties in Kampala.
Finally, to make sure your query returns in sf format, append the osmdata_sf() to the end of the pipe.
bb_kampala <- getbb("kampala", format_out = "data.frame")

kampala_boundaries <- opq(bb_kampala) %>%
  add_osm_feature(key = "admin_level", value = "8") %>%
  osmdata_sf()
Now that we have the results, we can extract our boundary polygons, which are stored in the multipolygon object inside the query results. Let’s extract this now.
kampala_boundaries <- kampala_boundaries$osm_multipolygons
And now we can plot our results, labelling each region for clarity:
ggplot() + geom_sf(data = kampala_boundaries) +
  geom_sf_label(data = kampala_boundaries, aes(label = name)) + theme_void()
A grey outline of Kampala and borders of its five regions, shaded light grey. Each region has a rounded white box with the name of the region as a label inside.
Figure C.3.2. Kampala with regions labelled