Friday, January 13, 2012

Exercise in grImport

Last week I used grImport for the first time. I decided to try perform another exercise using it. The task was to add voivodeship division of Poland.

Standard R maps do not contain such a division. I have found it on r-forge in package  mapoland based on ESRI shape files, but I wanted to import such a map from SVG file which can be found on Wikipedia. As last time SVG file has to be converted do PS first. Here is a comparison of both maps showing that the import worked quite well.


And this is the code I have used:

library(grImport)
PostScriptTrace("Wojewodztwa.ps")
voiv <- readPicture("Wojewodztwa.ps.xml")
broken.voiv <- explodePaths(voiv)

#extracting voivodeship 'PictureStrokes'
xpath <- ypath <- list()
sel <- c(2,4,6,8,20,22,24,28,30,32,34,36,38,41,44,46)
for (i in seq(along = sel)) {
      xpath[[i]] <- broken.voiv[[sel[i]]]@paths$path@x
      ypath[[i]] <- broken.voiv[[sel[i]]]@paths$path@y
}
#adding Wolin island to zachodniopomorskie
xpath[[2]] <- c(broken.voiv[10]@paths$path@x[c(39:1, 95:40)],
                xpath[[2]])
ypath[[2]] <- c(broken.voiv[10]@paths$path@y[c(39:1, 95:40)],
                ypath[[2]])

library(mapoland)
pl <- getShape("voiv")

#functions rescaling paths to mapoland map size
transx <- function(x) {
      old <- c(min(sapply(xpath,min)), max(sapply(xpath,max)))
      new <- pl@bbox[1,]
      ((x - old[1]) / (old[2] - old[1])) * (new[2] - new[1])
    + new[1]
}

transy <- function(y) {
      old <- c(min(sapply(ypath, min)), max(sapply(ypath, max)))
      new <- pl@bbox[2,]
      ((y - old[1]) / (old[2] - old[1])) * (new[2] - new[1])
    + new[1]
}

plot(pl, lwd = 4)
for (i in seq(along = sel)) {
      lines(transx(xpath[[i]]), transy(ypath[[i]]), col = "red")
}

2 comments:

  1. Thank you for the blog post. I try to do exactly the same with an svg file. Unfortunately, i got stuck at converting my svg into an ps file. I tried the following:
    -Inkscape: Returns a .ps file, but there are no paths included
    -image.online-convert.com: returns a .ps file, but there are no paths in the .ps, only an image.

    -as converting the file from your example works with inkscape, i tried to adjust the incoming svg so they're the same.

    I tried giving them the same header, but inkscape still does not convert it into a path .ps. An example of the svg looks like this:



    The Program used for creating this svg is:

    Do you know any way to get this kind of SVG to convert correctly as a .ps or is there any other way to plot this SVG in R?

    ReplyDelete
  2. Unfortunately I can't see your file in the comment. I used Inkscape for my example. If it does not work the other thing I did in the past was extracting the shapes from SVG file by parsing XML that is contained in it.

    ReplyDelete