getSds.R 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #' List SDS Layers in an .HDF File
  2. #'
  3. #' @description
  4. #' This function lists the names of all scientific datasets (SDS) contained in a
  5. #' specified MODIS grid HDF file.
  6. #'
  7. #' @param HdfName \code{character}. (Absolute) filename from which to extract
  8. #' SDS names.
  9. #' @param SDSstring \code{character}, see Value.
  10. #' @param method \code{character}, defaults to \code{"gdal"}. Caution: on
  11. #' Windows, the default 'GDAL' installation doesn't support HDF4 files. Install
  12. #' 'FWTools' or use \code{method = "mrt"} instead.
  13. #'
  14. #' @return
  15. #' A \code{list} or \code{character}. If \code{SDSstring} is provided, the
  16. #' function reports extracted SDS and a formatted SDSsting (e.g., "11101"). If
  17. #' not provided, the SDS names in \code{HdfName} are returned. Consult the MRT
  18. #' manual for details.
  19. #'
  20. #' @author
  21. #' Matteo Mattiuzzi
  22. #'
  23. #' @examples
  24. #' \dontrun{
  25. #' getSds(HdfName="XXX.hdf")
  26. #' getSds(HdfName="/path/XXX.hdf",method="gdal") # require GDAL (FWTools on Windows)
  27. #' getSds(HdfName="/path/XXX.hdf",method="mrt") # require MRTool
  28. #' }
  29. #'
  30. #' @export getSds
  31. #' @name getSds
  32. getSds <- function(HdfName,SDSstring=NULL,method="gdal")
  33. {
  34. method <- toupper(method)
  35. fsep <- .Platform$file.sep
  36. iw <- getOption("warn")
  37. options(warn=-1)
  38. on.exit(options(warn=iw))
  39. opts <- combineOptions()
  40. if (!file.exists(HdfName))
  41. {
  42. cat("Hm, I have to search for the file! Next time provide the full path and I'll be very fast!\n")
  43. HdfName <- list.files(path=opts$localArcPath,pattern=paste(HdfName,"$",sep=""),recursive=TRUE,full.names = TRUE)
  44. }
  45. HdfName <- HdfName[1]
  46. checkTool <- checkTools(tool=method,quiet=TRUE, opts = opts)[[method]][[method]]
  47. if (!checkTool)
  48. {
  49. stop("Method ",method, " does not work. Is ", method," installed properly on your system? Run: 'MODIS:::checkTools()' to check out which metods should work on your system!")
  50. }
  51. if (method=="GDAL")
  52. {
  53. if (.Platform$OS=="unix")
  54. {
  55. sdsRaw <- system(paste("gdalinfo ", HdfName,sep=""),intern=TRUE)
  56. } else if (.Platform$OS=="windows")
  57. {
  58. usar <- gsub(utils::shortPathName(HdfName),pattern="\\\\",replacement="/")
  59. if (is.null(opts$gdalPath))
  60. {
  61. cmd <- paste('gdalinfo ', usar,sep="")
  62. } else
  63. {
  64. cmd <- shQuote(paste0(opts$gdalPath,'gdalinfo.exe ',usar),type="cmd")
  65. }
  66. sdsRaw <- shell(cmd,intern=TRUE)
  67. }
  68. SDSnames <- grep(x=sdsRaw,pattern="SUBDATASET_[0-9]{1,2}_NAME",value=TRUE)
  69. SDSnames <- unlist(lapply(SDSnames,function(x) strsplit(x,"=")[[1]][2]))
  70. SDSnames <- unlist(lapply(SDSnames,function(x) gsub(x,pattern="\\\"",replacement="")))
  71. sds <- unlist(lapply(SDSnames,function(x)
  72. {
  73. x <- strsplit(x,":")[[1]]
  74. x <- x[length(x)]
  75. }
  76. ))
  77. } else if (method=="MRT")
  78. {
  79. if (.Platform$OS=="unix")
  80. {
  81. sdsRaw <- system(paste("sdslist",HdfName,sep=" "),intern=TRUE)
  82. }else if (.Platform$OS=="windows")
  83. {
  84. sdsRaw <- shell(gsub(fsep,"\\\\",paste('sdslist "',HdfName,'"',sep="")),intern=TRUE)
  85. }
  86. sds <- list()
  87. for (i in 1:length(sdsRaw))
  88. {
  89. sds[[i]] <- substr(sdsRaw[i],1,11) == "SDgetinfo: "
  90. }
  91. sds <- sdsRaw[unlist(sds)]
  92. sds <- unlist(lapply(sds,function(x){strsplit(x,", ")[[1]][2]}))
  93. }
  94. if (!is.null(SDSstring))
  95. {
  96. if (inherits(SDSstring,"list"))
  97. {
  98. SDSstring <- paste(SDSstring$SDSstring,collapse="")
  99. } else if (inherits(SDSstring,"numeric"))
  100. {
  101. SDSstring <- paste(SDSstring,collapse="")
  102. }
  103. SDSstring <- gsub(pattern=" ",replacement="",x=SDSstring) # collapse the spaces
  104. if (nchar(SDSstring)!= length(sds))
  105. {
  106. warning("The file has ",length(sds)," layers (SDS), your SDSstring has length ",nchar(SDSstring),"!\nThe string is auto-completed!")
  107. }
  108. msk <- rep(FALSE,length(sds))
  109. for (o in 1:length(sds))
  110. {
  111. msk[o] <- substr(SDSstring,o,o)==1
  112. }
  113. if (method=="GDAL")
  114. {
  115. return(list(SDSnames = sds[msk],SDSstring = paste(as.numeric(msk),collapse=" "),SDS4gdal=SDSnames[msk]))
  116. } else
  117. {
  118. return(list(SDSnames = sds[msk],SDSstring = paste(as.numeric(msk),collapse=" ")))
  119. }
  120. } else
  121. {
  122. if (method=="GDAL")
  123. {
  124. return(list(SDSnames = sds,SDS4gdal=SDSnames))
  125. } else
  126. {
  127. return(list(SDSnames = sds))
  128. }
  129. }
  130. }