P 2018 Basel Rspatial1
P 2018 Basel Rspatial1
Michael Dorman
Geography and Environmental Development
dorman@post.bgu.ac.il
2018-02-26 - 2018-03-01
Contents
install.packages("rgdal")
install.packages("sf")
install.packages("raster")
install.packages("rgeos")
install.packages("geosphere")
install.packages("rmapshaper")
install.packages("gstat")
install.packages("automap")
install.packages("spdep")
install.packages("spatstat")
install.packages("osmdata")
install.packages("mapview")
Requirements
1
blog.revolutionanalytics.com/2015/07/the-network-structure-of-cran.html
R as a GIS?
I Strengths of R as a GIS
I R capabilities in data processing and visualization, combined
with dedicated packages for spatial data
I A single environment encompassing all analysis aspects -
acquiring data, computation, statistics, visualization, Web, etc.
I General advantages of programming
I Automation - Doing otherwise unfeasible repetitive tasks
I Reproducibility - Precise control of instructions to the
computer
I Situations when other tools are needed
I Interactive editing or georeferencing (but see mapedit)
I Unique GIS algorithms (label placement, network routing,
splitting lines at intersections, etc.)
I Data that cannot fit in RAM (but R can connect to spatial
databases)
Notable packages
I Binary
I ESRI Shapefile (.shp, .shx, .dbf, .prj, . . . )
I Plain Text
I GeoJSON (.json or .geojson)
I GPX (.gpx)
I Spatial Databases
I PostGIS / PostgreSQL
Vector: Data structures (sp)
2
http://neondataskills.org/R/Introduction-to-Raster-Data-In-R/
Raster: File formats
I “Simple” rasters
I GeoTiff (.tif)
I Erdas Imagine Image (.img)
I “Complex” rasters (>3D and / or metadata)
I HDF (.hdf)
I NetCDF (.nc)
Raster: Data structures
Figure 5: Geographic (WGS 84; left) and projected (NAD83 / UTM zone
12N; right) CRS3
3
https://geocompr.robinlovelace.net/spatial-class.html
Coordinate Reference Systems (CRS)
crs = rgdal::make_EPSG()
Coordinate Reference Systems (CRS)
4326
class(pol_sp)
## [1] "SpatialPolygonsDataFrame"
## attr(,"package")
## [1] "sp"
rgdal, sf, raster: Handling spatial data
pol_sf = st_read("data/cb_2015_us_state_5m.shp")
## Reading layer `cb_2015_us_state_5m' from data source `/home/michael/Dropbox/
## Simple feature collection with 49 features and 1 field
## geometry type: MULTIPOLYGON
## dimension: XY
## bbox: xmin: -124.7332 ymin: 24.51496 xmax: -66.9499 ymax: 49.38436
## epsg (SRID): 4326
## proj4string: +proj=longlat +datum=WGS84 +no_defs
class(pol_sf)
## [1] "sf" "data.frame"
rgdal, sf, raster: Handling spatial data
I Since sf is new, the majority of the R-Spatial ecosystem only
works with sp
I “Migration” document between sp and sf
I Conversion sp → sf
x = st_as_sf(pol_sp)
class(x)
## [1] "sf" "data.frame"
I Conversion sf → sp
x = as(pol_sf, "Spatial")
class(x)
## [1] "SpatialPolygonsDataFrame"
## attr(,"package")
## [1] "sp"
rgdal, sf, raster: Handling spatial data
r = raster("data/dem.tif")
r
## class : RasterLayer
## dimensions : 333, 286, 95238 (nrow, ncol, ncell)
## resolution : 90, 90 (x, y)
## extent : 673414, 699154, 3615239, 3645209 (xmin, xmax, ymin, ymax)
## coord. ref. : +proj=utm +zone=36 +ellps=WGS84 +units=m +no_defs
## data source : /home/michael/Dropbox/Presentations/p_2018_02_EO_Workshop_Base
## names : dem
## values : -12, 537 (min, max)
class(r)
## [1] "RasterLayer"
## attr(,"package")
## [1] "raster"
rgdal, sf, raster: Handling spatial data
I CRS of sp vector layer
proj4string(pol_sp)
## [1] "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +t
proj4string(r)
## [1] "+proj=utm +zone=36 +ellps=WGS84 +units=m +no_defs"
st_crs(pol_sf)
## Coordinate Reference System:
## EPSG: 4326
## proj4string: "+proj=longlat +datum=WGS84 +no_defs"
rgeos, sf: Geoprocessing Vector Layers
I GEOS is used for geometric operations on vector layers with
rgeos / sf -
I Numeric operators - Area, Length, Distance. . .
I Logical operators - Contains, Within, Within distance,
Crosses, Overlaps, Equals, Intersects, Disjoint, Touches. . .
I Geometry generating operators - Centroid, Buffer,
Intersection, Union, Difference, Convex-Hull, Simplification. . .
width: −0.2 width: 0 width: 0.2
library(rgeos)
st_distance(pol_sf[1, ], pol_sf[2, ])
## Units: m
## [,1]
## [1,] 1888200
raster: Geoprocessing Rasters
500 350
40
300
400
50 30 250
300 200
20
0
20
150
150
10
200
0
35
300 100
0
100 10
50
50
45
250 0 0 0 0
40
0
*
Latitude
0
−50
−100
Longitude
4
http://paulbutler.org/archives/visualizing-facebook-friends/
geosphere: Example
library(geosphere)
LA = c(-118.40, 33.95)
NY = c(-73.78, 40.63)
gci = gcIntermediate(LA, NY)
head(gci)
## lon lat
## [1,] -117.6264 34.23369
## [2,] -116.8477 34.51250
## [3,] -116.0638 34.78633
## [4,] -115.2747 35.05510
## [5,] -114.4804 35.31872
## [6,] -113.6810 35.57712
rmapshaper
I rmapshaper is an R wrapper around the mapshaper tool,
which also has a nice web-interface
I The main advantage of rmapshaper is the topologically-aware
simplification algorithm (also see Vignette)
I Shared boundaries between polygons are always kept intact,
with no gaps or overlaps
library(rmapshaper)
pol_sp_s1 = ms_simplify(pol_sp, keep = 0.05)
pol_sp_s2 = ms_simplify(pol_sp, keep = 0.01)
Figure 10: Original (left), 0.05 points retained (middle) and 0.01 retained
(right)
gstat: Geostatistical Modelling
I Univariate and multivariate geostatistics -
I Variogram modelling
I Ordinary and universal point or block (co)kriging
I Cross-validation
333000
7.0
332000
6.5
6.0
331000
5.5
5.0
330000
library(gstat)
library(automap)
data(meuse)
data(meuse.riv)
coordinates(meuse) = ~ x + y
data(meuse.grid)
gridded(meuse.grid) = ~ x + y
grid = raster(meuse.grid)
grid[!is.na(grid)] = 1
I Plot
plot(grid)
plot(meuse, add = TRUE)
gstat: Example
333000
1.0010
332000
1.0005
1.0000
331000
0.9995
0.9990
330000
v = autofitVariogram(log(zinc) ~ 1, meuse)
v$var_model
## model psill range
## 1 Nug 0.04848089 0.0000
## 2 Sph 0.58754741 889.9084
gstat: Example
I The fitted variogram model is shown below -
plot(v)
1314
1139
0.6 1349 1355
0.5 830
Semi−variance
0.4
711
0.3
149
184
0.2
36114
Model: Sph
Distance
g = gstat(
formula = log(zinc) ~ 1,
model = v$var_model,
data = meuse
)
gstat: Example
predicted = interpolate(grid, g)
## [using ordinary kriging]
plot(predicted)
contour(predicted, add = TRUE)
gstat: Example
7
333000
6.8
6.4
6.2
7
7.2
7.4
332000 7.0
6.8 6.4 5.2
6
5.6 6.5
7
6.0
331000
5
5.5
7
6.6 5.4 5.0
5.8
6
6.2
6.6
6.8
330000
6.2 5.2
6.4
6.4 6 6.2
6
6.
6.8
333000
4
5.
4
6.
7.0
7
332000
6.8 5.2
6
6.6 5.6 6.5
6.0
331000
5.5
5
6.4
8
6.
6.4
6.6
330000
6
6.2 5.2
6.4 5.8
rate
0.006
0.004
0.002
0.000
Figure 17: SIDS rate in North Carolina
spdep: Example
library(spdep)
nc = as(nc, "Spatial")
nb = poly2nb(nc)
spdep: Example
summary(nb)
## Neighbour list object:
## Number of regions: 100
## Number of nonzero links: 490
## Percentage nonzero weights: 4.9
## Average number of links: 4.9
## Link number distribution:
##
## 2 3 4 5 6 7 8 9
## 8 15 17 23 19 14 2 2
## 8 least connected regions:
## 4 21 45 56 77 80 90 99 with 2 links
## 2 most connected regions:
## 39 67 with 9 links
spdep: Example
nbw = nb2listw(nb)
spdep: Example
summary(nbw)
## Characteristics of weights list object:
## Neighbour list object:
## Number of regions: 100
## Number of nonzero links: 490
## Percentage nonzero weights: 4.9
## Average number of links: 4.9
## Link number distribution:
##
## 2 3 4 5 6 7 8 9
## 8 15 17 23 19 14 2 2
## 8 least connected regions:
## 4 21 45 56 77 80 90 99 with 2 links
## 2 most connected regions:
## 39 67 with 9 links
##
## Weights style: W
## Weights constants summary:
## n nn S0 S1 S2
## W 100 10000 100 44.65023 410.4746
spdep: Example
I Moran’s I is the most common global test for spatial
auto-correlation
I Values of I range from −1 to +1, with the expected value
being −1/(N − 1)
I Low values indicate negative spatial autocorrelation
I High values indicate positive spatial autocorrelation
moran.test(nc$rate, nbw)
##
## Moran I test under randomisation
##
## data: nc$rate
## weights: nbw
##
## Moran I statistic standard deviate = 2.3625, p-value = 0.009075
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic Expectation Variance
## 0.142750422 -0.010101010 0.004185853
Disease mapping
0.1 0.14
0.0
4
0.2
0.1
6
0.06
6
0.04 0.1
0.0
0.16
0.04 0.04 0.16
0.06 0.12
2 0.08
0.1 0.06
0.04 0.06
0.1 0.1 0.08
0.04 0.04
0.06 0.04
0.04
0.08
0.06 0.08 0.06
0.04 0.04 0.04 0.06
2
0.1
0.08 0.04
0.04 0.04
0.12 0.06
0.1
0.14
0.06
0.04 0.06
0.06 0.04
0.1
0.04
0.14
0.1 0.04
0.04 0.04 6
0.04
0.0
2
0.1 0.14 0.12
0.1
6
0.06
0.0
6
0.1
0.18 0.08
6
Figure 20: Distance map for the Biological Cells Point Pattern dataset
spatstat: Example
library(spatstat)
cells
## Planar point pattern: 42 points
## window: rectangle = [0, 1] x [0, 1] units
japanesepines
## Planar point pattern: 65 points
## window: rectangle = [0, 1] x [0, 1] units (one unit = 5.7 metres)
redwood
## Planar point pattern: 62 points
## window: rectangle = [0, 1] x [-1, 0] units
spatstat: Example
plot(cells)
plot(japanesepines)
plot(redwood)
Figure 21: Distance map for the Biological Cells Point Pattern dataset
spatstat: Example
I Ripley’s K-function measures the expected number of
random points within a distance r of a typical random point of
a point pattern X
Kpines = envelope(
japanesepines,
fun = Kest,
r = r,
nsim = 99
)
Kredwood = envelope(
redwood,
fun = Kest,
r = r,
nsim = 99
)
spatstat: Example
plot(Kcells)
plot(Kpines)
plot(Kredwood)
0.20
0.20
0.20
K ob s (r ) K ob s (r ) K ob s (r )
^ ^ ^
K t h eo (r ) K t h eo (r ) K t h eo (r )
0.15
K h i (r ) K h i (r ) K h i (r )
^ ^ ^
0.15
0.15
K l o (r ) K l o (r ) K l o (r )
^ ^ ^
0.10
K (r )
K (r )
K (r )
0.10
0.10
0.05
0.05
0.05
0.00
0.00
0.00
0.00 0.05 0.10 0.15 0.20 0.00 0.05 0.10 0.15 0.20 0.00 0.05 0.10 0.15 0.20
Figure 22: Distance map for the Biological Cells Point Pattern dataset
osmdata: Access to OpenStreetMap data
I Accessing OpenStreetMap (OSM) data using the Overpass API
library(osmdata)
plot(lines)
osmdata: Access to OpenStreetMap data
osm_id highway
5
http://spatial.ly/2012/02/great-maps-ggplot2/
ggplot2, ggmap: Visualization
6
http://spatial.ly/2012/02/great-maps-ggplot2/
leaflet, mapview: Web mapping
library(mapview)
states = st_read("data/us-states.geojson")
pal = colorBin(
palette = "YlOrRd",
domain = states$density,
bins = c(0, 10, 20, 50, 100, 200, 500, 1000, Inf)
)
pal(153)
## [1] "#FD8D3C"
leaflet: Example
labels = paste0(
"<b>",
states$name,
"</b><br/>",
format(round(states$density, 2), nsmall = 2),
" people / mi<sup>2</sup>"
) %>%
lapply(htmltools::HTML)
leaflet: Example
leaflet(states) %>%
setView(-96, 37.8, 4) %>%
addProviderTiles("CartoDB.DarkMatterNoLabels") %>%
leaflet: Example
I Adding polygonal layer with addPolygons
addPolygons(
fillColor = ~pal(density),
weight = 2,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7,
highlight = highlightOptions(
weight = 5,
color = "#666",
dashArray = "",
fillOpacity = 0.7,
bringToFront = TRUE
),
label = labels,
labelOptions = labelOptions(
style = list("font-weight" = "normal", padding = "3px 8px"),
textsize = "15px",
direction = "auto"
)
) %>%
leaflet: Example
addLegend(
pal = pal,
values = ~density,
opacity = 0.7,
title = NULL,
position = "bottomright"
)
leaflet: Example
I Geometry
I maptools, dggridR
I Routing
I gdistance, stplanr
I Statistics
I dbscan, gwrr, geoR, nlme, FRK
I Visualization
I rasterVis
I Web APIs
I ggmap
Books
I Hierarchical Modeling and Analysis for Spatial Data (1st
ed 2003, 2nd ed. 2014)
I Model-based Geostatistics (2007)
I Applied Spatial Data Analysis with R (1st ed. 2008, 2nd
ed. 2013)
I A Practical Guide for Geostatistical Mapping (2009)
I Spatial Data Analysis in Ecology and Agriculture using R
(2012)
I Displaying Time Series, Spatial, and Space-Time Data
with R (2014)
I Learning R for Geospatial Analysis (2014)
I An Introduction to R for Spatial Analysis and Mapping
(2015)
I Spatial Point Patterns: Methodology and Applications
with R (2015)
I Geocomputation with R (2018)7
7
https://geocompr.robinlovelace.net/
Online courses and tutorials
I Courses
I https://mgimond.github.io/Spatial/index.html
I http://adamwilson.us/RDataScience/index.html
I http://geog.uoregon.edu/bartlein/courses/geog490/index.html
I Tutorials
I http://www.nickeubank.com/gis-in-r/
I http://neondataskills.org/spatial-data-gis/
Thank you for listening!