Generate IDs for nested grid cells in R

I have generated 1km grid cells:

library(sf)

BBox <- st_bbox(c(xmin = 0, xmax = 10000, ymax = 10000, ymin = 0), crs = st_crs(27700))

Grid_1km  <- st_as_sfc(BBox) %>%
             st_make_grid(square = TRUE, cellsize = c(1e3, 1e3)) %>%
             cbind(data.frame(ID = sprintf(paste("GID%0",nchar(length(.)),"d",sep=""), 1:length(.)))) %>%
             st_sf()

I would like to generate 500m, 250m and 125m grid cells that nest within each 1km cell and then use a naming scheme to give each cell a unique ID.

This can be used to create the grid cells:

Grid_500m  <- st_as_sfc(BBox) %>%
             st_make_grid(square = TRUE, cellsize = c(5e2, 5e2)) 
             
Grid_250m  <- st_as_sfc(BBox) %>%
             st_make_grid(square = TRUE, cellsize = c(2.5e2, 2.5e2)) 

Grid_125m  <- st_as_sfc(BBox) %>%
             st_make_grid(square = TRUE, cellsize = c(1.25e2, 1.25e2)) 

I would like each 500m, 250m and 125 cell to reference the ID given to the 1km cell that it nests within and use the naming convention illustrated below to assign ID's to each cell of the hierarchy. So for example, the top left 125m cell in GID001 would be GID001333.

Cell ID naming scheme

I am not sure the best way to generate these IDs. The real 1km IDs I am working with are more randomly ordered than presented in my example - so I assume some some sort of spatial operation will be needed to identity the 1km grid cell ID. After this I would guess there is a mathematical way of doing what I am after that will be the most efficient?

1 answer

  • answered 2021-03-04 10:08 Jindra Lacko

    When facing this issue myself - my use case called for preserving the original numeric Id of a big cell and supplement it by character (a, b, c, d) - I used code like this.

    It is built around st_contains = getting indexes of small cells contained in the "big ones", and creating a vector of ids for each.

    I do not presume to call it the best or most efficient way to generate the ids, and it likely does not scale indefinitely, but it works.

    library(sf)
    library(dplyr)
    
    BBox <- st_bbox(c(xmin = 0, 
                      xmax = 2000, 
                      ymax = 2000, 
                      ymin = 0), crs = st_crs(27700))
    
    grid_1000  <- st_as_sfc(BBox) %>%
      st_make_grid(square = TRUE, cellsize = c(1e3, 1e3)) %>% 
      st_sf() %>% 
      mutate(id_1000 = 1:nrow(.)) # this will be "final" id
    
    grid_500  <- st_as_sfc(BBox) %>%
      st_make_grid(square = TRUE, cellsize = c(500, 500)) %>% 
      st_sf() %>% 
      mutate(idx_500 = 1:nrow(.)) # this is just temporary
    
    # a technical object to link sequences 
    asdf <- grid_1000 %>% 
      st_contains(grid_500) %>% 
      as.data.frame() %>%
      setNames(c("idx_1000", "idx_500"))
    
    asdf$id_1000 <- grid_1000$id_1000[asdf$idx_1000]
    
    asdf$id_500 <- paste0(asdf$id_1000, c("c", "d", "a", "b"))
    
    grid_500 <- grid_500 %>%
      inner_join(asdf, by = c("idx_500" = "idx_500")) %>%
      select(id_500) %>%
      st_set_agr("constant")
    
    # check validity
    library(ggplot2)
    
    ggplot(grid_1000) +
      geom_sf() +
      geom_sf_text(aes(label = id_1000))
    
    ggplot(grid_500) +
      geom_sf() +
      geom_sf_text(aes(label = id_500))
    

    4 big squares with ids

    16 small squares with ids