Skip to content

Instantly share code, notes, and snippets.

@pepijn-devries
Last active January 6, 2017 11:03
Show Gist options
  • Save pepijn-devries/43d864271ef2b7a189aa72450804267b to your computer and use it in GitHub Desktop.
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
## 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