Last active
January 6, 2017 11:03
-
-
Save pepijn-devries/43d864271ef2b7a189aa72450804267b to your computer and use it in GitHub Desktop.
An example of how to fill a SpatialPolygons object with a png image
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Required libraries for this example | |
library(png) | |
library(sp) | |
library(maptools) | |
library(raster) | |
## A function as a wrapper around 4 of the 5 steps | |
## described in the main text of the blog.... | |
## As input it requires a SpatialPolygons object | |
## and the URL to the png image that will be used | |
## to fill the SpatialPolygons object. Additional | |
## arguments are passed onto the plotRGB function | |
## from the raster package. | |
plot.masked.image <- function(sp, png.url, ...) { | |
############################################### | |
## STEP 2 ## | |
############################################### | |
## First step is to read the png file, in this | |
## case from an url... | |
## Note that step 1 is shown below and is executed | |
## before calling this function... | |
## open an url connection to the png file | |
u <- url(png.url, "rb") | |
## I'm assuming here that the png file is less | |
## then 10 MiB (just increase the number if it is larger). | |
img.dat <- readBin(u, "raw", 10*1024*1024) | |
## close the url connection... | |
close(u) | |
## convert the raw data read from the file into a | |
## raster object: | |
img.dat <- readPNG(img.dat) | |
############################################### | |
## STEP 3 ## | |
## Georeference the image, such that it ## | |
## matches the location of the country ## | |
############################################### | |
## convert the raster object into | |
## a raster brick object and georeference | |
## it using the extent and CRS of the | |
## SpatialPolygons object 'sp'. | |
img <- brick(img.dat, | |
xmn = extent(sp)@xmin, | |
xmx = extent(sp)@xmax, | |
ymn = extent(sp)@ymin, | |
ymx = extent(sp)@ymax, | |
crs = CRS(proj4string(sp))) | |
############################################### | |
## STEP 4 ## | |
## Use the 'over' function to determine ## | |
## which pixels are inside the country shape ## | |
############################################### | |
indices <- over(as(img, "SpatialGrid"), sp) | |
## set the RGB values that do not overlap with | |
## SpatialPolygons object sp to NA | |
img[is.na(indices)] <- NA | |
############################################### | |
## STEP 5 ## | |
## Plot the pixels of the image that are ## | |
## inside the country and plot the outline ## | |
############################################### | |
## This is done by plotting the resulting | |
## rasterbrick as RGB. | |
## 'bgalpha = 0' is important as otherwise | |
## you may interfere with previously plotted | |
## shapes... | |
plotRGB(img, 1, 2, 3, 1, bgalpha = 0, ...) | |
} | |
############################################### | |
## STEP 1 ## | |
## Download the country shape(s) ## | |
############################################### | |
## Download several country's outlines from gadm.org: | |
nld <- raster::getData("GADM", country = "NLD", level = 1) | |
nld <- unionSpatialPolygons(nld, nld@data$ENGTYPE_1 != "Water body")[2] | |
uk <- raster::getData("GADM", country = "GBR", level = 0) | |
bel <- raster::getData("GADM", country = "BEL", level = 0) | |
fr <- raster::getData("GADM", country = "FRA", level = 0) | |
de <- raster::getData("GADM", country = "DEU", level = 0) | |
lux <- raster::getData("GADM", country = "LUX", level = 0) | |
## specify a bounding box, to initialise the base plot | |
box <- as(extent(-5.5, 8, 48, 58.5), "SpatialPolygons") | |
proj4string(box) <- proj4string(nld) | |
## open a graphics device for the resulting plot and save as png: | |
png("flagmap.png", 400, 500, type = "cairo") | |
## Get rid of the margins | |
par(mar = c(0, 0, 0, 0)) | |
## Initialise the base plot | |
plot(box, border = NA, xaxs = "i", yaxs = "i") | |
## Call the magical function defined above. | |
## For each country use the flag image as | |
## available from wikipedia. | |
## The resolution of the flag-image can be | |
## increased, simply by increasing the 800px | |
## bit in the url into for instance 1200px... | |
plot.masked.image(nld, "https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Flag_of_the_Netherlands.svg/800px-Flag_of_the_Netherlands.svg.png", add = T) | |
plot(nld, add = T, lwd = 2) | |
plot.masked.image(bel, "https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/Flag_of_Belgium.svg/800px-Flag_of_Belgium.svg.png", add = T) | |
plot(bel, add = T, lwd = 2) | |
plot.masked.image(lux, "https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/Flag_of_Luxembourg.svg/800px-Flag_of_Luxembourg.svg.png", add = T) | |
plot(lux, add = T, lwd = 2) | |
plot.masked.image(uk, "https://upload.wikimedia.org/wikipedia/en/thumb/a/ae/Flag_of_the_United_Kingdom.svg/800px-Flag_of_the_United_Kingdom.svg.png", add = T) | |
plot(uk, add = T, lwd = 2) | |
plot.masked.image(fr, "https://upload.wikimedia.org/wikipedia/en/thumb/c/c3/Flag_of_France.svg/800px-Flag_of_France.svg.png", add = T) | |
plot(fr, add = T, lwd = 2) | |
plot.masked.image(de, "https://upload.wikimedia.org/wikipedia/en/thumb/b/ba/Flag_of_Germany.svg/800px-Flag_of_Germany.svg.png", add = T) | |
plot(de, add = T, lwd = 2) | |
## make sure to turn off the graphical device: | |
dev.off() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment