1

A similar question has been asked before, but for adding data from different columns of one data frame to the plot. Link to the question

In my case, I would like to add new map layers, if they exist in the global environment, to my final map with a "for" loop.

With the code as it is now, only the final layer, the points, is plotted to the map, but not the line layer:

rm(list = ls())  
library(OpenStreetMap)
library(ggplot2)
library(sp)

### The base layer map
map <- OpenStreetMap::openmap(c(55.8759, -4.2946), c(55.8638, -4.2776), type="osm")
map <- openproj(map)
myMap <- ggplot2::autoplot(map)

### Create some custom map files
# Some spatial point
new_shapefile <- data.frame(long = -4.290, lat = c(55.868, 55.872))
sp::coordinates(new_shapefile) <- c("long", "lat")
sp::proj4string(new_shapefile) <- sp::CRS("+init=epsg:4326")

# Some spatial line
x <- c(-4.290,-4.285)
y <- c(55.868,55.868)
new_line <- SpatialLines(list(Lines(Line(cbind(x,y)), ID="a")))
new_line = SpatialLinesDataFrame(new_line, data.frame(Z = c("Road"), row.names = c("a")))


addLayer <- function(){
  glob <- globalenv()
  customFiles <- data.frame(ls(pattern = "^(?i)new", envir = glob))
  colnames(customFiles) <- "X"
  customFiles$X <- as.character(customFiles$X)
  for(i in 1:length(customFiles$X)){
    plot <- myMap
    gg.data <- get(paste(customFiles$X[i]))
    if(grepl("^SpatialPolygons", class(get(paste(customFiles$X[i])))) == TRUE){
      plot <- plot + geom_polygon(data = gg.data, aes(long, lat, group= group))
    }
    if(grepl("^SpatialLines", class(get(paste(customFiles$X[i])))) == TRUE){
      plot <- plot + geom_path(data = gg.data, aes(long, lat, group= group))
    }
    if(grepl("^SpatialPoints", class(get(paste(customFiles$X[i])))) == TRUE){
      plot <- plot + geom_point(data = data.frame(coordinates(gg.data)), aes(long, lat))
     }
  }
  print(plot)
}


### Run the function
addLayer()

enter image description here

Since I can't use melt to solve this, as suggested in the previous question: Is there any other way to plot all of the layers in the "for" loop?

Community
  • 1
  • 1
Joris
  • 417
  • 4
  • 17
  • You are starting with a "fresh" `plot` in each iteration of the loop. You probably want to initiate the plot, `plot <- myMap`, just before you start the loop. It looks like "gg.data" in each `if` statement also will need work. In the points layer you turn this into a data.frame so that layer works fine, but you use "gg.data" directly in the other layers and it doesn't appear to be a data.frame. – aosmith Nov 29 '16 at 15:22
  • Thanks you so much, moving the `plot <- myMap` before the "for" loop actually solved it!! I turned only the points layer into a data.frame, since it otherwise gave me an error: `ggplot2 doesn't know how to deal with data of class SpatialPoints` – Joris Nov 29 '16 at 15:36

1 Answers1

1

You are currently initiating your base map at the beginning in each iteration of the loop, which replaces plot that you made in the previous iteration. Initiate the base map before starting the loop to add all layers to the same map.

addLayer <- function(){
  glob <- globalenv()
  customFiles <- data.frame(ls(pattern = "^(?i)new", envir = glob))
  colnames(customFiles) <- "X"
  customFiles$X <- as.character(customFiles$X)
  plot <- myMap
  for(i in 1:length(customFiles$X)){
  gg.data <- get(paste(customFiles$X[i]))
  if(grepl("^SpatialPolygons", class(get(paste(customFiles$X[i])))) == TRUE){
      plot <- plot + geom_polygon(data = gg.data, aes(long, lat, group= group))
    }
    if(grepl("^SpatialLines", class(get(paste(customFiles$X[i])))) == TRUE){
      plot <- plot + geom_path(data = gg.data, aes(long, lat, group= group))
    }
    if(grepl("^SpatialPoints", class(get(paste(customFiles$X[i])))) == TRUE){
      plot <- plot + geom_point(data = data.frame(coordinates(gg.data)), aes(long, lat))
     }
  }
  print(plot)
}
aosmith
  • 34,856
  • 9
  • 84
  • 118