Skip to content

cell2cell #15

@mdsumner

Description

@mdsumner
cell2cell <- function(dm, blocksize, cell) {
  nc <- dm[1L]
  col0 <- (cell - 1L) %% nc          # 0-indexed col in source
  row0 <- (cell - 1L) %/% nc          # 0-indexed row in source
  
  tile_col <- col0 %/% blocksize[1L]  # 0-indexed tile col
  tile_row <- row0 %/% blocksize[2L]  # 0-indexed tile row
  
  n_tile_cols <- ceiling(dm[1L] / blocksize[1L])
  tile_row * n_tile_cols + tile_col + 1L
}

tile_lines <- function(dm, ex, blocksize, crs_src, crs_dst, n_dense = 100, reproj = TRUE) {
  nx <- dm[1L]; ny <- dm[2L]
  
  # tile boundary indices (0-indexed cell edges)
  x_breaks <- seq(ex[1], ex[2], length.out = nx + 1L)
  y_breaks <- seq(ex[3], ex[4], length.out = ny + 1L)
  
  tile_x <- x_breaks[seq(1L, nx + 1L, by = blocksize[1L])]
  tile_y <- y_breaks[seq(1L, ny + 1L, by = blocksize[2L])]
  
  # vertical lines (constant x), densified in y
  y_dense <- seq(ex[3], ex[4], length.out = n_dense)
  vlines <- lapply(tile_x, \(x) cbind(x = rep(x, n_dense), y = y_dense))
  
  # horizontal lines (constant y), densified in x
  x_dense <- seq(ex[1], ex[2], length.out = n_dense)
  hlines <- lapply(tile_y, \(y) cbind(x = x_dense, y = rep(y, n_dense)))
  
  all_lines <- c(vlines, hlines)
  if (!reproj) return(all_lines)
  # reproject each line
  invisible(lapply(all_lines, \(ln) reproj::reproj(ln, target = crs_dst, source = crs_src)))
}


src <- list(ex = c(-180, 180, -90, 90), dm = c(360, 180), crs  = "EPSG:4326")

dst <- list(ex = vaster::buffer_extent(reproj::reproj_extent(src$ex, tgt <- "+proj=laea", source = src$crs ), 1000), 
            dm = c(360, 360), crs = tgt)

library(terra)
r <- project(rast(sds::gebco()), rast(ext(src$ex), ncols = src$dm[1], nrows = src$dm[2], crs = src$crs), by_util = TRUE)
par(mfrow = c(2, 2))
plot(project(setValues(r, cell2cell(dim(r)[2:1], c(72, 36), seq_len(prod(dim(r)[2:1])))), 
             rast(ext(dst$ex), ncols = dst$dm[1], nrows = dst$dm[2], crs = dst$crs), by_util = TRUE))

lapply(tile_lines(src$dm, src$ex, c(72, 36), src$crs, dst$crs), lines)
plot(project(setValues(r, cell2cell(dim(r)[2:1], c(72, 36), seq_len(prod(dim(r)[2:1])))), 
             rast(ext(dst$ex), ncols = dst$dm[1], nrows = dst$dm[2], crs = dst$crs), by_util = TRUE))

lapply(tile_lines(dst$dm, dst$ex, c(72, 72), dst$crs, src$crs, reproj = FALSE), lines)

r2 <- project(rast(sds::gebco()), rast(ext(dst$ex), ncols = dst$dm[1], nrows = dst$dm[2], crs = dst$crs), by_util = TRUE)

plot(project(setValues(r2, cell2cell(dim(r2)[2:1], c(72, 72), seq_len(prod(dim(r2)[2:1])))), 
             rast(ext(src$ex), ncols = src$dm[1], nrows = src$dm[2], crs = src$crs), by_util = TRUE))

max_jump <- function(xy) {
  dx <- diff(xy[, 1]); dy <- diff(xy[, 2])
  max(sqrt(dx^2 + dy^2))
}

# cull lines where any single segment exceeds threshold
threshold <- diff(dst$ex[1:2]) * 0.3  # e.g. 30% of display width
reprojected_lines <- tile_lines(dst$dm, dst$ex, c(72, 72), dst$crs, src$crs)
good <- !(sapply(reprojected_lines, max_jump) < threshold)
good[is.na(good)] <- F
lapply(reprojected_lines[good], lines)
plot(project(setValues(r2, cell2cell(dim(r2)[2:1], c(72, 72), seq_len(prod(dim(r2)[2:1])))), 
             rast(ext(src$ex), ncols = src$dm[1], nrows = src$dm[2], crs = src$crs), by_util = TRUE))

lapply(tile_lines(src$dm, src$ex, c(72, 36), src$crs, dst$crs, reproj = FALSE), lines)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions