-
Notifications
You must be signed in to change notification settings - Fork 4
/
141-mapping-2.rmd
112 lines (83 loc) · 5.48 KB
/
141-mapping-2.rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# Mapping part two {#mapping-2}
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(tidyverse)
library(leaflet)
library(ggmap)
```
Many online services generate tile maps. Generally a small number of maps are available for free and then further maps require a subscription. For causal use the free service tier is almost always sufficient. To keep track of your usage you sometimes need to sign up for an API key. The first example below is unusual because you can use these maps without any account. Tools and services for this sort of mapping change frequently, so this lesson shows how to use two different services.
## Tiled maps with leaflet
In the previous lesson we made maps to show geographical data using map outlines from R packages.
In this lesson we will look at making maps that build on detailed basemaps from online mapping systems. [Google maps](https://www.google.com/maps) is a well known service; [OpenStreetMap](https://www.openstreetmap.org/) is a community-built free alternative. We will use the `leaflet` package.
Let's make a map and place a marker at the location of the Mathematics and Statistics Department. You can pan and zoom this map from within Rstudio and in the knitted output.
```{r}
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=-63.5932, lat=44.63697, popup="Math & Stats, Dalhousie U")
m # Print the map
```
Let's use the city database we used in the MDS lesson to label the 61 cities we selected in that lesson.
```{r}
cities <- read_csv("static/selected_cities.csv")
m2 <- leaflet(data = cities) %>%
addTiles() %>%
addCircleMarkers(~ lng, ~lat, label = ~city)
m2
```
There are several different [basemaps](https://rstudio.github.io/leaflet/basemaps.html), or tiles, that you can use. A fun one to look at -- because it changes frequently is a radar map for the USA from Iowa State.
```{r}
m3 <- leaflet(data = cities) %>%
addTiles() %>%
addCircleMarkers(~ lng, ~lat, label = ~city) %>%
addWMSTiles("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi",
layers = "nexrad-n0r-900913",
options = WMSTileOptions(format = "image/png", transparent = TRUE),
attribution = "Weather data © 2012 IEM Nexrad") %>%
setView(-93.65, 42.0285, zoom = 4)
m3
```
It's common to see "chloropleth" maps of the USA in which geographic regions are coloured to show a quantitative or categorical variable, such as population density or election results. These maps are less common in Canada due to two main factors: the geographic concentration of the population in cities means that area maps are even less informative than for the USA and the latitude range of Canada makes for some severe challenges when plotting whole-country territory and province chloropleth maps on commonly used projections. Nevertheless, it is possible. Here's a demonstration with some random numbers for "data".
```{r}
library(geojsonio)
pal <- colorNumeric("viridis", NULL) # make a viridis palette
canada <- geojson_read("https://gist.githubusercontent.com/mikelotis/2156d7c170d10d2c77cb79424fe2137d/raw/7a13748ed7ea5ba64876c77c53b6cb64dd5c3ab0/canada-province.geojson", what="sp")
my_values = runif(13, 0, 10) # random numbers between 0 and 10
canada %>%
leaflet() %>%
addTiles() %>%
addPolygons(fillColor = ~ pal(my_values)) %>%
addLegend(pal = pal, values = my_values, opacity = 1.0)
```
## Tiled map with ggmap
In this section we will use tile maps from the [openstreetmap](https://www.openstreetmap.org/) database rendered by [Stamen Maps](http://maps.stamen.com/). We will use the `ggmap` package to download and draw the map.
There are two steps. First download the tiles needed for your map by specifying
* the bounding box in degrees latitude and longitude,
* the [zoom level](https://wiki.openstreetmap.org/wiki/Zoom_levels) of the map, and
* the type of the tiles (terrain, terrain-background, etc. See the help for `get_stamenmap` for more.)
Always start with a small zoom level -- if you make it too big you will download a lot of unnecessary data, which takes time and imposes a burden on the service.
```{r}
mymap_terrain <- get_stamenmap(bbox = c(left = -130, bottom = 41, right = -50, top = 60), zoom=4, maptype = "terrain")
ggmap(mymap_terrain)
```
This is a regular ggplot, so you can add lines and points to a map easily, using latitude and longitude as coordinates. Placing text on a map in a readable and attractive way can be quite a challenge.
```{r}
my_points <- tibble(lat = c(43+57/60, 49+53/60),
lon = c(-59-55/60, -97-9/60),
label = c("Sable Is.", "Winnipeg")
)
ggmap(mymap_terrain) +
geom_point(data =my_points, color="brown") +
geom_text(data = my_points, aes(label=label))
```
You can also zoom in on urban areas.
```{r}
mymap_halifax <- get_stamenmap(bbox = c(left = -63.6-0.1, bottom = 44.60, right = -63.6+0.1, top = 44.75),
zoom=12, maptype = "toner-lite")
ggmap(mymap_halifax)
```
## Further reading
* Healy's chapter 7 on [mapping](https://socviz.co/maps.html#maps)
* Wilke's chapter 15 on [geospatial data](https://clauswilke.com/dataviz/geospatial-data.html)
* An article describing how [ggmap](https://journal.r-project.org/archive/2013-1/kahle-wickham.pdf) works
* A [ggmap](https://github.com/dkahle/ggmap) tutorial, showing how to use Google map services including geocoding (turning an address into a location and the reverse) and routing.
* Another well-developed approach to mapping: [mapview](https://r-spatial.github.io/mapview/index.html)