Start libraries we need:
library(tidyverse)
library(sf)
library(tmap)
library(tmaptools)
library(lubridate)
library(ggthemes)
library(ggspatial)
library(raster)
library(rnaturalearth)
library(rgeos)
To create the map we need geolayers:
You can find this kind of datasets from many different places. One option for example is OpenStreetMap data: http://download.geofabrik.de
Full zipped OSM dataset for Georgia is 44.9 MB. To speed up the process you can download selected data from here:
download.file("http://aasa.ut.ee/tbilisi/osm_georgia_selected.zip", destfile="osm_georgia_selected.zip")
unzip("osm_georgia_selected.zip")
The list of selected dataset contains 4 layers:
Layers are quite big, which can make the processing a bit slow. Administrative borders and elevation are missing from downloaded archive.
Lets look at roads and waterways:
# Import
roads <- st_read("gis_osm_roads_free_1.shp")
## Reading layer `gis_osm_roads_free_1' from data source `C:\ANTO\loengud\tbilisi\2020\web\gis_osm_roads_free_1.shp' using driver `ESRI Shapefile'
## Simple feature collection with 156942 features and 10 fields
## geometry type: LINESTRING
## dimension: XY
## bbox: xmin: 39.5847 ymin: 40.94172 xmax: 46.724 ymax: 43.97154
## epsg (SRID): 4326
## proj4string: +proj=longlat +datum=WGS84 +no_defs
#check the data:
glimpse(roads)
## Observations: 156,942
## Variables: 11
## $ osm_id <fct> 5119612, 15950870, 17637354, 17637699, 17639488, 17673797,...
## $ code <int> 5114, 5113, 5112, 5112, 5112, 5132, 5132, 5112, 5113, 5133...
## $ fclass <fct> secondary, primary, trunk, trunk, trunk, trunk_link, trunk...
## $ name <fct> NA, Ardahan-Posof yolu, NA, NA, NA, <U+10D7><U+10D1><U+10D...
## $ ref <fct> NA, D 955, <U+10E1> 1, <U+10E1> 1, <U+10E1> 1, <U+10E1> 4,...
## $ oneway <fct> B, F, F, B, B, F, F, B, F, F, B, B, B, T, B, B, B, B, F, B...
## $ maxspeed <int> 0, 20, 90, 0, 0, 0, 90, 90, 50, 0, 40, 50, 0, 0, 0, 0, 50,...
## $ layer <dbl> 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
## $ bridge <fct> F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F...
## $ tunnel <fct> F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F...
## $ geometry <LINESTRING [arc_degree]> LINESTRING (40.31842 43.230..., LINEST...
Roads layer contains 156942 road segments. Most probably we don’t need all of them. Let’s selected only major roads.
# Road types are stored in column 'fclass'. Get the list of unique records:
unique(roads$fclass)
## [1] secondary primary trunk trunk_link primary_link
## [6] residential tertiary motorway_link motorway secondary_link
## [11] service unclassified track unknown living_street
## [16] footway track_grade3 path track_grade2 track_grade4
## [21] steps pedestrian track_grade1 tertiary_link track_grade5
## [26] bridleway cycleway
## 27 Levels: bridleway cycleway footway living_street motorway ... unknown
We have 27 different road types. Select step by step till you are satisfied:
roads_slct <- roads %>%
filter(fclass == "primary" | fclass == "secondary")
In queries we can use AND and OR operators: &and |.
In previous sessions we used geolayers of Georgia from The Humanitarian Data Exchange. But there are many different sources. For example you can download data directly from raster library:
Download country contour (level = 0):
gadm_0_georgia <- raster::getData('GADM', country = 'GEO', level = 0)
gadm_0_georgia_sf <- st_as_sf(gadm_0_georgia)
Plot country contour and roads layer:
ggplot()+
geom_sf(data = gadm_0_georgia_sf)+
geom_sf(data = roads_slct, col = "red")
Result is not very nice: the filtered road layer contains some obvious errors and unconnected roads.
Lets check the rivers layer:
rivers <- st_read("gis_osm_waterways_free_1.shp")
## Reading layer `gis_osm_waterways_free_1' from data source `C:\ANTO\loengud\tbilisi\2020\web\gis_osm_waterways_free_1.shp' using driver `ESRI Shapefile'
## Simple feature collection with 17123 features and 5 fields
## geometry type: LINESTRING
## dimension: XY
## bbox: xmin: 39.52382 ymin: 40.93108 xmax: 46.8273 ymax: 45.74497
## epsg (SRID): 4326
## proj4string: +proj=longlat +datum=WGS84 +no_defs
glimpse(rivers)
## Observations: 17,123
## Variables: 6
## $ osm_id <fct> 17639034, 17810571, 17811047, 19854951, 19855058, 20449331...
## $ code <int> 8103, 8101, 8101, 8102, 8101, 8101, 8101, 8101, 8101, 8101...
## $ fclass <fct> canal, river, river, stream, river, river, river, river, r...
## $ width <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
## $ name <fct> <U+0425><U+043E><U+0431>, <U+10DB><U+10E2><U+10D9><U+10D5>...
## $ geometry <LINESTRING [arc_degree]> LINESTRING (41.76159 42.652..., LINEST...
# River types are stored in column 'fclass'. Get the list of unique records:
unique(rivers$fclass)
## [1] canal river stream drain
## Levels: canal drain river stream
# filter:
rivers_slct <- rivers %>% filter(fclass == "river")
ggplot()+
geom_sf(data = gadm_0_georgia_sf)+
geom_sf(data = rivers_slct, col = "blue")
Result is again not very good. Clip rivers outside of Georgia. For that we can use st_intersection:
rivers_slct <- st_intersection(rivers_slct, gadm_0_georgia_sf)
## although coordinates are longitude/latitude, st_intersection assumes that they are planar
## Warning: attribute variables are assumed to be spatially constant
## throughout all geometries
ggplot()+
geom_sf(data = gadm_0_georgia_sf, col = "red")+
geom_sf(data = rivers_slct, col = "blue", size= 0.25)
Result is still not 100% ok, but we don’t have time to deal with it. The quality of the dat ais just not good enough. Look for other options.
Let’s take now roads layer. For that we should try some other option. Lot of spatial layers are available via Natural Earth
ne_roads <- ne_download(scale = "large", type = "roads", category = "cultural")
## OGR data source with driver: ESRI Shapefile
## Source: "C:\Users\Administrator\AppData\Local\Temp\Rtmpi83Afu", layer: "ne_10m_roads"
## with 56601 features
## It has 31 fields
## Integer64 fields read as strings: scalerank question
class(ne_roads)
## [1] "SpatialLinesDataFrame"
## attr(,"package")
## [1] "sp"
To plot Spatial***DataFrame objects we can use simply plot. It’s functionality is quite limited compared with ggplot2 but it is faster and able to plot much bigger objectS:
plot(ne_roads)
It is a global layer. How can we extract Georgian roads?
For that we can use function called gIntersection. It is a function for determining the intersection between the two given geometries. In other words - that portion of geometry A and geometry B that is shared between the two geometries.
ne_roads_GE <- gIntersection(ne_roads, gadm_0_georgia, byid = TRUE, drop_lower_td = TRUE)
class(ne_roads_GE)
## [1] "SpatialLines"
## attr(,"package")
## [1] "sp"
plot(gadm_0_georgia)
plot(ne_roads_GE, add= T, col = "red")
Result looks logical: all the road segments are connected with each other and nothing appears outside of Georgian borders.
And now populated places. In OSM dataset the Georgian alphabet is used. Author of current tutorial needs to learn it… But till this time we have to find something else. Maybe the Natural Earth can help us again?
ne_populated_places <- ne_download(scale = "large", type = "populated_places", category = "cultural")
## OGR data source with driver: ESRI Shapefile
## Source: "C:\Users\Administrator\AppData\Local\Temp\Rtmpi83Afu", layer: "ne_10m_populated_places"
## with 7343 features
## It has 119 fields
## Integer64 fields read as strings: wof_id ne_id
class(ne_populated_places)
## [1] "SpatialPointsDataFrame"
## attr(,"package")
## [1] "sp"
glimpse(ne_populated_places@data)
## Observations: 7,343
## Variables: 119
## $ SCALERANK <int> 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, ...
## $ NATSCALE <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,...
## $ LABELRANK <int> 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5,...
## $ FEATURECLA <chr> "Admin-1 capital", "Admin-1 capital", "Admin-1 capital",...
## $ NAME <chr> "Colonia del Sacramento", "Trinidad", "Fray Bentos", "Ca...
## $ NAMEPAR <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ NAMEALT <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ DIFFASCII <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ NAMEASCII <chr> "Colonia del Sacramento", "Trinidad", "Fray Bentos", "Ca...
## $ ADM0CAP <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ CAPIN <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ WORLDCITY <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MEGACITY <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ SOV0NAME <chr> "Uruguay", "Uruguay", "Uruguay", "Uruguay", "Uruguay", "...
## $ SOV_A3 <chr> "URY", "URY", "URY", "URY", "URY", "TGO", "TGO", "TUN", ...
## $ ADM0NAME <chr> "Uruguay", "Uruguay", "Uruguay", "Uruguay", "Uruguay", "...
## $ ADM0_A3 <chr> "URY", "URY", "URY", "URY", "URY", "TGO", "TGO", "TUN", ...
## $ ADM1NAME <chr> "Colonia", "Flores", NA, "Canelones", "Florida", "Kara",...
## $ ISO_A2 <chr> "UY", "UY", "UY", "UY", "UY", "TG", "TG", "TN", "TN", "T...
## $ NOTE <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ LATITUDE <dbl> -34.479999, -33.543999, -33.138999, -34.538004, -34.0990...
## $ LONGITUDE <dbl> -57.8400025, -56.9009966, -58.3039975, -56.2840015, -56....
## $ CHANGED <dbl> 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,...
## $ NAMEDIFF <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,...
## $ DIFFNOTE <chr> "Added missing admin-1 capital. Population from GeoNames...
## $ POP_MAX <int> 21714, 21093, 23279, 19698, 32234, 61845, 21054, 61705, ...
## $ POP_MIN <int> 21714, 21093, 23279, 19698, 32234, 61845, 21054, 61705, ...
## $ POP_OTHER <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ RANK_MAX <int> 7, 7, 7, 6, 7, 8, 7, 8, 6, 8, 8, 8, 8, 7, 7, 7, 8, 6, 9,...
## $ RANK_MIN <int> 7, 7, 7, 6, 7, 8, 7, 8, 6, 8, 8, 8, 8, 7, 7, 7, 7, 6, 9,...
## $ GEONAMEID <dbl> 3443013, 3439749, 3442568, 3443413, 3442585, 2367568, 23...
## $ MEGANAME <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ LS_NAME <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ LS_MATCH <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ CHECKME <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_POP10 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_POP20 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_POP50 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_POP300 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_POP310 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_NATSCA <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MIN_AREAKM <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_AREAKM <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MIN_AREAMI <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_AREAMI <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MIN_PERKM <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_PERKM <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MIN_PERMI <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_PERMI <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MIN_BBXMIN <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_BBXMIN <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MIN_BBXMAX <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_BBXMAX <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MIN_BBYMIN <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_BBYMIN <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MIN_BBYMAX <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MAX_BBYMAX <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MEAN_BBXC <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ MEAN_BBYC <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ COMPARE <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ GN_ASCII <chr> "Colonia del Sacramento", "Trinidad", "Fray Bentos", "Ca...
## $ FEATURE_CL <chr> "P", "P", "P", "P", "P", "P", "P", NA, "P", "P", NA, "P"...
## $ FEATURE_CO <chr> "PPL", "PPL", "PPL", "PPL", "PPL", "PPL", "PPL", NA, "PP...
## $ ADMIN1_COD <dbl> 4, 6, 12, 2, 7, 5, 22, 0, 31, 34, 0, 6, 0, 33, 22, 0, 0,...
## $ GN_POP <dbl> 21714, 21093, 23279, 19698, 32234, 61845, 21054, 0, 1987...
## $ ELEVATION <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ GTOPO30 <dbl> 28, 134, 43, 29, 74, 463, 374, 0, 49, 247, 0, 141, 0, 31...
## $ TIMEZONE <chr> "America/Montevideo", "America/Montevideo", "America/Mon...
## $ GEONAMESNO <chr> "Geonames ascii name + lat.d + long.d matching.", "Geona...
## $ UN_FID <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ UN_ADM0 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ UN_LAT <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ UN_LONG <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP1950 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP1955 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP1960 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP1965 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP1970 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP1975 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP1980 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP1985 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP1990 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP1995 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP2000 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP2005 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP2010 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP2015 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP2020 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP2025 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ POP2050 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ CITYALT <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ min_zoom <dbl> 9.0, 9.0, 9.0, 9.0, 7.0, 9.0, 7.0, 6.1, 9.0, 9.0, 8.0, 9...
## $ wikidataid <chr> "Q56064", "Q862508", "Q849835", "Q841342", "Q842472", "Q...
## $ wof_id <chr> "421199749", "890444639", "890451703", "890444649", "890...
## $ CAPALT <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ name_en <chr> "Colonia del Sacramento", "Trinidad", "Fray Bentos", "Ca...
## $ name_de <chr> "Colonia del Sacramento", "Trinidad", "Fray Bentos", "Ca...
## $ name_es <chr> "Colonia del Sacramento", "Trinidad", "Fray Bentos", "Ca...
## $ name_fr <chr> "Colonia del Sacramento", "Trinidad", "Fray Bentos", "Ca...
## $ name_pt <chr> "Colónia do Sacramento", "Trinidad", "Fray Bentos", "Can...
## $ name_ru <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ name_zh <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ label <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ name_ar <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ name_bn <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ name_el <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ name_hi <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ name_hu <chr> "Colonia del Sacramento", NA, NA, NA, NA, "Bassar", NA, ...
## $ name_id <chr> NA, "Trinidad", "Fray Bentos", "Canelones", "Florida", N...
## $ name_it <chr> "Colonia del Sacramento", "Trinidad", "Fray Bentos", "Ca...
## $ name_ja <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ name_ko <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, ...
## $ name_nl <chr> "Colonia del Sacramento", "Trinidad", "Fray Bentos", "Ca...
## $ name_pl <chr> "Colonia del Sacramento", "Trinidad", "Fray Bentos", "Ca...
## $ name_sv <chr> "Colonia del Sacramento", "Trinidad", "Fray Bentos", "Ca...
## $ name_tr <chr> "Colonia del Sacramento", "Trinidad", "Fray Bentos", "Ca...
## $ name_vi <chr> "Colonia del Sacramento", "Trinidad", "Fray Bentos", "Ca...
## $ wdid_score <int> 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,...
## $ ne_id <chr> "1159112629", "1159112647", "1159112663", "1159112679", ...
Downloaded object belongs to the class SpatialPointsDataFrame. Convert it to sf and filter locations in Georgia (iso_a2 code = GE).
# Here we can use 'filter' which works with sf-layers:
ne_populated_places_sf <- st_as_sf(ne_populated_places)
ne_populated_places_sf <- ne_populated_places_sf %>% filter(ISO_A2 =="GE")
ggplot()+
geom_sf(data = gadm_0_georgia_sf)+
geom_sf(data = ne_populated_places_sf, col = "red")+
geom_sf_text(data = ne_populated_places_sf, aes(label = NAME), nudge_y = 0.1, nudge_x = 0.25)
## Warning in st_point_on_surface.sfc(sf::st_zm(x)): st_point_on_surface may not
## give correct results for longitude/latitude data
Number of places is not very big, but adds some additional spatial context to the map.
For elevation we can use already familiar getDatafunction from library called raster. From there is available SRTM (Shuttle Radar Topography Mission) elevation data link. Instead of country ISO3 code we have to fix geographical coordinates of area we are interested.
srtm <- raster::getData('SRTM', lon = 44, lat = 42)
plot(srtm)
plot(gadm_0_georgia, add= T)
Elavation raster is download by tiles (tile which covers coordinates N42 and E44). from the plot we see, that it is not enough to cover whole Georgia. We have to donload one more tile
#Download one more tile:
srtm2 <- raster::getData('SRTM', lon = 46, lat = 42)
Downloaded rasters are store as different objects. We can bind them together:
#Mosaic/merge srtm tiles
srtmmosaic <- mosaic(srtm, srtm2, fun = mean)
plot(gadm_0_georgia)
plot(srtmmosaic, add = T)
plot(gadm_0_georgia, add= T)
In case we want to keep elevation data only for borders of Georgia, we can mask raster outside of the borders:
srtmmosaic_masked <- mask(srtmmosaic, gadm_0_georgia)
plot(gadm_0_georgia)
plot(srtmmosaic_masked, add = T)
Looks like we have now all the layers we need. And we can put all the layers in logical order together.
library(maptools) # enables function 'pointLabel'
plot(gadm_0_georgia, col = "grey")
plot(srtmmosaic_masked, add = T, col = (terrain.colors(20)))
plot(rivers_slct, add=T, col="lightblue", lwd = 0.25)
plot(ne_roads_GE, add = T, col = "red", lwd = 0.1)
plot(ne_populated_places_sf, col = "black", add = T)
# Add place names
pointLabel(st_coordinates(ne_populated_places_sf),labels = ne_populated_places_sf$NAME)
There are quite often the cases where we want to combine several spatial layers and derive new information from this combination.
Let us imagine the situation when we want to calculate average elevation above sea level for every region in Georgia.
# We need the regions layer in format of SpatialPolygonsDataFrame. Let's download it again:
gadm_1_sp <- raster::getData('GADM', country = 'GEO', level = 1)
class(gadm_1_sp)
## [1] "SpatialPolygonsDataFrame"
## attr(,"package")
## [1] "sp"
# extract mean from raster:
alt_GEO <- getData('alt', country='GEO', mask=TRUE)
region_Ave_Elev <- raster::extract(alt_GEO, gadm_1_sp, fun = mean, na.rm=TRUE, sp = T)
#Check the data:
region_Ave_Elev@data %>%
head()
## GID_0 NAME_0 GID_1 NAME_1 VARNAME_1 NL_NAME_1 TYPE_1
## 1 GEO Georgia GEO.1_1 Abkhazia Sokhumi <NA> Avtonomiuri Respublika
## 5 GEO Georgia GEO.2_1 Ajaria Batumi <NA> Avtonomiuri Respublika
## 6 GEO Georgia GEO.3_1 Guria Ozurgeti <NA> Region
## 7 GEO Georgia GEO.4_1 Imereti Kutaisi <NA> Region
## 8 GEO Georgia GEO.5_1 Kakheti Telavi <NA> Region
## 9 GEO Georgia GEO.6_1 Kvemo Kartli Rustavi <NA> Region
## ENGTYPE_1 CC_1 HASC_1 GEO_msk_alt
## 1 Autonomous Republic <NA> GE.AB 1050.9602
## 5 Autonomous Republic <NA> GE.AJ 1142.7060
## 6 Region <NA> GE.GU 605.3960
## 7 Region <NA> GE.IM 681.9269
## 8 Region <NA> GE.KA 914.1449
## 9 Region <NA> GE.KK 1101.4145
Plot the results
# Convert SpatialpolygonDataFrame to sf:
region_Ave_Elev_sf <- st_as_sf(region_Ave_Elev)
ggplot()+
geom_sf(data = region_Ave_Elev_sf, aes(fill = GEO_msk_alt), col = "grey", size= 0.25)+
geom_sf_label(data = region_Ave_Elev_sf, aes(label= round(GEO_msk_alt, 0)), alpha = 0.5)+
scale_fill_viridis_c()+
labs(title = "Average elevation above sea level (m)", fill = "meters \n(a.s.l.)")
## Warning in st_point_on_surface.sfc(sf::st_zm(x)): st_point_on_surface may not
## give correct results for longitude/latitude data
You can save the previous map:
# Save previous plot:
ggsave("georgia_Mean_elev.png", dpi = 300, height = 4, width = 6, units = "in")
# Another posibility to save the map as raster image or pdf is:
png("filename.png", res= 300, units = "in", height = 4, width = 6) # this will create an empty file and leaves it open for writing
ggplot()+ ......... #(the command, which creates the map)
dev.off() # This is very important! If you will not close the writing session all the next outputs will be written into "filename.png".
# download climate means (can be slow! (75MB)):
climate <- raster::getData('worldclim', var ='bio', res = 0.5, lon = 42, lat = 44)
climate_2 <- climate$bio1_17
climate_masked <- mask(climate_2, gadm_0_georgia)
# Temperature map:
climate_masked <- climate_masked / 10 # to get real values
plot(gadm_0_georgia)
plot(climate_masked, add= T, col = topo.colors(20))
plot(gadm_0_georgia, ad = T)
Good introduction to raster::getData: link
# we have some populated places:
ggplot()+
geom_sf_text(data = ne_populated_places_sf, aes(label = NAME))
## Warning in st_point_on_surface.sfc(sf::st_zm(x)): st_point_on_surface may not
## give correct results for longitude/latitude data
#sf to SpatialpointDataFrame:
ne_populated_places_sp <- as(ne_populated_places_sf, "Spatial")
# warmest place:
place_temp <- raster::extract(climate_masked, ne_populated_places_sp, fun = mean, na.rm=TRUE, sp = T)
library(knitr)
place_temp@data %>%
dplyr::select(NAME, bio1_17) %>%
arrange(-bio1_17) %>%
kable()
| NAME | bio1_17 |
|---|---|
| Poti | 14.4 |
| Batumi | 14.1 |
| Sukhumi | 14.1 |
| Kutaisi | 13.7 |
| Rustavi | 13.6 |
| Tbilisi | 13.1 |
| Tskhinvali | 8.6 |
Warmest place is Poti (14.4 Celsius degrees)!
dat_tbilisi_airtemp <- read.csv2("http://aasa.ut.ee/tbilisi/tbilisi_airTemp_2017.csv")
dat_tbilisi_airtemp_day <- dat_tbilisi_airtemp %>% filter(!is.na(air_temp)) %>% mutate(date2 = as.Date(date)) %>% group_by(date2) %>% summarise(ave_airtemp = mean(air_temp)) %>% ungroup()
ggplot()+
geom_line(data = dat_tbilisi_airtemp_day, aes(x= date2, y = ave_airtemp))
For that you need library “ggTimeseries”. To install this library you have to install first “devtools”. Also the installation process is a bit different:
install.packages("devtools")
library(devtools)
install_github("Ather-Energy/ggTimeSeries")
Plot:
library(ggTimeSeries)
ggplot_calendar_heatmap(dat_tbilisi_airtemp_day,
'date2',
'ave_airtemp')+
scale_fill_viridis_c()+
labs(title = "Mean daily air temperature in Tbilisi (2017)", fill= "C")
Use previously downloaded Worldclim dataset. First example was based on annual mean air temperature. You task now is to create 2 thematic maps:
Bind all the home works into one doc/pdf/html. Add script-files separately (in case of R-markdowm script is already in html file). Please add your name to each file name! E-mail results to: anto.aasa@ut.ee. Final deadline for all submissions is May 15th, 2020.
Possible results:
Author: Anto Aasa
in ISET, Tbilisi
Last update: 2020-04-22 14:33:04
.