Map any region in the world with R – Part II: Obtaining the coordinates
Posted on November 3, 2022 by R with White Dwarf in R bloggers | 0 Comments
[This article was first published on R with White Dwarf , and kindly contributed to R-bloggers ]. (You can report issue about the content on this page here )
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Share Tweet
Scope of this post
This is the second part of the series to create a map of any region of the world with R.
We are creating maps of data showing changes over a span of time for different countries and pointing at all kinds of cities. That basically means that we need to map any region of the world with R. Today there are all kinds of packages and techniques to do that. I will share the strategy I used with ggplot2 and maps packages, using support of Open Street Map to obtain the coordinates of cities and finally making it interactive with shiny . The project is quite long for a single post, so my idea is to split it into a few smaller blog posts. So far, the list is a follows:
Making a single script for fast replication
Making the code interactive in a shiny app
The ideas is to share the how-to of one of the projects I am most proud of and, at the same time to give back to the R community in hopes that it can help somebody else.
I hope you all enjoy it. Feel free to leave any kind of comment and/or question at the end.
Open Street Maps and Nominatim
A simple query
library('RJSONIO') site [[1]]$place_id > [1] 1177116 > > [[1]]$licence > [1] "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright" > > [[1]]$osm_type > [1] "node" > > [[1]]$osm_id > [1] 336169214 > > [[1]]$boundingbox > [1] "29.619" "29.659" "-111.0786667" "-111.0386667" > > [[1]]$lat > [1] "29.639" > > [[1]]$lon > [1] "-111.0586667" > > [[1]]$display_name > [1] "Texcoco, Carbó, Sonora, México" > > [[1]]$class > [1] "place" > > [[1]]$type > [1] "village" > > [[1]]$importance > [1] 0.385 > > [[1]]$icon > [1] "https://nominatim.openstreetmap.org/ui/mapicons/poi_place_village.p.20.png" > > > [[2]] > [[2]]$place_id > [1] 3448536 > > [[2]]$licence > [1] "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright" > > [[2]]$osm_type > [1] "node" > > [[2]]$osm_id > [1] 458633446 > > [[2]]$boundingbox > [1] "16.551667" "16.591667" "-97.053333" "-97.013333" > > [[2]]$lat > [1] "16.571667" > > [[2]]$lon > [1] "-97.033333" > > [[2]]$display_name > [1] "Texcoco, Santa María Sola, Oaxaca, México" > > [[2]]$class > [1] "place" > > [[2]]$type > [1] "hamlet" > > [[2]]$importance > [1] 0.36 > > [[2]]$icon > [1] "https://nominatim.openstreetmap.org/ui/mapicons/poi_place_village.p.20.png"
We start with Open Street Map and its API nominatim . In the piece of code above we can see how to perform a simple query for one city. It is basically one long string containing first the url of nominatim and at the end the search details: here we start the search with city using ?city=Texcoco, in this case I aimed for a city with only a few results. Next we are limiting the amount of results to 9 with &limit=9 and finally requesting the results in format JSON.
We could basically copy the string that we are passing to site and paste it in the web browser to see the results directly there. Feel free to change the city Texcoco to any other city, and play a bit more with the rest of the parameters. Particularly have a look at what happens when you remove the &format=json part or when you exchange json for any other abstract string like csv or other non-recognized format.
A more specific query
city > [[1]]$osm_type > [1] "relation" > > [[1]]$osm_id > [1] 111968 > > [[1]]$boundingbox > [1] "37.6403143" "37.929811" "-123.173825" "-122.281479" > > [[1]]$lat > [1] "37.7790262" > > [[1]]$lon > [1] "-122.419906" > > [[1]]$display_name > [1] "San Francisco, CAL Fire Northern Region, California, United States" > > [[1]]$class > [1] "boundary" > > [[1]]$type > [1] "administrative" > > [[1]]$importance > [1] 1.035131 > > [[1]]$icon > [1] "https://nominatim.openstreetmap.org/ui/mapicons/poi_boundary_administrative.p.20.png"
If you explore OSM and nominatim a bit you will see that we can add search arguments using & followed by the argument we want (i.e., state), the symbol equal = and the argument. In my example above you can see how we are specifying the State and Country of our query. Additionally it is important to know how to pass spaces in a name, for example, San Francisco will be passed as San%20Francisco.
With this basic information in mind and knowing that the package RJSONIO helps us to retrieve the data from the JSON api into an R-friendly format, we can easily prepare a function to search for any city quickly, provided a few extra details like a region, state or county, and especially important, the country (try searching for cities like London or Prague without providing a country, you might be surprised of how many cities exist in the world with such names).
coords_from_city