R/ExtractTile.R

Defines functions ExtractTile

Documented in ExtractTile

ExtractTile <- 
function(Data, Rows, Cols, Grid = FALSE)
{
  if(!is.object(Data)) stop("Data input should be an R object - numeric vector, matrix, or data frame.")
  
  if(!is.vector(Data) & !is.matrix(Data) & !is.data.frame(Data)){
    stop("Data should be a vector (one tile), or a matrix/data.frame (multiple tiles).")
  }
  
  if(is.vector(Data)) Data <- matrix(Data, nrow = 1, ncol = length(Data))
  if(is.data.frame(Data)) Data <- as.matrix(Data)
  
  if(!is.numeric(Data)) stop("Data is not numeric class: should be MODIS data only to extract a nested subset.")
  
  if(ncol(Data) <= 1) stop("Not enough pixels (columns) found to extract a subset.")
  
  if(!is.numeric(Rows) | !is.numeric(Cols)) stop("Rows and Cols should be both be numeric class - two integers.")
  if(length(Rows) != 2 | length(Cols) != 2) stop("Rows and Cols input must both be a vector of integers, with two elements.")
  if(abs(Rows[1] - round(Rows[1])) > .Machine$double.eps^0.5 | 
       abs(Rows[2] - round(Rows[2])) > .Machine$double.eps^0.5 |
       abs(Cols[2] - round(Cols[2])) > .Machine$double.eps^0.5 |
       abs(Cols[2] - round(Cols[2])) > .Machine$double.eps^0.5){
    stop("Size input must be integers.")
  }
  
  if((Rows[1] %% 2) != 1 | (Cols[1] %% 2) != 1) stop("The dimensions from any tile downloaded should be odd numbered")
  
  # Check Rows & Cols [1] == ncol Data, i.e. the length of data in a tile fits a matrix of dim Rows[1] & Cols[1]
  if(ncol(Data) != length(matrix(nrow=Rows[1], ncol=Cols[1]))) stop("Tile size of Data does not match Rows and Cols input.")
  
  if(((Rows[2] * 2) + 1) >= Rows[1] & ((Cols[2] * 2) + 1) >= Cols[1]) stop("Tile size requested is not smaller than Data.")
  
  if(!is.logical(Grid)) stop("Grid should be logical, to specify the format of the output.")
  #####
  
  # Get Data into a workable format and work out the subscripts of the nested subset.
  full.tile <- apply(Data, 1, function(x) list(matrix(x, nrow = Rows[1], ncol = Cols[1], byrow = TRUE)))
  centre <- c(ceiling(nrow(full.tile[[1]][[1]]) / 2), ceiling(ncol(full.tile[[1]][[1]]) / 2))
  row.range <- (centre[1] - Rows[2]):(centre[1] + Rows[2])
  col.range <- (centre[2] - Cols[2]):(centre[2] + Cols[2])
  
  # Put output in either array or matrix format.
  if(Grid){
    res <- array(dim = c( ((Rows[2] * 2) + 1), ((Cols[2] * 2) + 1), nrow(Data)))
    for(i in 1:nrow(Data)) res[ , ,i] <- full.tile[[i]][[1]][row.range,col.range]
  } else if(!Grid){
    res <- matrix(nrow = nrow(Data), ncol = length(matrix(nrow=((Rows[2] * 2) + 1), ncol = ((Cols[2] * 2) + 1))))
    for(i in 1:nrow(Data)) res[i, ] <- as.vector(full.tile[[i]][[1]][row.range,col.range])
  }
  
  return(res)
}
seantuck12/MODISTools documentation built on May 29, 2019, 4:55 p.m.