LandCover.R 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. LandCover <-
  2. function(Dir = ".", Band)
  3. {
  4. ########## Define land cover classes for each lc band.
  5. LC_CLASS <- list(
  6. Land_Cover_Type_1 = c("Water" = 0, "Evergreen Needleleaf forest" = 1, "Evergreen Broadleaf forest" = 2,
  7. "Deciduous Needleleaf forest" = 3, "Deciduous Broadleaf forest" = 4, "Mixed forest" = 5,
  8. "Closed shrublands" = 6, "Open shrublands" = 7, "Woody savannas" = 8, "Savannas" = 9,
  9. "Grasslands" = 10, "Permanent wetlands" = 11, "Croplands" = 12, "Urban & built-up" = 13,
  10. "Cropland/Natural vegetation mosaic" = 14, "Snow & ice" = 15, "Barren/Sparsely vegetated" = 16,
  11. "Unclassified" = 254, "NoDataFill" = 255),
  12. Land_Cover_Type_2 = c("Water" = 0, "Evergreen Needleleaf forest" = 1, "Evergreen Broadleaf forest" = 2,
  13. "Deciduous Needleleaf forest" = 3, "Deciduous Broadleaf forest" = 4, "Mixed forest" = 5,
  14. "Closed shrublands" = 6, "Open shrublands" = 7, "Woody savannas" = 8, "Savannas" = 9,
  15. "Grasslands" = 10, "Croplands" = 12, "Urban & built-up" = 13, "Barren/Sparsely vegetated" = 16,
  16. "Unclassified" = 254, "NoDataFill" = 255),
  17. Land_Cover_Type_3 = c("Water" = 0, "Grasses/Cereal crops" = 1, "Shrubs" = 2, "Broadleaf crops" = 3, "Savanna" = 4,
  18. "Evergreen Broadleaf forest" = 5, "Deciduous Broadleaf forest" = 6,
  19. "Evergreen Needleleaf forest" = 7, "Deciduous Needleleaf forest" = 8, "Non-vegetated" = 9,
  20. "Urban" = 10, "Unclassified" = 254, "NoDataFill" = 255),
  21. Land_Cover_Type_4 = c("Water" = 0, "Evergreen Needleleaf forest" = 1, "Evergreen Broadleaf forest" = 2,
  22. "Deciduous Needleleaf forest" = 3, "Deciduous Broadleaf forest" = 4,
  23. "Annual Broadleaf vegetation" = 5, "Annual grass vegetation" = 6, "Non-vegetated land" = 7,
  24. "Urban" = 8, "Unclassified" = 254, "NoDataFill" = 255),
  25. Land_Cover_Type_5 = c("Water" = 0, "Evergreen Needleleaf forest" = 1, "Evergreen Broadleaf forest" = 2,
  26. "Deciduous Needleleaf forest" = 3, "Deciduous Broadleaf forest" = 4, "Shrub" = 5, "Grass" = 6,
  27. "Cereal crop" = 7, "Broadleaf crop" = 8, "Urban & built-up" = 9, "Snow & ice" = 10,
  28. "Barren/Sparsely vegetated" = 11, "Unclassified" = 254, "NoDataFill" = 255)
  29. )
  30. NUM_METADATA_COLS <- 10
  31. ##########
  32. if(!file.exists(Dir)) stop("Character string input for Dir argument does not resemble an existing file path.")
  33. file.list <- list.files(path = Dir, pattern = "MCD12Q1.*asc$")
  34. if(length(file.list) == 0) stop("Found no MODIS Land Cover ASCII files in Dir.")
  35. if(!any(GetBands("MCD12Q1") == Band)) stop("LandCover is for land cover data. Band specified is not for this product.")
  36. lc.type.set <- LC_CLASS[[which(names(LC_CLASS) == Band)]]
  37. NoDataFill <- unname(lc.type.set["NoDataFill"])
  38. ValidRange <- unname(lc.type.set)
  39. lc.summary <- list(NA)
  40. for(i in 1:length(file.list)){
  41. cat("Processing file ", i, " of ", length(file.list), "...\n", sep="")
  42. lc.subset <- read.csv(paste(Dir, "/", file.list[i], sep = ""), header = FALSE, as.is = TRUE)
  43. names(lc.subset) <- c("nrow", "ncol", "xll", "yll", "pixelsize", "row.id", "land.product.code",
  44. "MODIS.acq.date", "where", "MODIS.proc.date", 1:(ncol(lc.subset) - NUM_METADATA_COLS))
  45. where.long <- regexpr("Lon", lc.subset$where[1])
  46. where.samp <- regexpr("Samp", lc.subset$where[1])
  47. where.land <- regexpr("Land", lc.subset$row.id)
  48. lat <- as.numeric(substr(lc.subset$where[1], 4, where.long - 1))
  49. long <- as.numeric(substr(lc.subset$where[1], where.long + 3, where.samp - 1))
  50. band.codes <- substr(lc.subset$row.id, where.land, nchar(lc.subset$row.id))
  51. ifelse(any(grepl(Band, lc.subset$row.id)),
  52. which.are.band <- which(band.codes == Band),
  53. stop("Cannot find which rows in LoadDat are band data. Make sure the only ascii files in the directory are
  54. those downloaded from MODISSubsets."))
  55. lc.tiles <- as.matrix(lc.subset[which.are.band,(NUM_METADATA_COLS+1):ncol(lc.subset)],
  56. nrow = length(which.are.band), ncol = length((NUM_METADATA_COLS+1):ncol(lc.subset)))
  57. if(!all(lc.tiles %in% ValidRange)) stop("Some values fall outside the valid range for the data band specified.")
  58. # Screen pixels in lc.tiles: pixels = NoDataFill, or whose corresponding pixel in qc.tiles < QualityThreshold.
  59. lc.tiles <- matrix(ifelse(lc.tiles != NoDataFill, lc.tiles, NA), nrow = length(which.are.band))
  60. # Extract year and day from the metadata and make POSIXlt dates (YYYY-MM-DD), ready for time-series analysis.
  61. year <- as.numeric(substr(lc.subset$MODIS.acq.date, 2, 5))
  62. day <- as.numeric(substr(lc.subset$MODIS.acq.date, 6, 8))
  63. lc.subset$date <- strptime(paste(year, "-", day, sep = ""), "%Y-%j")
  64. # Initialise objects to store landscape summaries
  65. lc.mode.class <- rep(NA, nrow(lc.tiles))
  66. lc.richness <- rep(NA, nrow(lc.tiles))
  67. simp.even <- rep(NA, nrow(lc.tiles))
  68. simp.d <- rep(NA, nrow(lc.tiles))
  69. no.fill <- rep(NA, nrow(lc.tiles))
  70. poor.quality <- rep(NA, nrow(lc.tiles))
  71. for(x in 1:nrow(lc.tiles)){
  72. # Calculate mode - most frequent lc class
  73. lc.freq <- table(lc.tiles[x, ])
  74. lc.freq <- lc.freq / ncol(lc.tiles)
  75. lc.freq <- sum(lc.freq^2)
  76. # Calculate Simpson's D diversity index
  77. simp.d[x] <- 1 / lc.freq
  78. lc.mode <- which.max(table(lc.tiles[x, ]))
  79. lc.mode.class[x] <- names(which(lc.type.set == lc.mode))
  80. # Calculate landscape richness
  81. lc.richness[x] <- length(table(lc.tiles[x, ]))
  82. # Calculate Simpson's measure of evenness
  83. simp.even[x] <- simp.d[x] / lc.richness[x]
  84. no.fill[x] <- paste(round((sum(lc.subset[x,(NUM_METADATA_COLS+1):ncol(lc.subset)] == NoDataFill) / length(lc.tiles[x, ])) * 100, 2),
  85. "% (", sum(lc.subset[x,(NUM_METADATA_COLS+1):ncol(lc.subset)] == NoDataFill), "/", length(lc.tiles[x, ]), ")",
  86. sep = "")
  87. } # End of loop that summaries tiles at each time-step, for the ith ASCII file.
  88. # Compile summaries into a table.
  89. lc.summary[[i]] <- data.frame(lat = lat, long = long, date = lc.subset$date[which(band.codes == Band)],
  90. modis.band = Band, most.common = lc.mode.class, richness = lc.richness,
  91. simpsons.d = simp.d, simpsons.evenness = simp.even, no.data.fill = no.fill)
  92. } # End of loop that reiterates for each ascii file.
  93. # Write output summary file by appending summary data from all files, producing one file of summary output.
  94. lc.summary <- do.call("rbind", lc.summary)
  95. write.table(lc.summary, file = paste(Dir, "/", "MODIS_Land_Cover_Summary ", Sys.Date(), ".csv", sep = ""),
  96. sep = ",", row.names = FALSE)
  97. cat("Done! Check the 'MODIS Land Cover Summary' output file.\n")
  98. }