Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
I’d like to introduce you to the Grid2Polygons function; an R function for converting sp spatial objects from class SpatialGridDataFrame to SpatialPolygonsDataFrame. The significance of this conversion is that spatial polygons can be transformed to a different projection or datum with the spTransform function in package rgdal. Postscript files created with spatial polygons are reduced in size and result in a much “cleaner” version of your image. Disadvantages of the conversion include long computational times and irreversible leveling, partitioning the range of z values. A general explanation of the algorithm is provided here; inspiration provided here.
To access the function install the Grid2Polygons package (source):
install.packages("Grid2Polygons") library(Grid2Polygons)
See help documentation for argument descriptions:
?Grid2Polygons
The following examples highlight the functions usefulness:
Example 1
Construct a simple spatial grid data frame.
m <- 5 n <- 6 z <- c(1.1, 1.5, 4.2, 4.1, 4.3, 4.7, 1.2, 1.4, 4.8, 4.8, NA, 4.1, 1.7, 4.2, 1.4, 4.8, 4.0, 4.4, 1.1, 1.3, 1.2, 4.8, 1.6, NA, 3.3, 2.9, NA, 4.1, 1.0, 4.0) x <- rep(0:6, m + 1) y <- rep(0:5, each = n + 1) xc <- c(rep(seq(0.5, 5.5, by = 1), m)) yc <- rep(rev(seq(0.5, 4.5, by = 1)), each = n) grd <- data.frame(z = z, xc = xc, yc = yc) coordinates(grd) <- ~ xc + yc gridded(grd) <- TRUE grd <- as(grd, "SpatialGridDataFrame")
Plot the grid using a gray scale to indicate values of z (fig. 1).
image(grd, col = gray.colors(30), axes = TRUE) grid(col = "black", lty = 1) points(x = x, y = y, pch = 16) text(cbind(xc, yc), labels = z) text(cbind(x = x + 0.1, y = rev(y + 0.1)), labels = 1:42, cex = 0.6)
Figure 1: Simple spatial grid data frame.
Convert the grid to spatial polygons and overlay in plot (fig. 2). Leveling is specified with cut locations at 1, 2, 3, 4, and 5, and z-values set equal to the midpoint between breakpoints. A “winding rule” is used to determine if a polygon ring is filled (island) or is a hole in another polygon.
plys <- Grid2Polygons(grd, level = TRUE, at = 1:5) cols <- rainbow(4, alpha = 0.3) plot(plys, col = cols, add = TRUE) x <- rep(0:6, m + 1) y <- rep(0:5, each = n + 1) legend("top", legend = plys[[1]], fill = cols, bty = "n", xpd = TRUE, inset = c(0, -0.1), ncol = 4)
Figure 2: Simple gridded data represented with spatial polygons.
Example 2
Apply the conversion function to the meuse data set, included in the sp package. The effect of leveling is shown in figure 3.
data(meuse.grid) coordinates(meuse.grid) <- ~ x + y gridded(meuse.grid) <- TRUE meuse.grid <- as(meuse.grid, "SpatialGridDataFrame") meuse.plys <- Grid2Polygons(meuse.grid, "dist", level = FALSE) op <- par(mfrow = c(1, 2), oma = c(0, 0, 0, 0), mar = c(0, 0, 0, 0)) z <- meuse.plys[[1]] col.idxs <- findInterval(z, sort(unique(na.omit(z)))) cols <- heat.colors(max(col.idxs))[col.idxs] plot(meuse.plys, col = cols) title("level = FALSE", line = -7) meuse.plys.lev <- Grid2Polygons(meuse.grid, "dist", level = TRUE) z <- meuse.plys.lev[[1]] col.idxs <- findInterval(z, sort(unique(na.omit(z)))) cols <- heat.colors(max(col.idxs))[col.idxs] plot(meuse.plys.lev, col = cols) title("level = TRUE", line = -7) par(op)
Figure 3: Distance from river represented with spatial polygons.
Example 3
A real-world example using topographic information on the eastern Snake River Plain; raster plot shown in figure 4.
library(rgdal) data(DEM) at <- seq(500, 4000, by = 250) op <- par(oma = c(0, 0, 0, 0), mar = c(0, 0, 0, 0)) image(DEM, breaks = at, col = terrain.colors(length(at) - 1))
Figure 4: Topographic information represented with a raster image.
Convert the grid to spatial polygons (fig. 5). The conversion took 22.7 seconds on my machine. The size of the postscript file created from the polygon image (1.89 MB) is 82.6 percent smaller than the size of the raster image file (10.86 MB).
dem.plys <- Grid2Polygons(DEM, level = TRUE, at = at) z <- dem.plys[[1]] col.idxs <- findInterval(z, at) cols <- terrain.colors(length(at) - 1)[col.idxs] plot(dem.plys, border = "transparent", col = cols)
Figure 5: Topographic information represented with spatial polygons.
Finally, transform the projection of the spatial polygons object (1.5 seconds) and replot (fig. 6).
dem.plys.trans <- rgdal::spTransform(dem.plys, CRS = CRS("+proj=eqc")) plot(dem.plys.trans, border = "transparent", col = cols) par(op)
Figure 6: Topographic information represented with spatial polygons and new projection.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.