arcStats.R 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #' Get Summary of Local MODIS Data
  2. #'
  3. #' @description
  4. #' In the same manner as \code{\link{getHdf}}, this function quantifies the
  5. #' availability of local MODIS hdf data and gives you an overview (plot or/and
  6. #' table) of locally available MODIS grid hdf files.
  7. #'
  8. #' @param product \code{character}, see \code{\link{getProduct}}. MODIS grid
  9. #' product to be checked.
  10. #' @param collection \code{character} or \code{integer}, see
  11. #' \code{\link{getCollection}}. MODIS product version.
  12. #' @param extent Extent information, defaults to \code{'global'}. See
  13. #' \code{\link{getTile}}.
  14. #' @param begin \code{character}. Begin date of MODIS time series, see
  15. #' \code{\link{transDate}}.
  16. #' @param end \code{character}. End date, defaults to \code{'Today'} expressed in
  17. #' a function.
  18. #' @param asMap Controls output type. Possible options are \code{TRUE} (png),
  19. #' \code{FALSE} (csv) or \code{'both'}.
  20. #' @param outName \code{character}. Name of output file, defaults to
  21. #' 'product.collection.YYYYMMDDHHMMSS.png' (or *.csv) of the function call or,
  22. #' if applicable, 'product.collection.extent.YYYYMMDDHHMMSS.png' (or *.csv).
  23. #' @param ... Arguments passed to \code{\link{MODISoptions}}, most importantly
  24. #' \code{outProj} and \code{outDirPath}.
  25. #'
  26. #' @return
  27. #' An invisible \code{NULL} (provably this will change to a matrix-like object
  28. #' similar to the '*.csv' output). If \code{asMap= TRUE}, a 'table.csv' and a
  29. #' 'image.png' file(s) in \code{outDirPath}.
  30. #'
  31. #' @author
  32. #' Matteo Mattiuzzi
  33. #'
  34. #' @examples
  35. #' \dontrun{
  36. #' # arcStats result on a webserver:
  37. #' # "http://ivfl-info.boku.ac.at/index.php/eo-data-processing/status-of-the-local-archive"
  38. #' #
  39. #' # The following examples are expecting that you have some data stored locally!
  40. #' ###########################################################
  41. #' # generates 2 png's and 2 csv's one for TERRA one for AQUA
  42. #' arcStats(product="M.D13Q1")
  43. #'
  44. #' # generates 2 png's and 2 csv's one for TERRA one for AQUA with the specified countries.
  45. #' arcStats(product="M.D13Q1",extent=c("austria","germany","italy"))
  46. #'
  47. #' # generates 1 png and 1 csv for AQUA.
  48. #' arcStats(product="MYD13Q1",begin="2005001",outName="MyDataStart2005")
  49. #'
  50. #' # generates 1 png for AQUA for the selected area and plots it in 'Sinusoidal'.
  51. #' arcStats(product="MYD13Q1",begin="2005001",asMap=TRUE, outName="InteractiveSelection2005",
  52. #' extent=getTile(), outProj="asIn")
  53. #'
  54. #' # generates 1 png for AQUA for the selected area and plots it in 'Geographic' Coordinates.
  55. #' arcStats(product="MYD13Q1",begin="2005001",asMap=TRUE, outName="InteractiveSelection2005",
  56. #' extent=getTile(), outProj="GEOGRAPHIC")
  57. #' }
  58. #'
  59. #' @export arcStats
  60. #' @name arcStats
  61. arcStats <- function(product, collection=NULL, extent="global", begin="2000.01.01", end=format(Sys.time(), "%Y.%m.%d"), asMap=TRUE, outName=NULL,...)
  62. {
  63. # product="MYD17A2"; collection="005"; extent=list(xmin=-20,xmax=40,ymin=10, ymax=20); begin="2000.08.01"; end="2000.08.21"; asMap="both"; outName=NULL;u=1;z=1
  64. # product="MOD13Q1"; collection="005"; extent='global'; begin="2000.08.01"; end="2004.08.21"; asMap="both"; outName=NULL;u=1;z=1
  65. date4name <- format(Sys.time(), "%Y%m%d%H%M%S")
  66. if(is.null(outName))
  67. {
  68. if (inherits(extent,"character"))
  69. {
  70. outName <- paste(paste0(extent,collapse=""),date4name,sep="_")
  71. } else
  72. {
  73. outName <- date4name
  74. }
  75. }
  76. opts <- combineOptions(...)
  77. opts$localArcPath <- setPath(opts$localArcPath)
  78. opts$outDirPath <- setPath(opts$outDirPath)
  79. if (opts$outProj == "asIn")
  80. {
  81. opts$outProj <- "+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs"
  82. } else
  83. {
  84. opts$outProj <- checkOutProj(opts$outProj,tool="GDAL")
  85. }
  86. # product/dates/extent
  87. product <- getProduct(x=product, quiet=TRUE)
  88. product$CCC <- getCollection(product=product, collection=collection, quiet=TRUE)
  89. tLimits <- transDate(begin=begin, end=end)
  90. if (extent[1]=="global")
  91. {
  92. ext <- getTile(x = raster::extent(raster::raster()))
  93. } else
  94. {
  95. ext <- getTile(x = extent)
  96. }
  97. for (z in seq_along(product$PRODUCT))
  98. {
  99. prod <- product$PRODUCT[z]
  100. coll <- product$CCC[[which(names(product$CCC)==product$PRODUCT[z])]]
  101. todo <- paste0(prod,".", coll)
  102. ftpdirs <- as.Date(getStruc(product=prod,collection=coll, begin=tLimits$begin, end=tLimits$end, wait=0)$dates)
  103. expected <- ftpdirs[tLimits$begin <= ftpdirs & tLimits$end >= ftpdirs]
  104. expected <- expected[!is.na(expected)]
  105. path <- genString(x=prod,collection=coll,remote=FALSE,...)$localPath
  106. path <- strsplit(path,"/")[[1]]
  107. path <- paste0(path[-length(path)],collapse="/")
  108. allLocal <- list.files(path=path,pattern=".hdf$",recursive=TRUE,full.names=TRUE)
  109. if(length(allLocal)==0)
  110. {
  111. warnings(paste0("No ", todo, " files found!"))
  112. locDates <- NULL
  113. } else
  114. {
  115. # remove dates not in the query
  116. locDates <- sapply(allLocal,function(x)
  117. {
  118. date <- strsplit(normalizePath(dirname(x),winslash="/"),"/")[[1]]
  119. date <- date[length(date)]
  120. return(date)
  121. })
  122. locDates <- as.Date(locDates,"%Y.%m.%d")
  123. locDates <- allLocal[locDates%in%expected]
  124. }
  125. # remove not requested tiles
  126. if(length(locDates)==0)
  127. {
  128. tileinfo <- ext$tile
  129. } else if (extent[1]=="global")
  130. {
  131. tileinfo <- unique(sapply(basename(locDates),function(x){x <- getProduct(x);getPart(x,"TILE")}))
  132. } else
  133. {
  134. tileinfo <- ext$tile
  135. }
  136. available <- needed <- percent <- rep(0,length(tileNames))
  137. MBperHDF <- rep(NA,length(available))
  138. table <- data.frame(tileNames,available,needed,percent,MBperHDF)
  139. table[,"needed"] <- length(expected)
  140. colnames(table) <- c("tile", "available", "needed", "percent", "MBperHDF")
  141. # calculation section
  142. for (i in seq_along(tileinfo))
  143. {
  144. n <- grep(locDates,pattern=tileinfo[i],value=TRUE)
  145. if (length(n)!=0)
  146. {
  147. meanSize <- mean(fileSize(n,units="Mb"))
  148. n <- sapply(n,function(x)
  149. {
  150. date <- strsplit(normalizePath(dirname(x),winslash="/"),"/")[[1]]
  151. date <- date[length(date)]
  152. return(date)
  153. })
  154. n <- as.Date(n,"%Y.%m.%d")
  155. n <- sum(n %in% expected)
  156. } else
  157. {
  158. n <- 0
  159. meanSize <- NA
  160. }
  161. ind <- which(tileNames==tileinfo[i])
  162. table[ind,"available"] <- n
  163. table[ind,"percent"] <- round(100*(n/length(expected)),2)
  164. table[ind,"MBperHDF"] <- round(meanSize)
  165. }
  166. # mapping
  167. if (isTRUE(asMap)|tolower(asMap)=="both")
  168. {
  169. srx <- sr
  170. srx@data <- data.frame(percent=(round(table$percent)))
  171. # require(scales)
  172. # colors <- c("#00000000",colorRampPalette(c("red","blue","green"))(100)) # hollow + palette
  173. colors <- c("#00000000", "#FF0000", "#F90005", "#F4000A", "#EF000F", "#EA0014", "#E50019", "#E0001E", "#DA0024", "#D50029", "#D0002E", "#CB0033", "#C60038", "#C1003D", "#BC0042", "#B60048", "#B1004D", "#AC0052", "#A70057", "#A2005C", "#9D0061", "#970067", "#92006C", "#8D0071", "#880076", "#83007B", "#7E0080", "#790085", "#73008B", "#6E0090", "#690095", "#64009A", "#5F009F", "#5A00A4", "#5400AA", "#4F00AF", "#4A00B4", "#4500B9", "#4000BE", "#3B00C3", "#3600C8", "#3000CE", "#2B00D3", "#2600D8", "#2100DD", "#1C00E2", "#1700E7", "#1200EC", "#0C00F2", "#0700F7", "#0200FC", "#0002FC", "#0007F7", "#000CF2", "#0012EC", "#0017E7", "#001CE2", "#0021DD", "#0026D8", "#002BD3", "#0030CE", "#0036C8", "#003BC3", "#0040BE", "#0045B9", "#004AB4", "#004FAF", "#0055A9", "#005AA4", "#005F9F", "#00649A", "#006995", "#006E90", "#00738B", "#007985", "#007E80", "#00837B", "#008876", "#008D71", "#00926C", "#009767", "#009D61", "#00A25C", "#00A757", "#00AC52", "#00B14D", "#00B648", "#00BC42", "#00C13D", "#00C638", "#00CB33", "#00D02E", "#00D529", "#00DA24", "#00E01E", "#00E519", "#00EA14", "#00EF0F", "#00F40A", "#00F905", "#00FF00")
  174. xlim <- c(ext$extent@xmin,ext$extent@xmax)
  175. ylim <- c(ext$extent@ymin,ext$extent@ymax)
  176. xax <- data.frame(x=seq(-180,180,by=10),y=rep(0,37),tileID=c(0:35,""))
  177. yax <- data.frame(x=rep(0,19),y=seq(90,-90,by=-10),tileID=c(0:17,""))
  178. png(paste(opts$outDirPath,todo,".",outName,".png",sep=""), width = 800, height = 600)
  179. if(extent[1]=="global")
  180. {
  181. globe <- maps::map("world",plot=FALSE)
  182. } else
  183. {
  184. globe <- maps::map("worldHires",plot=FALSE,xlim=xlim,ylim=ylim)
  185. xax <- xax[xax$x>=min(xlim) & xax$x<=max(xlim),]
  186. yax <- yax[yax$y>=min(ylim) & yax$y<=max(ylim),]
  187. }
  188. sp::coordinates(xax) <- ~x+y
  189. sp::coordinates(yax) <- ~x+y
  190. sp::proj4string(xax) <- "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"
  191. sp::proj4string(yax) <- "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"
  192. globe$x[!is.na(globe$x) & globe$x > 180] <- 180
  193. globe <- maptools::map2SpatialLines(globe)
  194. #invisible(set_ll_warn(TRUE)) # shouldn't be necessary becaus of the trimming
  195. #iwa <- options()$warn
  196. #options(warn=-1)
  197. sp::proj4string(globe) <- "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"
  198. #options(warn=iwa)
  199. if(!isLonLat(opts$outProj))
  200. {
  201. tmp <- raster(ext$extent)
  202. projection(tmp) <- "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"
  203. tmp <- projectExtent(tmp,opts$outProj)
  204. xlim <- c(xmin(tmp),xmax(tmp))
  205. ylim <- c(ymin(tmp),ymax(tmp))
  206. xax <- sp::spTransform(xax,CRS(opts$outProj))
  207. yax <- sp::spTransform(yax,CRS(opts$outProj))
  208. globe <- sp::spTransform(globe,CRS(opts$outProj))
  209. srx <- sp::spTransform(srx,CRS(opts$outProj))
  210. }
  211. xax <- as.data.frame(xax)[,c("x","tileID")]
  212. yax <- as.data.frame(yax)[,c("y","tileID")]
  213. globe <- list("sp.lines", as(globe, "SpatialLines"), lwd=0.8)
  214. if(opts$outProj=="+proj=sinu +lon_0=0 +x_0=0 +y_0=0 +a=6371007.181 +b=6371007.181 +units=m +no_defs")
  215. {
  216. print(
  217. spplot(srx, zcol="percent", col.regions=colors, colorkey=TRUE,at=0:101,xlab="H-Tiles",ylab="V-Tiles", xlim=xlim, ylim=ylim, sp.layout=globe,
  218. scales=list(alternating=3,x=list(at=xax$x ,labels=xax$tileID,rot=90),y=list(at=yax$y,labels=yax$tileID)),
  219. main = paste("Percentage of '",todo,"' available on the local archive\nbetween ", tLimits$begin," and ", tLimits$end,sep=""), checkEmptyRC=FALSE)
  220. )
  221. } else
  222. {
  223. print(
  224. spplot(srx, zcol="percent", col.regions=colors, colorkey=TRUE,at=0:101, xlim=xlim, ylim=ylim, sp.layout=globe, scales=list(draw = TRUE),
  225. main = paste("Percentage of '",todo,"' available on the local archive\nbetween ", tLimits$begin," and ", tLimits$end,sep=""), checkEmptyRC=FALSE)
  226. )
  227. }
  228. dev.off()
  229. }
  230. if (!isTRUE(asMap)|asMap=="both")
  231. {
  232. if (extent[1]=="global")
  233. {
  234. out <- table
  235. } else
  236. {
  237. out <- table[table$tile %in% ext$tile,]
  238. }
  239. write.csv(x=out,file=paste(opts$outDirPath,todo,".",outName,".csv",sep=""),row.names = FALSE)
  240. }
  241. }
  242. return(invisible(NULL))
  243. }