rgeospatialr-sfsfnetwork

nearest neighbour join between two sfc_LINESTRING objects


I have two adjacent areas, on which I have a connected grid that each take the structure of sfc_LINESTRING. One area is larger and has a coarser grid, and the other is smaller with a finer grid.

I want to be able to do a join so at least one of the points from the larger grid is connected to at least one of the points from the smaller grids. The overall goal is to be able to have a connection between the two grids so I can use sfnetworks to make a network that includes all the nodes from both sampled areas.

Is there an easy way to go about doing this? I couldn't get st_join or merge to work on these objects.

here's some code:

library(sf)
library(nngeo)

nc = st_read(system.file("shape/nc.shp", package="sf"))
nc_utm = st_transform(nc, crs="+proj=utm +zone=18 +datum=NAD83 +unit=m") # using UTM

# crop the area to two smaller areas for sampling the grids
area_1 <- st_crop(nc_utm, xmin = 0, xmax = 20000, 
                  ymin = 3950000, ymax = 4000000)
area_2 <- st_crop(nc_utm, xmin = 20100, xmax = 25000, 
                  ymin = 3960000, ymax = 3980000)

# sample the grids and connect each
grid_1 <- sf::st_sample(
  area_1, size = 25, type = 'regular') %>% 
  sf::st_as_sf() %>%
  nngeo::st_connect(.,.,k = 9)

grid_2 <- sf::st_sample(
  area_2, size = 25, type = 'regular') %>% 
  sf::st_as_sf() %>%
  nngeo::st_connect(.,.,k = 9)

# plot it 
ggplot() + 
  geom_sf(data = nc_utm) +
  geom_sf(data = area_1, fill = 'blue', alpha = 0.3) + 
  geom_sf(data = area_2, fill = "red", alpha = 0.3) + 
  geom_sf(data = grid_1, colour = "blue") + 
  geom_sf(data = grid_2, colour = "red") +
  coord_sf(datum = "+proj=utm +zone=18 +datum=NAD83 +unit=m",
           xlim = c(-10000, 30000), ylim = c(3940000, 4001000))

Solution

  • @mrhellman gave the tip that solved this for me. st_connect(st_combine(grid_1), st_combine(gird_2)) returns a single linestring that connects the two grids above.

    Here's how it works with an additional area to show that it scales:

    grid_3 <- sf::st_sample(
      area_3, size = 25, type = 'regular') %>% 
      sf::st_as_sf() %>%
      nngeo::st_connect(.,.,k = 9)
    
    grid_connect <- nngeo::st_connect(st_combine(grid_1), st_combine(grid_2))
    
    grid_connect2 <- nngeo::st_connect(st_combine(grid_1), st_combine(grid_3))
    
    all_grids <- c(grid_1, grid_2, grid_3, grid_connect, grid_connect2)
    

    And can be visualized as one single grid:

    ggplot() + 
      geom_sf(data = nc_utm) +
      geom_sf(data = area_1, fill = 'blue', alpha = 0.3) + 
      geom_sf(data = area_2, fill = "red", alpha = 0.3) + 
      geom_sf(data = area_3, fill = "yellow", alpha = 0.3) + 
      geom_sf(data = grid_1, colour = "blue") + 
      geom_sf(data = grid_2, colour = "red") +
      geom_sf(data = all_grids, colour = "purple", size = 2) +
      coord_sf(datum = "+proj=utm +zone=18 +datum=NAD83 +unit=m",
               xlim = c(-10000, 30000), ylim = c(3940000, 4001000))
    

    enter image description here