ExtractTile.R 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. ExtractTile <-
  2. function(Data, Rows, Cols, Grid = FALSE)
  3. {
  4. if(!is.object(Data)) stop("Data input should be an R object - numeric vector, matrix, or data frame.")
  5. if(!is.vector(Data) & !is.matrix(Data) & !is.data.frame(Data)){
  6. stop("Data should be a vector (one tile), or a matrix/data.frame (multiple tiles).")
  7. }
  8. if(is.vector(Data)) Data <- matrix(Data, nrow = 1, ncol = length(Data))
  9. if(is.data.frame(Data)) Data <- as.matrix(Data)
  10. if(!is.numeric(Data)) stop("Data is not numeric class: should be MODIS data only to extract a nested subset.")
  11. if(ncol(Data) <= 1) stop("Not enough pixels (columns) found to extract a subset.")
  12. if(!is.numeric(Rows) | !is.numeric(Cols)) stop("Rows and Cols should be both be numeric class - two integers.")
  13. if(length(Rows) != 2 | length(Cols) != 2) stop("Rows and Cols input must both be a vector of integers, with two elements.")
  14. if(abs(Rows[1] - round(Rows[1])) > .Machine$double.eps^0.5 |
  15. abs(Rows[2] - round(Rows[2])) > .Machine$double.eps^0.5 |
  16. abs(Cols[2] - round(Cols[2])) > .Machine$double.eps^0.5 |
  17. abs(Cols[2] - round(Cols[2])) > .Machine$double.eps^0.5){
  18. stop("Size input must be integers.")
  19. }
  20. if((Rows[1] %% 2) != 1 | (Cols[1] %% 2) != 1) stop("The dimensions from any tile downloaded should be odd numbered")
  21. # Check Rows & Cols [1] == ncol Data, i.e. the length of data in a tile fits a matrix of dim Rows[1] & Cols[1]
  22. if(ncol(Data) != length(matrix(nrow=Rows[1], ncol=Cols[1]))) stop("Tile size of Data does not match Rows and Cols input.")
  23. if(((Rows[2] * 2) + 1) >= Rows[1] & ((Cols[2] * 2) + 1) >= Cols[1]) stop("Tile size requested is not smaller than Data.")
  24. if(!is.logical(Grid)) stop("Grid should be logical, to specify the format of the output.")
  25. #####
  26. # Get Data into a workable format and work out the subscripts of the nested subset.
  27. full.tile <- apply(Data, 1, function(x) list(matrix(x, nrow = Rows[1], ncol = Cols[1], byrow = TRUE)))
  28. centre <- c(ceiling(nrow(full.tile[[1]][[1]]) / 2), ceiling(ncol(full.tile[[1]][[1]]) / 2))
  29. row.range <- (centre[1] - Rows[2]):(centre[1] + Rows[2])
  30. col.range <- (centre[2] - Cols[2]):(centre[2] + Cols[2])
  31. # Put output in either array or matrix format.
  32. if(Grid){
  33. res <- array(dim = c( ((Rows[2] * 2) + 1), ((Cols[2] * 2) + 1), nrow(Data)))
  34. for(i in 1:nrow(Data)) res[ , ,i] <- full.tile[[i]][[1]][row.range,col.range]
  35. } else if(!Grid){
  36. res <- matrix(nrow = nrow(Data), ncol = length(matrix(nrow=((Rows[2] * 2) + 1), ncol = ((Cols[2] * 2) + 1))))
  37. for(i in 1:nrow(Data)) res[i, ] <- as.vector(full.tile[[i]][[1]][row.range,col.range])
  38. }
  39. return(res)
  40. }