SOFaddict
SOFaddict

Reputation: 23

Overlaying ggmap map of area with LSOA shp file

I am trying to teach myself how to overlay a ggmap map of a town with a .shp, dividing that map up into LSOAs. By overlaying the map with LSOAs I hope to better communicate with local leaders, by clearly illustrating events in LSOAs that are relatable to specific areas, street names and local landmarks.

I am struggling!

In the tutorials I have read, these steps seem to be necessary:

  1. Obtain google maps API and create a ggmap map object using qmap
  2. Read in an LSOA shp file (in my case taken from HERE
  3. Bring the two together in a single ggplot plot, aligning latitude and longitude of the two objects in the aesthetics.

I have done this by:

    londonmap <- qmap("London")

    LSOA<- readOGR(".", "Lower_Layer_Super_Output_Areas_(December_2011)_Boundaries_Super_Generalised_Clipped_(BSC)_EW_V3")
 
    mymap <- londonmap + geom_polygon(aes(x = lon, y = lat), data = LSOA)

However, I get errors about longitude and latitude: "Error in FUN(X[[i]], ...) : object 'lon' not found"

Can anyone see where I'm going wrong? Is it something to do with the lat and long of the map object not matching the shp object?

Many thanks for any pointers you can spare!

EDIT:

dput(londonmap) returns:
structure(list(data =         structure(list(lon =         c(-0.566352679492181, 
0.312553570507799,   -0.566352679492181, 0.312553570507799),     lat = c(51.2324435804282, 
51.2324435804282, 51.7794952698017,     51.7794952698017)), out.attrs = list(
    dim = c(lon = 2L, lat = 2L),     dimnames = list(lon =  c("lon=-0.5663527", 
    "lon= 0.3125536"), lat =  c("lat=51.23244", "lat=51.77950"
    ))), class = "data.frame",   row.names = c(NA, -4L)), layers = list(
    <environment>, <environment>,  <environment>), scales = <environment>, 
    mapping = structure(list(x =     ~lon, y = ~lat), class = "uneval"), 
    theme =   structure(list(axis.title =   structure(list(), class =  c("element_blank", 
    "element")), axis.text =     structure(list(), class = c("element_blank", 
"element")), axis.ticks.length = structure(0, unit = 1L, class = c("simpleUnit", 
"unit", "unit_v2")), panel.background = structure(list(), class = c("element_blank", 
"element")), panel.spacing = structure(0, unit = 3L, class = c("simpleUnit", 
"unit", "unit_v2")), panel.grid.major = structure(list(), class = c("element_blank", 
"element")), panel.grid.minor = structure(list(), class = c("element_blank", 
"element")), plot.margin = structure(c(0, 0, 0, 0), unit = 3L, class = c("simpleUnit", 
"unit", "unit_v2")), legend.position = "right"), complete = FALSE, validate = TRUE), 
coordinates = <environment>, facet = <environment>, plot_env = <environment>, 
labels = list(x = "lon", y = "lat", xmin = "xmin", xmax = "xmax", 
    ymin = "ymin", ymax = "ymax")), class = c("gg", "ggplot"

)).

EDIT2:

Output of dput(LSOA) is enormous, and I'm not sure putting it here is possible?

Upvotes: 0

Views: 237

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 173803

The shape file is massive here, and you only need a small part of it to cover your map. Let's use sf to handle the shape file and trim it down to central London:

library(ggmap)
library(sf)

LSOA <- read_sf(path_to_shp) |>
          st_transform(crs = 4326)

london_shp <- LSOA[grepl("(Westminster)|(London)", LSOA$LSOA11NM),]

We will also get a somewhat zoomed-in map of London so we can actually see the detail of the shape file:

londonmap <- ggmap(get_map(c(lon = -0.15, lat = 51.51), zoom = 12))

Now the plotting code is just:

londonmap + 
  geom_sf(data = london_shp, aes(fill = LSOA11NM), inherit.aes = FALSE,
          alpha = 0.5) +
  guides(fill = guide_none())

enter image description here

Upvotes: 1

Related Questions