Joris
Joris

Reputation: 417

ggplot map: "for" loop only adds final map layer

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?

Upvotes: 1

Views: 434

Answers (1)

aosmith
aosmith

Reputation: 36076

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)
}

Upvotes: 1

Related Questions