1. Introduction

This is an R Markdown Notebook which illustrates how to read a text file with geographic coordinates, convert it into a spatial feature object, and create a leaflet map. In addition, a shapefile of polygons is used to enhance the map contents.

This notebook includes a workaround to publishing a map when uploading a html to RPubs crashes. It is written to help Geomatica Basica students at Universidad Nacional de Colombia to get started with geospatial data in R.

# install libraries from console -NOT FROM HERE -
# if (!require('devtools')) install.packages('devtools')
# devtools::install_github('rstudio/leaflet')
# load libraries
library(sf)
## Warning: replacing previous import 'vctrs::data_frame' by 'tibble::data_frame'
## when loading 'dplyr'
## Linking to GEOS 3.7.2, GDAL 2.4.2, PROJ 5.2.0
library(leaflet)
library(leaflet.extras)
library(htmltools)
library(stringr)

2. Read table as dataframe

cities <- read.table("../datos/cities.txt", sep=";", quote="", header=TRUE)
# what is cities?
class(cities)
## [1] "data.frame"
# see the first records
head(cities)
##   X.id. X.cod. X.country.        X.name.    X.lat.    X.lon. X.alt.
## 1   "1"   2338  "Colombi"       "Bogota"  4.600000 -74.08334   2620
## 2   "2"   2339  "Colombi"         "Cali"  3.437222 -76.52250    758
## 3   "3"   2340  "Colombi"     "Medellin"  6.291389 -75.53611   2076
## 4   "4"   2341  "Colombi" "Barranquilla" 10.963889 -74.79639     33
## 5   "5"   2342  "Colombi"    "Cartagena" 10.399722 -75.51444     36
## 6   "6"   2343  "Colombi"       "Cucuta"  7.883333 -72.50528    314
colnames(cities) <- c("id", "cod", "country", "name", "lat", "lon", "alt")
# check column names
colnames(cities)
## [1] "id"      "cod"     "country" "name"    "lat"     "lon"     "alt"

3. Convert dataframe into a spatial feature

# install simple features (sf) library
# install.packages("sf")
# load sf library
library(sf)
# convert dataframe object to simple feature object 
# https://stackoverflow.com/questions/44214487/create-sf-object-from-two-column-matrix
m <- st_as_sf(cities,coords = c(6,5,7))
# This another way of executing the above line
# cities %>%  sf::st_as_sf(coords = c(6,5,7)) -> m
# what is m?
class(m)
## [1] "sf"         "data.frame"

4. Create leaflet map of cities

# get matrix of coordinates (lat, long, alt)
coords <- st_coordinates(m)
# create vector of coordinates
# what are vectors in R
# https://datascienceplus.com/vectors-and-functions-in-r/#:~:text=A%20vector%20is%20the%20simplest,a%20vector%20of%20logical%20values.
lat = coords[, 2]
long = coords[,1]
alt = coords[,3]
# install leaflet library
#install.packages("leaflet")
# load leaflet
library(leaflet)
# review tutorial https://rstudio.github.io/leaflet/
# create leaflet map
mapa2 <- leaflet() 
mapa2 <-   addTiles(mapa2)  # Add default OpenStreetMap map tiles
mapa2 <-   addMarkers(mapa2, lng=long, lat=lat, popup=m$name)
# show map
mapa2

5. Create leaflet map of departments

We will use the sf library to read a shapefile of departments downloaded from DANE:

library(sf)
deptos <- read_sf("../datos/shapefiles/MGN2018_DPTO_POLITICO/MGN_DPTO_POLITICO.shp")

Let’s create a leaflet map representing departments as filled color polygons using the attribute Shape_Area.

Note that the following chunk did sucessfully run to produce a html file on my computer. However, when uploading the html to RPubs, the program output a message error stating: “Error in rawToChar(response$headers) : argument ‘x’ must be a raw vector”
To partly solve this problem, I did the following:
1. I opened the html file in my browser and took three screenshots of the leaflet map.
2. I put the chunk’s commands as comments (using ###).
3. I included the three screenshots using the following text (outside a chunk):
#![Texto](path-to-image-here.png)

Now, the original code BUT this time commented:

#mapa <-   leaflet(deptos)
#mapa <-   addTiles(mapa)  
#mapa <-   addPolygons(mapa, color = "#444444", weight = 1, smoothFactor = 0.5,
 #         opacity = 1.0, fillOpacity = 0.5,
 #         fillColor = ~colorQuantile("YlOrRd", Shape_Area)(Shape_Area),
 #         highlightOptions = highlightOptions(color = "red", weight = 2,
 #         bringToFront = TRUE)) 
#mapa <- addMarkers(mapa, lng=long, lat=lat, popup=m$name)

#mapa

“Leaflet output 1”

“Leaflet output 2”

“Leaflet output 3”

You may explore other ways of visualization & mapping by reading the leaflet documentation here.

Another alternative for making maps in R can be seen here.

sessionInfo()
## R version 3.6.3 (2020-02-29)
## Platform: x86_64-apple-darwin15.6.0 (64-bit)
## Running under: macOS Mojave 10.14.6
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] stringr_1.4.0        htmltools_0.5.0      leaflet.extras_1.0.0
## [4] leaflet_2.0.3.9000   sf_0.9-5            
## 
## loaded via a namespace (and not attached):
##  [1] Rcpp_1.0.5         knitr_1.29         magrittr_1.5       units_0.6-6       
##  [5] tidyselect_1.1.0   R6_2.4.1           rlang_0.4.7        dplyr_1.0.0       
##  [9] tools_3.6.3        grid_3.6.3         xfun_0.17          KernSmooth_2.23-17
## [13] e1071_1.7-3        DBI_1.1.0          crosstalk_1.1.0.1  ellipsis_0.3.1    
## [17] class_7.3-17       yaml_2.2.1         digest_0.6.25      tibble_3.0.3      
## [21] lifecycle_0.2.0    crayon_1.3.4       purrr_0.3.4        htmlwidgets_1.5.1 
## [25] vctrs_0.3.4        glue_1.4.2         evaluate_0.14      rmarkdown_2.3.5   
## [29] stringi_1.5.3      pillar_1.4.6       compiler_3.6.3     generics_0.0.2    
## [33] classInt_0.4-3     jsonlite_1.7.1     pkgconfig_2.0.3