├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ ├── R-CMD-check.yaml │ └── test-coverage.yaml ├── .gitignore ├── CONDUCT.md ├── DESCRIPTION ├── LICENSE ├── MODISTools-logo.ai ├── MODISTools-logo.png ├── MODISTools.Rproj ├── NAMESPACE ├── NEWS.md ├── R ├── coordinate_conversion.R ├── data.R ├── mt_bands.R ├── mt_batch_subset.R ├── mt_dates.R ├── mt_products.R ├── mt_sites.R ├── mt_subset.R ├── mt_to_terra.R └── zzz.R ├── README-not.md ├── README.Rmd ├── README.md ├── cran-comments.md ├── data ├── arcachon_lai.rda └── arcachon_lc.rda ├── docs ├── 404.html ├── CONDUCT.html ├── LICENSE-text.html ├── articles │ ├── index.html │ ├── modistools-vignette.html │ └── modistools-vignette_files │ │ ├── accessible-code-block-0.0.1 │ │ └── empty-anchor.js │ │ ├── figure-html │ │ ├── unnamed-chunk-10-1.png │ │ ├── unnamed-chunk-11-1.png │ │ ├── unnamed-chunk-12-1.png │ │ ├── unnamed-chunk-13-1.png │ │ ├── unnamed-chunk-14-1.png │ │ ├── unnamed-chunk-5-1.png │ │ ├── unnamed-chunk-6-1.png │ │ ├── unnamed-chunk-7-1.png │ │ ├── unnamed-chunk-8-1.png │ │ └── unnamed-chunk-9-1.png │ │ ├── header-attrs-2.11 │ │ └── header-attrs.js │ │ └── header-attrs-2.8 │ │ └── header-attrs.js ├── authors.html ├── bootstrap-toc.css ├── bootstrap-toc.js ├── docsearch.css ├── docsearch.js ├── index.html ├── jquery.sticky-kit.min.js ├── link.svg ├── news │ └── index.html ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml ├── reference │ ├── Rplot001.png │ ├── arcachon_lai.html │ ├── arcachon_lc.html │ ├── index.html │ ├── ll_to_bb.html │ ├── mt_bands.html │ ├── mt_batch_subset.html │ ├── mt_bbox.html │ ├── mt_dates.html │ ├── mt_products.html │ ├── mt_read.html │ ├── mt_sites.html │ ├── mt_subset.html │ ├── mt_to_raster.html │ ├── mt_to_terra.html │ ├── mt_write.html │ ├── my_sites.csv │ └── sin_to_ll.html └── sitemap.xml ├── inst └── CITATION ├── man ├── arcachon_lai.Rd ├── arcachon_lc.Rd ├── mt_bands.Rd ├── mt_batch_subset.Rd ├── mt_bbox.Rd ├── mt_dates.Rd ├── mt_products.Rd ├── mt_sites.Rd ├── mt_subset.Rd ├── mt_to_terra.Rd └── sin_to_ll.Rd ├── tests ├── testthat.R └── testthat │ ├── test_coordinate_conversions.R │ ├── test_download_functions.R │ └── test_server_errors.R └── vignettes └── modistools-vignette.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^\.travis\.yml$ 2 | ^.*\.Rproj$ 3 | ^\.Rproj\.user$ 4 | ^README\.Rmd$ 5 | ^README\.md$ 6 | ^_config\.yml$ 7 | ^cran-comments\.md$ 8 | ^CONDUCT\.md$ 9 | ^NEWS\.md$ 10 | ^LICENSE$ 11 | ^docs$ 12 | ^\.httr-oauth$ 13 | ^.*-logo\..*$ 14 | ^\.github$ 15 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # For help debugging build failures open an issue on the RStudio community with the 'github-actions' tag. 2 | # https://community.rstudio.com/new-topic?category=Package%20development&tags=github-actions 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - master 8 | pull_request: 9 | branches: 10 | - main 11 | - master 12 | 13 | name: R-CMD-check 14 | 15 | jobs: 16 | R-CMD-check: 17 | runs-on: ${{ matrix.config.os }} 18 | 19 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 20 | 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | config: 25 | - {os: windows-latest, r: 'release'} 26 | - {os: macOS-latest, r: 'release'} 27 | - {os: ubuntu-20.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"} 28 | - {os: ubuntu-20.04, r: 'devel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"} 29 | 30 | env: 31 | R_REMOTES_NO_ERRORS_FROM_WARNINGS: true 32 | RSPM: ${{ matrix.config.rspm }} 33 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 34 | 35 | steps: 36 | - uses: actions/checkout@v2 37 | 38 | - uses: r-lib/actions/setup-r@v1 39 | with: 40 | r-version: ${{ matrix.config.r }} 41 | 42 | - uses: r-lib/actions/setup-pandoc@v1 43 | 44 | - name: Query dependencies 45 | run: | 46 | install.packages('remotes') 47 | saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) 48 | writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") 49 | shell: Rscript {0} 50 | 51 | - name: Restore R package cache 52 | if: runner.os != 'Windows' 53 | uses: actions/cache@v2 54 | with: 55 | path: ${{ env.R_LIBS_USER }} 56 | key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} 57 | restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- 58 | 59 | - name: Install system dependencies 60 | if: runner.os == 'Linux' 61 | run: | 62 | while read -r cmd 63 | do 64 | eval sudo $cmd 65 | done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "20.04"))') 66 | 67 | - name: Install dependencies 68 | run: | 69 | remotes::install_deps(dependencies = TRUE) 70 | remotes::install_cran("rcmdcheck") 71 | shell: Rscript {0} 72 | 73 | - name: Check 74 | env: 75 | _R_CHECK_CRAN_INCOMING_REMOTE_: false 76 | run: | 77 | options(crayon.enabled = TRUE) 78 | rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check") 79 | shell: Rscript {0} 80 | 81 | - name: Upload check results 82 | if: failure() 83 | uses: actions/upload-artifact@main 84 | with: 85 | name: ${{ runner.os }}-r${{ matrix.config.r }}-results 86 | path: check 87 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | - master 6 | pull_request: 7 | branches: 8 | - main 9 | - master 10 | 11 | name: test-coverage 12 | 13 | jobs: 14 | test-coverage: 15 | runs-on: macOS-latest 16 | env: 17 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 18 | steps: 19 | - uses: actions/checkout@v2 20 | 21 | - uses: r-lib/actions/setup-r@v1 22 | 23 | - uses: r-lib/actions/setup-pandoc@v1 24 | 25 | - name: Query dependencies 26 | run: | 27 | install.packages('remotes') 28 | saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) 29 | writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") 30 | shell: Rscript {0} 31 | 32 | - name: Restore R package cache 33 | uses: actions/cache@v2 34 | with: 35 | path: ${{ env.R_LIBS_USER }} 36 | key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} 37 | restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- 38 | 39 | - name: Install dependencies 40 | run: | 41 | install.packages(c("remotes")) 42 | remotes::install_deps(dependencies = TRUE) 43 | remotes::install_cran("covr") 44 | shell: Rscript {0} 45 | 46 | - name: Test coverage 47 | run: covr::codecov() 48 | shell: Rscript {0} 49 | 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | .httr-oauth 6 | -------------------------------------------------------------------------------- /CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, we pledge to respect all people who 4 | contribute through reporting issues, posting feature requests, updating documentation, 5 | submitting pull requests or patches, and other activities. 6 | 7 | We are committed to making participation in this project a harassment-free experience for 8 | everyone, regardless of level of experience, gender, gender identity and expression, 9 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. 10 | 11 | Examples of unacceptable behavior by participants include the use of sexual language or 12 | imagery, derogatory comments or personal attacks, trolling, public or private harassment, 13 | insults, or other unprofessional conduct. 14 | 15 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 16 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 17 | Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed 18 | from the project team. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 21 | opening an issue or contacting one or more of the project maintainers. 22 | 23 | This Code of Conduct is adapted from the Contributor Covenant 24 | (http:contributor-covenant.org), version 1.0.0, available at 25 | http://contributor-covenant.org/version/1/0/0/ 26 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: MODISTools 2 | Title: Interface to the 'MODIS Land Products Subsets' Web Services 3 | Version: 1.1.3 4 | Authors@R: c(person( 5 | family = "Hufkens", 6 | given = "Koen", 7 | email = "koen.hufkens@gmail.com", 8 | role = c("aut", "cre"), 9 | comment = c(ORCID = "0000-0002-5070-8109")), 10 | person(given = "BlueGreen Labs", 11 | role = c("cph", "fnd"))) 12 | Description: Programmatic interface to the Oak Ridge National Laboratories 13 | 'MODIS Land Products Subsets' web services 14 | (). Allows for easy 15 | downloads of 'MODIS' time series directly to your R workspace or 16 | your computer. 17 | URL: https://docs.ropensci.org/MODISTools, https://github.com/ropensci/MODISTools 18 | BugReports: https://github.com/ropensci/MODISTools/issues 19 | Depends: 20 | R (>= 3.4) 21 | Imports: 22 | httr, 23 | utils, 24 | sf, 25 | sp, 26 | terra, 27 | stats, 28 | memoise, 29 | jsonlite 30 | License: AGPL-3 31 | LazyData: true 32 | ByteCompile: true 33 | RoxygenNote: 7.2.1 34 | Suggests: 35 | knitr, 36 | markdown, 37 | covr, 38 | testthat, 39 | ggplot2, 40 | dplyr 41 | VignetteBuilder: knitr 42 | -------------------------------------------------------------------------------- /MODISTools-logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/MODISTools-logo.ai -------------------------------------------------------------------------------- /MODISTools-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/MODISTools-logo.png -------------------------------------------------------------------------------- /MODISTools.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(mt_bands) 4 | export(mt_batch_subset) 5 | export(mt_bbox) 6 | export(mt_dates) 7 | export(mt_products) 8 | export(mt_sites) 9 | export(mt_subset) 10 | export(mt_to_terra) 11 | export(sin_to_ll) 12 | import(sp) 13 | importFrom(memoise,memoise) 14 | importFrom(terra,rast) 15 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | # MODISTools 1.1.3 2 | 3 | * removing {raster} dependencies 4 | 5 | # MODISTools 1.1.2 6 | 7 | * removing parallel processing in batch tool due to timeout issues 8 | * set error = TRUE on vignette to prevent stopping during render 9 | * correct batch downloading, missing argument in apply() 10 | 11 | # MODISTools 1.1.1 12 | 13 | * added raster conversion function `mt_to_raster()` 14 | * force integer values on buffer values 15 | * removed keywords 16 | 17 | # MODISTools 1.1.0 18 | 19 | * ropensci code review 20 | * replaced NULL parameters with missing() 21 | * output a tidy data frame 22 | * include coordinate transform functions to sf objects 23 | * pkgdown documentation generation 24 | 25 | # MODISTools 1.0.0 26 | 27 | * ropensci refactoring 28 | * version increment follows original package 29 | * push to CRAN 30 | 31 | # MODISTools 0.1.0 32 | 33 | * first draft 34 | -------------------------------------------------------------------------------- /R/coordinate_conversion.R: -------------------------------------------------------------------------------- 1 | #' Convert sinusoidal coordinates to lat / lon 2 | #' 3 | #' A full description of the sinusoidal projection is provided on the 4 | #' lpdaac page: 5 | #' https://lpdaac.usgs.gov/dataset_discovery/modis 6 | #' and wikipedia: 7 | #' https://en.wikipedia.org/wiki/Sinusoidal_projection 8 | #' 9 | #' @param x sinusoidal x coordinate (vector) 10 | #' @param y sinusoidal y coordinate (vector) 11 | #' @seealso \code{\link[MODISTools]{mt_bbox}} 12 | #' @export 13 | #' @examples 14 | #' 15 | #' \donttest{ 16 | #' # Download some test data 17 | #' subset <- mt_subset(product = "MOD11A2", 18 | #' lat = 40, 19 | #' lon = -110, 20 | #' band = "LST_Day_1km", 21 | #' start = "2004-01-01", 22 | #' end = "2004-03-31", 23 | #' progress = FALSE) 24 | #' 25 | #' # convert sinusoidal to lat / lon 26 | #' lat_lon <- sin_to_ll(subset$xllcorner, subset$yllcorner) 27 | #' 28 | #' # bind with the original dataframe 29 | #' subset <- cbind(subset, lat_lon) 30 | #' head(subset) 31 | #'} 32 | 33 | sin_to_ll <- function(x, y){ 34 | 35 | # check parameters 36 | if(missing(x) | missing(y)){ 37 | stop("please provide a coordinate pair in sinusoidal projection...") 38 | } 39 | 40 | # convert to sf object 41 | coords <- suppressWarnings( 42 | sf::st_as_sf( 43 | x = data.frame(as.numeric(x), 44 | as.numeric(y), 45 | stringsAsFactors = FALSE), 46 | coords = c("as.numeric.x.", "as.numeric.y."), 47 | crs = "+proj=sinu +a=6371007.181 +b=6371007.181 +units=m +type=crs" 48 | )) 49 | 50 | # reproject coordinates 51 | coords <- sf::st_transform(coords, crs = 4326) 52 | 53 | # unravel the sf dataframe into a normal one 54 | coords <- as.data.frame(do.call("rbind", lapply(coords$geometry, unlist))) 55 | colnames(coords) <- c("longitude_ll", "latitude_ll") 56 | 57 | # return the labelled dataframe 58 | return(coords) 59 | } 60 | 61 | #' Converts lower-left sinusoidal coordinates to lat-lon sf bounding box 62 | #' 63 | #' @param xllcorner lower left x coordinate as provided by 64 | #' \code{\link[MODISTools]{mt_subset}} 65 | #' @param yllcorner lower left y coordinate as provided by 66 | #' \code{\link[MODISTools]{mt_subset}} 67 | #' @param cellsize cell size provided by \code{\link[MODISTools]{mt_subset}} 68 | #' @param nrows cell size provided by \code{\link[MODISTools]{mt_subset}} 69 | #' @param ncols cell size provided by \code{\link[MODISTools]{mt_subset}} 70 | #' @param transform transform the bounding box from sin to lat long coordinates, 71 | #' \code{TRUE} or \code{FALSE} (default = \code{TRUE}) 72 | #' @seealso \code{\link[MODISTools]{sin_to_ll}}, 73 | #' \code{\link[MODISTools]{mt_subset}} 74 | #' @export 75 | #' @examples 76 | #' 77 | #' \donttest{ 78 | #' # Download some test data 79 | #' subset <- mt_subset(product = "MOD11A2", 80 | #' lat = 40, 81 | #' lon = -110, 82 | #' band = "LST_Day_1km", 83 | #' start = "2004-01-01", 84 | #' end = "2004-03-31", 85 | #' progress = FALSE) 86 | #' 87 | #' # convert sinusoidal to lat / lon 88 | #' lat_lon <- sin_to_ll(subset$xllcorner, subset$yllcorner) 89 | #' 90 | #' # bind with the original dataframe 91 | #' subset <- cbind(subset, lat_lon) 92 | #' 93 | #' # convert to bounding box 94 | #' bb <- apply(subset, 1, function(x){ 95 | #' mt_bbox(xllcorner = x['xllcorner'], 96 | #' yllcorner = x['yllcorner'], 97 | #' cellsize = x['cellsize'], 98 | #' nrows = x['nrows'], 99 | #' ncols = x['ncols']) 100 | #' }) 101 | #' 102 | #' head(bb) 103 | #'} 104 | 105 | mt_bbox <- function( 106 | xllcorner, 107 | yllcorner, 108 | cellsize, 109 | nrows, 110 | ncols, 111 | transform = TRUE 112 | ){ 113 | 114 | # check parameters 115 | if(missing(cellsize) | missing(yllcorner) | 116 | missing(xllcorner) | missing(nrows) | 117 | missing(ncols)){ 118 | stop("missing parameter, all parameters are required") 119 | } 120 | 121 | # transform matrix 122 | trans <- c( 123 | 0, 0, 124 | 0, 1, 125 | 1, 1, 126 | 1, 0, 127 | 0, 0 128 | ) 129 | 130 | # create coordinate matrix 131 | m <- c(as.numeric(cellsize) * as.numeric(ncols), 132 | as.numeric(cellsize) * as.numeric(nrows)) * trans + 133 | c(as.numeric(xllcorner), as.numeric(yllcorner)) 134 | m <- matrix(m, 5, 2, byrow = TRUE) 135 | 136 | # convert to a sf polygon, with the proper 137 | # projection etc. 138 | p <- sf::st_linestring(m) 139 | p <- sf::st_cast(p, "POLYGON") 140 | p <- suppressWarnings( 141 | sf::st_sfc(p, crs = "+proj=sinu +a=6371007.181 +b=6371007.181 +units=m +type=crs") 142 | ) 143 | 144 | # a full description of the sinusoidal projection is provided on the 145 | # lpdaac page: 146 | # https://lpdaac.usgs.gov/dataset_discovery/modis 147 | # and wikipedia: 148 | # https://en.wikipedia.org/wiki/Sinusoidal_projection 149 | 150 | # return untransformed (sinusoidal) data upon request 151 | if(!transform){ 152 | return(p) 153 | } 154 | 155 | # transform the polygon to lat-lon 156 | p <- sf::st_transform(p, crs = 4326) 157 | 158 | # return the polygons 159 | return(p) 160 | } 161 | -------------------------------------------------------------------------------- /R/data.R: -------------------------------------------------------------------------------- 1 | #' arcachon_lai 2 | #' 3 | #' MODIS leaf area index (LAI) around the French town of Arcachon 4 | #' derived from the MODIS MOD15A2H product (band Lai_500m). 5 | #' 6 | #' @format A MODISTools tidy data frame 7 | "arcachon_lai" 8 | 9 | #' arcachon_lc 10 | #' 11 | #' MODIS land cover (IGBP) around the French town of Arcachon 12 | #' derived from the MODIS MCD12Q2 product (band LC_Type1). 13 | #' 14 | #' @format A MODISTools tidy data frame 15 | "arcachon_lc" 16 | -------------------------------------------------------------------------------- /R/mt_bands.R: -------------------------------------------------------------------------------- 1 | #' Download all available bands 2 | #' 3 | #' Lists all available bands for a MODIS Land Products Subset product. 4 | #' 5 | #' @param product a valid MODIS product name 6 | #' @return A data frame of all available bands for a MODIS Land 7 | #' Products Subsets products 8 | #' @seealso \code{\link[MODISTools]{mt_products}} 9 | #' \code{\link[MODISTools]{mt_sites}} \code{\link[MODISTools]{mt_dates}} 10 | #' @export 11 | #' @importFrom memoise memoise 12 | #' @examples 13 | #' 14 | #' \donttest{ 15 | #' # list all available MODIS Land Products Subsets products 16 | #' bands <- mt_bands(product = "MCD12Q2") 17 | #' head(bands) 18 | #' 19 | #'} 20 | #' 21 | 22 | mt_bands <- memoise::memoise(function(product){ 23 | 24 | # load all products 25 | products <- MODISTools::mt_products()$product 26 | 27 | # error trap 28 | if (missing(product) | !(product %in% products)){ 29 | stop("please specify a product, or check your product name...") 30 | } 31 | 32 | # define url 33 | url <- paste(mt_server(), product, "bands", sep = "/") 34 | 35 | # try to download the data 36 | bands <- try(jsonlite::fromJSON(url)) 37 | 38 | # trap errors on download, return a general error statement 39 | if (inherits(bands, "try-error")){ 40 | stop("Your requested timed out or the server is unreachable") 41 | } 42 | 43 | # return a data frame with all bands 44 | return(bands$bands) 45 | }) 46 | -------------------------------------------------------------------------------- /R/mt_batch_subset.R: -------------------------------------------------------------------------------- 1 | #' Batch download MODIS Land Products subsets 2 | #' 3 | #' Lists all available dates for a MODIS Land Products Subset product 4 | #' at a particular location. 5 | #' 6 | #' @param df a CSV file or data frame holding locations and their sitenames to 7 | #' batch process with column names site_name, lat, lon holding the respective 8 | #' sitenames, latitude and longitude. When providing a CSV make sure that the 9 | #' data are comma separated. 10 | #' @param product a valid MODIS product name 11 | #' @param band band to download 12 | #' @param start start date 13 | #' @param end end date 14 | #' @param km_lr km left-right to sample 15 | #' @param km_ab km above-below to sample 16 | #' @param out_dir location where to store all data 17 | #' @param internal should the data be returned as an internal data structure 18 | #' \code{TRUE} or \code{FALSE} (default = \code{TRUE}) 19 | #' @return A data frame combining meta-data and actual data values, data from 20 | #' different sites is concatenated into one large dataframe. Subsets can be 21 | #' created by searching on sitename. 22 | #' @seealso \code{\link[MODISTools]{mt_sites}} 23 | #' \code{\link[MODISTools]{mt_dates}} \code{\link[MODISTools]{mt_bands}} 24 | #' \code{\link[MODISTools]{mt_products}} 25 | #' \code{\link[MODISTools]{mt_subset}} 26 | #' @export 27 | #' @examples 28 | #' 29 | #' \dontrun{ 30 | #' # create data frame with a site_name, lat and lon column 31 | #' # holding the respective names of sites and their location 32 | #' df <- data.frame("site_name" = paste("test",1:2)) 33 | #' df$lat <- 40 34 | #' df$lon <- -110 35 | #' 36 | #' print(df) 37 | #' 38 | #' # test batch download 39 | #' subsets <- mt_batch_subset(df = df, 40 | #' product = "MOD11A2", 41 | #' band = "LST_Day_1km", 42 | #' internal = TRUE, 43 | #' start = "2004-01-01", 44 | #' end = "2004-03-31") 45 | #' 46 | #' # the same can be done using a CSV file with 47 | #' # a data structure similar to the dataframe above 48 | #' 49 | #' write.table(df, file.path(tempdir(),"my_sites.csv"), 50 | #' quote = FALSE, 51 | #' row.names = FALSE, 52 | #' col.names = TRUE, 53 | #' sep = ",") 54 | #' 55 | #' # test batch download form CSV 56 | #' subsets <- mt_batch_subset(df = file.path(tempdir(),"my_sites.csv"), 57 | #' product = "MOD11A2", 58 | #' band = "LST_Day_1km", 59 | #' internal = TRUE, 60 | #' start = "2004-01-01", 61 | #' end = "2004-03-31" 62 | #' ) 63 | #' 64 | #' head(subsets) 65 | #'} 66 | 67 | mt_batch_subset <- function( 68 | df, 69 | product, 70 | band, 71 | start = "2000-01-01", 72 | end = format(Sys.time(),"%Y-%m-%d"), 73 | km_lr = 0, 74 | km_ab = 0, 75 | out_dir = tempdir(), 76 | internal = TRUE 77 | ){ 78 | 79 | # error trap 80 | if (missing(df)){ 81 | stop("please specify a batch file...") 82 | } 83 | 84 | # check data frame 85 | if (!is.data.frame(df)){ 86 | if(file.exists(df)){ 87 | df <- utils::read.table(df, 88 | header = TRUE, 89 | sep = ",", 90 | stringsAsFactors = FALSE) 91 | } else { 92 | stop("specified batch file does not exist") 93 | } 94 | } 95 | 96 | # load products 97 | products <- MODISTools::mt_products()$product 98 | 99 | # error trap products 100 | if (missing(product) | !(product %in% products) ){ 101 | stop("please specify a product, or check your product name...") 102 | } 103 | 104 | # load bands for product 105 | bands <- mt_bands(product) 106 | 107 | # error trap band 108 | if (missing(band) | !(band %in% bands$band) ){ 109 | stop("please specify a band, or check your product band combination ...") 110 | } 111 | 112 | # If all tests pass construct the data frame over which we will 113 | # loop to process all the data 114 | df$product <- product 115 | df$band <- band 116 | df$start <- start 117 | df$end <- end 118 | df$km_lr <- km_lr 119 | df$km_ab <- km_ab 120 | df$out_dir <- path.expand(out_dir) 121 | df$internal <- internal 122 | 123 | # convert names tolower case 124 | # trapping naming issues of coordinates 125 | # and sites 126 | names(df) <- tolower(names(df)) 127 | 128 | # paralllel loop (if requested) 129 | output <- apply(df, 1, function(x){ 130 | MODISTools::mt_subset( 131 | site_name = as.character(x['site_name']), 132 | product = as.character(x['product']), 133 | band = as.character(x['band']), 134 | lat = as.numeric(x['lat']), 135 | lon = as.numeric(x['lon']), 136 | km_lr = as.numeric(x['km_lr']), 137 | km_ab = as.numeric(x['km_ab']), 138 | start = as.character(x['start']), 139 | end = as.character(x['end']), 140 | out_dir = x['out_dir'], 141 | internal = x['internal'], 142 | progress = FALSE) 143 | }) 144 | 145 | # return data 146 | if(internal){ 147 | # row bind the nested list output 148 | output <- do.call("rbind", output) 149 | 150 | return(output) 151 | } else { 152 | invisible() 153 | } 154 | } 155 | 156 | -------------------------------------------------------------------------------- /R/mt_dates.R: -------------------------------------------------------------------------------- 1 | #' Download all available dates 2 | #' 3 | #' Lists all available dates for a MODIS Land Products Subset product 4 | #' at a particular location. 5 | #' 6 | #' @param product a valid MODIS product name 7 | #' @param lat latitude in decimal degrees 8 | #' @param lon longitude in decimal degrees 9 | #' @param site_id site id (overides lat / lon) 10 | #' @param network the network for which to generate the site list, 11 | #' when not provided the complete list is provided 12 | #' @return A data frame of all available dates for a MODIS Land 13 | #' Products Subsets products at the given location. 14 | #' @seealso \code{\link[MODISTools]{mt_products}} 15 | #' \code{\link[MODISTools]{mt_sites}} \code{\link[MODISTools]{mt_bands}} 16 | #' @export 17 | #' @examples 18 | #' 19 | #' \donttest{ 20 | #' # list all available MODIS Land Products Subsets products 21 | #' bands <- mt_dates(product = "MOD11A2", lat = 40, lon = -110) 22 | #' head(bands) 23 | #'} 24 | 25 | mt_dates <- function( 26 | product, 27 | lat, 28 | lon, 29 | site_id, 30 | network 31 | ){ 32 | 33 | # load all products 34 | products <- MODISTools::mt_products()$product 35 | 36 | # error trap 37 | if (missing(product) | !(product %in% products) ){ 38 | stop("please specify a product, or check your product name...") 39 | } 40 | 41 | # error trap 42 | if (missing(site_id) & (missing(lat) | missing(lon)) ){ 43 | stop("please specify coordinates...") 44 | } 45 | 46 | # check if site_id is valid 47 | if(!missing(site_id)){ 48 | if(missing(network)){ 49 | 50 | # load all sites 51 | sites <- MODISTools::mt_sites() 52 | 53 | # check if the site id is valid 54 | if (!(site_id %in% sites$siteid)){ 55 | stop("please specify a valid site id...") 56 | } 57 | } else { 58 | 59 | # load all sites 60 | sites <- MODISTools::mt_sites(network = network) 61 | 62 | # check if the site id is valid 63 | if (!(site_id %in% sites$network_siteid)){ 64 | stop("please specify a valid site id...") 65 | } 66 | } 67 | } 68 | 69 | # switch url in case of siteid 70 | if (missing(site_id)){ 71 | url <- paste(mt_server(), 72 | product, 73 | "dates", 74 | sep = "/") 75 | 76 | # construct the query to be served to the server 77 | query <- list("latitude" = lat, 78 | "longitude" = lon) 79 | 80 | } else { 81 | if(missing(network)){ 82 | url <- paste(mt_server(), 83 | product, 84 | site_id, 85 | "dates", 86 | sep = "/") 87 | query <- NULL 88 | } else { 89 | url <- paste(mt_server(), 90 | product, 91 | network, 92 | site_id, 93 | "dates", 94 | sep = "/") 95 | query <- NULL 96 | } 97 | } 98 | 99 | # try to download the data 100 | json_dates <- httr::RETRY(verb = "GET", 101 | url = url, 102 | query = query, 103 | httr::write_memory(), 104 | terminate_on = c(403, 404)) 105 | 106 | # trap errors on download, return a general error statement 107 | # with the most common causes. 108 | if (httr::http_error(json_dates)){ 109 | stop(httr::content(json_dates), call. = FALSE) 110 | } 111 | 112 | # check the content of the json_dates, stop if not json 113 | if (httr::http_type(json_dates) != "application/json") { 114 | stop("API did not return proper json data.", call. = FALSE) 115 | } 116 | 117 | # grab content 118 | dates <- jsonlite::fromJSON(httr::content(json_dates, "text", 119 | encoding = "UTF-8"), 120 | simplifyVector = TRUE)$dates 121 | 122 | # return a data frame with all dates 123 | return(dates) 124 | } 125 | -------------------------------------------------------------------------------- /R/mt_products.R: -------------------------------------------------------------------------------- 1 | #' Download all available products 2 | #' 3 | #' Lists all available MODIS Land Products Subset products. 4 | #' 5 | #' @return A data frame of all available MODIS Land Products Subsets products 6 | #' @seealso \code{\link[MODISTools]{mt_bands}} 7 | #' \code{\link[MODISTools]{mt_sites}} \code{\link[MODISTools]{mt_dates}} 8 | #' @export 9 | #' @importFrom memoise memoise 10 | #' @examples 11 | #' 12 | #' \donttest{ 13 | #' # list all available MODIS Land Products Subsets products 14 | #' products <- mt_products() 15 | #' head(products) 16 | #'} 17 | #' 18 | 19 | mt_products <- memoise::memoise(function(){ 20 | 21 | # define url 22 | url <- paste(mt_server(), "products", sep = "/") 23 | 24 | # try to download the data 25 | products <- try(jsonlite::fromJSON(url)) 26 | 27 | # trap errors on download, return a general error statement 28 | if (inherits(products, "try-error")){ 29 | stop("Your requested timed out or the server is unreachable") 30 | } 31 | 32 | # split out data 33 | products <- products$products 34 | 35 | # convert labels to more sensible names 36 | products$frequency <- gsub("-", " ", products$frequency) 37 | products$frequency <- gsub("Day", "day", products$frequency) 38 | products$frequency <- gsub("Daily", "1 day", products$frequency) 39 | products$frequency <- gsub("Yearly", "1 year", products$frequency) 40 | 41 | # return a data frame with all products and their details 42 | return(products) 43 | }) 44 | -------------------------------------------------------------------------------- /R/mt_sites.R: -------------------------------------------------------------------------------- 1 | #' Download all available fixed sites 2 | #' 3 | #' Lists all available MODIS Land Products Subset pre-processed sites 4 | #' 5 | #' @param network the network for which to generate the site list, 6 | #' when not provided the complete list is provided 7 | #' @return A data frame of all available MODIS Land Products Subsets 8 | #' pre-processed sites 9 | #' @seealso \code{\link[MODISTools]{mt_products}} 10 | #' \code{\link[MODISTools]{mt_bands}} \code{\link[MODISTools]{mt_dates}} 11 | #' @export 12 | #' @importFrom memoise memoise 13 | #' @examples 14 | #' 15 | #' \donttest{ 16 | #' # list all available MODIS Land Products Subsets products 17 | #' sites <- mt_sites() 18 | #' print(head(sites)) 19 | #'} 20 | #' 21 | 22 | mt_sites <- memoise::memoise(function( 23 | network 24 | ){ 25 | 26 | # define server settings 27 | if(missing(network)){ 28 | url <- paste(mt_server(), "sites", sep = "/") 29 | } else{ 30 | url <- paste(mt_server(), network ,"sites", sep = "/") 31 | } 32 | 33 | # try to download the data 34 | sites <- try(jsonlite::fromJSON(url)) 35 | 36 | # trap errors on download, return a general error statement 37 | if (inherits(sites, "try-error")){ 38 | stop("Your requested timed out or the server is unreachable") 39 | } 40 | 41 | # return a data frame with all products and their details 42 | return(sites$sites) 43 | }) 44 | -------------------------------------------------------------------------------- /R/mt_to_terra.R: -------------------------------------------------------------------------------- 1 | #' Convert tidy MODISTools data to terra SpatRaster 2 | #' 3 | #' Convert tidy MODISTools data to a terra SpatRaster for easy 4 | #' spatial processing and plotting. 5 | #' 6 | #' @param df a valid MODISTools data frame with a single band (filter for a 7 | #' particular band using the dplyr \code{filter()} function or base \code{subset()} 8 | #' @param reproject reproject output to lat / long (default = \code{FALSE}) 9 | #' @return A terra SpatRaster populated with the tidy dataframe values 10 | #' @seealso \code{\link[MODISTools]{mt_subset}} 11 | #' \code{\link[MODISTools]{mt_batch_subset}} 12 | #' @export 13 | #' @examples 14 | #' 15 | #' \donttest{ 16 | #' # list all available MODIS Land Products Subsets products 17 | #' # download data 18 | #' LC <- mt_subset(product = "MCD12Q1", 19 | #' lat = 48.383662, 20 | #' lon = 2.610250, 21 | #' band = "LC_Type1", 22 | #' start = "2005-01-01", 23 | #' end = "2005-12-30", 24 | #' km_lr = 2, 25 | #' km_ab = 2, 26 | #' site_name = "testsite", 27 | #' internal = TRUE, 28 | #' progress = FALSE) 29 | #' 30 | #' head(LC) 31 | #' 32 | #' # convert to raster 33 | #' LC_r <- mt_to_terra(df = LC) 34 | #'} 35 | #' @importFrom terra rast 36 | #' @import sp 37 | 38 | mt_to_terra <- function( 39 | df, 40 | reproject = FALSE 41 | ){ 42 | 43 | # trap empty function 44 | if(missing(df)){ 45 | stop("No data provided") 46 | } 47 | 48 | # check if data frame 49 | if(!is.data.frame(df)){ 50 | stop("Data is not a data frame") 51 | } 52 | 53 | # check if MODISTools data frame 54 | # (introduce class?) 55 | if(!any(names(df) %in% "modis_date")){ 56 | stop("Data is not a MODISTools data frame") 57 | } 58 | 59 | # check if there are multiple bands stop 60 | # ask for a subset with a single band 61 | if(length(unique(df$band)) != 1){ 62 | stop("Multiple bands in data frame, filter for a single band first!") 63 | } 64 | 65 | # find unique dates for which data should exist 66 | dates <- unique(df$calendar_date) 67 | 68 | # convert scale to 1 if not available 69 | # should not change the numeric value of a band 70 | df$scale[df$scale == "Not Available"] <- 1 71 | 72 | # loop over all dates, format rasters and return 73 | r <- do.call("c", 74 | lapply(dates, function(date){ 75 | 76 | # stuff values into raster 77 | m <- matrix(as.numeric(df$value[df$calendar_date == date]) * 78 | as.numeric(df$scale[df$calendar_date == date]), 79 | df$nrows[1], 80 | df$ncols[1], 81 | byrow = TRUE 82 | ) 83 | 84 | # convert to raster and return 85 | return(terra::rast(m)) 86 | }) 87 | ) 88 | 89 | # get bounding box 90 | bb <- MODISTools::mt_bbox( 91 | xllcorner = df$xllcorner[1], 92 | yllcorner = df$yllcorner[1], 93 | cellsize = df$cellsize[1], 94 | nrows = df$nrows[1], 95 | ncols = df$ncols[1], 96 | transform = FALSE 97 | ) 98 | 99 | # convert to Spatial object (easier to get extent) 100 | bb <- sf::as_Spatial(bb) 101 | 102 | # assign extent + projection bb to raster 103 | terra::ext(r) <- terra::ext(bb) 104 | terra::crs(r) <- bb@proj4string@projargs 105 | names(r) <- as.character(dates) 106 | 107 | # reproject to lat long when desired 108 | if(reproject){ 109 | r <- terra::project( 110 | r, 111 | crs = 4326 112 | ) 113 | } 114 | 115 | # return the data 116 | return(r) 117 | } 118 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | # load default server names 2 | 3 | mt_server <- function() 'https://modis.ornl.gov/rst/api/v1/' 4 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | ```{r, include = FALSE} 7 | knitr::opts_chunk$set( 8 | collapse = TRUE, 9 | comment = "#>", 10 | fig.path = "README-" 11 | ) 12 | ``` 13 | 14 | # MODISTools 15 | 16 | 17 | [![R build status](https://github.com/ropensci/MODISTools/workflows/R-CMD-check/badge.svg)](https://github.com/ropensci/MODISTools/actions) [![codecov](https://codecov.io/gh/ropensci/MODISTools/branch/master/graph/badge.svg)](https://codecov.io/gh/ropensci/MODISTools) ![Status](https://www.r-pkg.org/badges/version/MODISTools) 18 | [![rOpenSci Peer Review](https://badges.ropensci.org/246_status.svg)](https://github.com/ropensci/software-review/issues/246) 19 | ![Downloads](https://cranlogs.r-pkg.org/badges/grand-total/MODISTools) 20 | 21 | 22 | Programmatic interface to the ['MODIS Land Products Subsets' web services](https://modis.ornl.gov/data/modis_webservice.html). Allows for easy downloads of ['MODIS'](http://modis.gsfc.nasa.gov/) time series directly to your R workspace or your computer. When using the package please cite the manuscript as referenced below. Keep in mind that the original manuscript describes versions prior to release 1.0 of the package. Functions described in this manuscript do not exist in the current package, please consult [the documentation](https://docs.ropensci.org/MODISTools/reference/index.html) to find matching functionality. 23 | 24 | ## Installation 25 | 26 | ### stable release 27 | 28 | To install the current stable release use a CRAN repository: 29 | 30 | ```{r eval = FALSE} 31 | install.packages("MODISTools") 32 | library("MODISTools") 33 | ``` 34 | 35 | ### development release 36 | 37 | To install the development releases of the package run the following commands: 38 | 39 | ```{r eval = FALSE} 40 | if(!require(devtools)){install.package("devtools")} 41 | devtools::install_github("khufkens/MODISTools") 42 | library("MODISTools") 43 | ``` 44 | 45 | Vignettes are not rendered by default, if you want to include additional documentation please use: 46 | 47 | ```{r eval = FALSE} 48 | if(!require(devtools)){install.package("devtools")} 49 | devtools::install_github("khufkens/MODISTools", build_vignettes = TRUE) 50 | library("MODISTools") 51 | ``` 52 | 53 | ## Use 54 | 55 | ### Downloading MODIS time series 56 | 57 | To extract a time series of modis data for a given location and its direct environment use the mt_subset() function. 58 | 59 |
detailed parameter description (click to expand) 60 |

61 | 62 | Parameter | Description 63 | ------------- | ------------------------------ 64 | product | a MODIS product 65 | band | a MODIS product band (if NULL all bands are downloaded) 66 | lat | latitude of the site 67 | lon | longitude of the site 68 | start | start year of the time series (data start in 1980) 69 | end | end year of the time series (current year - 2 years, use force = TRUE to override) 70 | internal | logical, TRUE or FALSE, if true data is imported into R workspace otherwise it is downloaded into the current working directory 71 | out_dir | path where to store the data when not used internally, defaults to tempdir() 72 | km_lr | force "out of temporal range" downloads (integer) 73 | km_ab | suppress the verbose output (integer) 74 | site_name | a site identifier 75 | site_id | a site_id for predefined locations (not required) 76 | progress | logical, TRUE or FALSE (show download progress) 77 | 78 |

79 |
80 | 81 | ```{r eval = TRUE} 82 | # load the library 83 | library(MODISTools) 84 | 85 | # download data 86 | subset <- mt_subset(product = "MOD11A2", 87 | lat = 40, 88 | lon = -110, 89 | band = "LST_Day_1km", 90 | start = "2004-01-01", 91 | end = "2004-02-01", 92 | km_lr = 1, 93 | km_ab = 1, 94 | site_name = "testsite", 95 | internal = TRUE, 96 | progress = FALSE) 97 | print(str(subset)) 98 | ``` 99 | 100 | The output format is a *tidy* data frame, as shown above. When witten to a csv with the parameter `internal = FALSE` this will result in a flat file on disk. 101 | 102 | Note that when a a region is defined using km_lr and km_ab multiple pixels might be returned. These are indexed using the `pixel` column in the data frame containing the time series data. The remote sensing values are listed in the `value` column. When no band is specified all bands of a given product are returned, be mindful of the fact that different bands might require different multipliers to represent their true values. To list all available products, bands for particular products and temporal coverage see function descriptions below. 103 | 104 | ### Batch downloading MODIS time series 105 | 106 | When a large selection of locations is needed you might benefit from using the batch download function `mt_batch_subset()`, which provides a wrapper around the `mt_subset()` function in order to speed up large download batches. This function has a similar syntax to `mt_subset()` but requires a data frame defining site names (site_name) and locations (lat / lon) (or a comma delimited file with the same structure) to specify a list of download locations. 107 | 108 | Below an example is provided on how to batch download data for a data frame of given site names and locations (lat / lon). 109 | 110 | ```{r eval = TRUE} 111 | # create data frame with a site_name, lat and lon column 112 | # holding the respective names of sites and their location 113 | df <- data.frame("site_name" = paste("test",1:2)) 114 | df$lat <- 40 115 | df$lon <- -110 116 | 117 | # test batch download 118 | subsets <- mt_batch_subset(df = df, 119 | product = "MOD11A2", 120 | band = "LST_Day_1km", 121 | internal = TRUE, 122 | start = "2004-01-01", 123 | end = "2004-02-01") 124 | 125 | print(str(subsets)) 126 | ``` 127 | 128 | ### Listing products 129 | 130 | To list all available products use the mt_products() function. 131 | 132 | ```{r eval = TRUE} 133 | products <- mt_products() 134 | head(products) 135 | ``` 136 | 137 | ### Listing bands 138 | 139 | To list all available bands for a given product use the mt_bands() function. 140 | 141 | ```{r eval = TRUE} 142 | bands <- mt_bands(product = "MOD11A2") 143 | head(bands) 144 | ``` 145 | 146 | ### listing dates 147 | 148 | To list all available dates (temporal coverage) for a given product and location use the mt_dates() function. 149 | 150 | ```{r eval = TRUE} 151 | dates <- mt_dates(product = "MOD11A2", lat = 42, lon = -110) 152 | head(dates) 153 | ``` 154 | 155 | ## References 156 | 157 | Hufkens (2022). The MODISTools package: an interface to the MODIS Land Products Subsets Web Services https://github.com/ropensci/MODISTools 158 | 159 | ## Acknowledgements 160 | 161 | Original development was supported by the UK Natural Environment Research Council (NERC; grants NE/K500811/1 and NE/J011193/1), and the Hans Rausing Scholarship. Refactoring was supported through the Belgian Science Policy office COBECORE project (BELSPO; grant BR/175/A3/COBECORE). Logo design elements are taken from the FontAwesome library according to [these terms](https://fontawesome.com/license), where the globe element was inverted and intersected. Continued support for MODISTools is provided by [BlueGreen Labs](https://bluegreenlabs.org). 162 | 163 | 164 | 165 | [![ropensci_footer](https://ropensci.org/public_images/ropensci_footer.png)](https://ropensci.org) 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # MODISTools 5 | 6 | 7 | 8 | [![rOpenSci 9 | Peer 10 | Review](https://badges.ropensci.org/246_status.svg)](https://github.com/ropensci/software-review/issues/246) 11 | 12 | 13 | This package has moved to https://github.com/bluegreen-labs/MODISTools/ 14 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | I have read and agree to the the CRAN policies at 2 | http://cran.r-project.org/web/packages/policies.html 3 | 4 | ## test environments, local, CI and r-hub 5 | 6 | - Ubuntu 20.04 install on R 4.1.3 7 | - Ubuntu 20.04 on github actions (devel / release) 8 | - Checks for macOS and Windows on github actions 9 | - codecove.io code coverage at ~89% 10 | 11 | ## local / Travis CI R CMD check results 12 | 13 | 0 errors | 0 warnings | 0 notes 14 | -------------------------------------------------------------------------------- /data/arcachon_lai.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/data/arcachon_lai.rda -------------------------------------------------------------------------------- /data/arcachon_lc.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/data/arcachon_lc.rda -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Page not found (404) • MODISTools 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 22 | 23 |
24 |
73 | 74 | 75 | 76 | 77 |
78 |
79 | 82 | 83 | Content not found. Please use links in the navbar. 84 | 85 |
86 | 87 | 91 | 92 |
93 | 94 | 95 | 96 |
100 | 101 |
102 |

103 |

Site built with pkgdown 2.0.6.

104 |
105 | 106 |
107 |
108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/CONDUCT.html: -------------------------------------------------------------------------------- 1 | 2 | Contributor Code of Conduct • MODISTools 6 | 7 | 8 |
9 |
50 | 51 | 52 | 53 |
54 |
55 | 58 | 59 |
60 | 61 |

As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.

62 |

We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.

63 |

Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.

64 |

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.

65 |

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.

66 |

This Code of Conduct is adapted from the Contributor Covenant (http:contributor-covenant.org), version 1.0.0, available at http://contributor-covenant.org/version/1/0/0/

67 |
68 | 69 |
70 | 71 | 74 | 75 |
76 | 77 | 78 | 79 |
82 | 83 |
84 |

Site built with pkgdown 2.0.6.

85 |
86 | 87 |
88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /docs/articles/index.html: -------------------------------------------------------------------------------- 1 | 2 | Articles • MODISTools 6 | 7 | 8 |
9 |
50 | 51 | 52 | 53 |
54 |
55 | 58 | 59 |
60 |

All vignettes

61 |

62 | 63 |
MODISTools
64 |
65 |
66 |
67 |
68 | 69 | 70 |
73 | 74 |
75 |

Site built with pkgdown 2.0.6.

76 |
77 | 78 |
79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /docs/articles/modistools-vignette_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-12-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-12-1.png -------------------------------------------------------------------------------- /docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-13-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-13-1.png -------------------------------------------------------------------------------- /docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-14-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-14-1.png -------------------------------------------------------------------------------- /docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/docs/articles/modistools-vignette_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /docs/articles/modistools-vignette_files/header-attrs-2.11/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/modistools-vignette_files/header-attrs-2.8/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | Authors and Citation • MODISTools 6 | 7 | 8 |
9 |
50 | 51 | 52 | 53 |
54 |
55 |
56 | 59 | 60 | 61 |
  • 62 |

    Koen Hufkens. Author, maintainer. 63 |

    64 |
  • 65 |
  • 66 |

    BlueGreen Labs. Copyright holder, funder. 67 |

    68 |
  • 69 |
70 |
71 |
72 |

Citation

73 | Source: inst/CITATION 74 |
75 |
76 | 77 | 78 |

Hufkens (2022). The MODISTools package: an interface to the MODIS Land Products Subsets Web Services https://github.com/ropensci/MODISTools

79 |
@Misc{,
 80 |   title = {The MODISTools package: an interface to the MODIS Land Products Subsets Web Services},
 81 |   author = {Koen Hufkens},
 82 |   year = {2022},
 83 |   url = {https://github.com/ropensci/MODISTools},
 84 | }
85 | 86 |
87 | 88 |
89 | 90 | 91 | 92 |
95 | 96 |
97 |

Site built with pkgdown 2.0.6.

98 |
99 | 100 |
101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | 6 | /* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ 7 | 8 | /* All levels of nav */ 9 | nav[data-toggle='toc'] .nav > li > a { 10 | display: block; 11 | padding: 4px 20px; 12 | font-size: 13px; 13 | font-weight: 500; 14 | color: #767676; 15 | } 16 | nav[data-toggle='toc'] .nav > li > a:hover, 17 | nav[data-toggle='toc'] .nav > li > a:focus { 18 | padding-left: 19px; 19 | color: #563d7c; 20 | text-decoration: none; 21 | background-color: transparent; 22 | border-left: 1px solid #563d7c; 23 | } 24 | nav[data-toggle='toc'] .nav > .active > a, 25 | nav[data-toggle='toc'] .nav > .active:hover > a, 26 | nav[data-toggle='toc'] .nav > .active:focus > a { 27 | padding-left: 18px; 28 | font-weight: bold; 29 | color: #563d7c; 30 | background-color: transparent; 31 | border-left: 2px solid #563d7c; 32 | } 33 | 34 | /* Nav: second level (shown on .active) */ 35 | nav[data-toggle='toc'] .nav .nav { 36 | display: none; /* Hide by default, but at >768px, show it */ 37 | padding-bottom: 10px; 38 | } 39 | nav[data-toggle='toc'] .nav .nav > li > a { 40 | padding-top: 1px; 41 | padding-bottom: 1px; 42 | padding-left: 30px; 43 | font-size: 12px; 44 | font-weight: normal; 45 | } 46 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 47 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 48 | padding-left: 29px; 49 | } 50 | nav[data-toggle='toc'] .nav .nav > .active > a, 51 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 52 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 53 | padding-left: 28px; 54 | font-weight: 500; 55 | } 56 | 57 | /* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ 58 | nav[data-toggle='toc'] .nav > .active > ul { 59 | display: block; 60 | } 61 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | (function() { 6 | 'use strict'; 7 | 8 | window.Toc = { 9 | helpers: { 10 | // return all matching elements in the set, or their descendants 11 | findOrFilter: function($el, selector) { 12 | // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ 13 | // http://stackoverflow.com/a/12731439/358804 14 | var $descendants = $el.find(selector); 15 | return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); 16 | }, 17 | 18 | generateUniqueIdBase: function(el) { 19 | var text = $(el).text(); 20 | var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); 21 | return anchor || el.tagName.toLowerCase(); 22 | }, 23 | 24 | generateUniqueId: function(el) { 25 | var anchorBase = this.generateUniqueIdBase(el); 26 | for (var i = 0; ; i++) { 27 | var anchor = anchorBase; 28 | if (i > 0) { 29 | // add suffix 30 | anchor += '-' + i; 31 | } 32 | // check if ID already exists 33 | if (!document.getElementById(anchor)) { 34 | return anchor; 35 | } 36 | } 37 | }, 38 | 39 | generateAnchor: function(el) { 40 | if (el.id) { 41 | return el.id; 42 | } else { 43 | var anchor = this.generateUniqueId(el); 44 | el.id = anchor; 45 | return anchor; 46 | } 47 | }, 48 | 49 | createNavList: function() { 50 | return $(''); 51 | }, 52 | 53 | createChildNavList: function($parent) { 54 | var $childList = this.createNavList(); 55 | $parent.append($childList); 56 | return $childList; 57 | }, 58 | 59 | generateNavEl: function(anchor, text) { 60 | var $a = $(''); 61 | $a.attr('href', '#' + anchor); 62 | $a.text(text); 63 | var $li = $('
  • '); 64 | $li.append($a); 65 | return $li; 66 | }, 67 | 68 | generateNavItem: function(headingEl) { 69 | var anchor = this.generateAnchor(headingEl); 70 | var $heading = $(headingEl); 71 | var text = $heading.data('toc-text') || $heading.text(); 72 | return this.generateNavEl(anchor, text); 73 | }, 74 | 75 | // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). 76 | getTopLevel: function($scope) { 77 | for (var i = 1; i <= 6; i++) { 78 | var $headings = this.findOrFilter($scope, 'h' + i); 79 | if ($headings.length > 1) { 80 | return i; 81 | } 82 | } 83 | 84 | return 1; 85 | }, 86 | 87 | // returns the elements for the top level, and the next below it 88 | getHeadings: function($scope, topLevel) { 89 | var topSelector = 'h' + topLevel; 90 | 91 | var secondaryLevel = topLevel + 1; 92 | var secondarySelector = 'h' + secondaryLevel; 93 | 94 | return this.findOrFilter($scope, topSelector + ',' + secondarySelector); 95 | }, 96 | 97 | getNavLevel: function(el) { 98 | return parseInt(el.tagName.charAt(1), 10); 99 | }, 100 | 101 | populateNav: function($topContext, topLevel, $headings) { 102 | var $context = $topContext; 103 | var $prevNav; 104 | 105 | var helpers = this; 106 | $headings.each(function(i, el) { 107 | var $newNav = helpers.generateNavItem(el); 108 | var navLevel = helpers.getNavLevel(el); 109 | 110 | // determine the proper $context 111 | if (navLevel === topLevel) { 112 | // use top level 113 | $context = $topContext; 114 | } else if ($prevNav && $context === $topContext) { 115 | // create a new level of the tree and switch to it 116 | $context = helpers.createChildNavList($prevNav); 117 | } // else use the current $context 118 | 119 | $context.append($newNav); 120 | 121 | $prevNav = $newNav; 122 | }); 123 | }, 124 | 125 | parseOps: function(arg) { 126 | var opts; 127 | if (arg.jquery) { 128 | opts = { 129 | $nav: arg 130 | }; 131 | } else { 132 | opts = arg; 133 | } 134 | opts.$scope = opts.$scope || $(document.body); 135 | return opts; 136 | } 137 | }, 138 | 139 | // accepts a jQuery object, or an options object 140 | init: function(opts) { 141 | opts = this.helpers.parseOps(opts); 142 | 143 | // ensure that the data attribute is in place for styling 144 | opts.$nav.attr('data-toggle', 'toc'); 145 | 146 | var $topContext = this.helpers.createChildNavList(opts.$nav); 147 | var topLevel = this.helpers.getTopLevel(opts.$scope); 148 | var $headings = this.helpers.getHeadings(opts.$scope, topLevel); 149 | this.helpers.populateNav($topContext, topLevel, $headings); 150 | } 151 | }; 152 | 153 | $(function() { 154 | $('nav[data-toggle="toc"]').each(function(i, el) { 155 | var $nav = $(el); 156 | Toc.init($nav); 157 | }); 158 | }); 159 | })(); 160 | -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /docs/jquery.sticky-kit.min.js: -------------------------------------------------------------------------------- 1 | /* Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | */ 2 | /* 3 | Source: https://github.com/leafo/sticky-kit 4 | License: MIT 5 | */ 6 | (function(){var b,f;b=this.jQuery||window.jQuery;f=b(window);b.fn.stick_in_parent=function(d){var A,w,J,n,B,K,p,q,k,E,t;null==d&&(d={});t=d.sticky_class;B=d.inner_scrolling;E=d.recalc_every;k=d.parent;q=d.offset_top;p=d.spacer;w=d.bottoming;null==q&&(q=0);null==k&&(k=void 0);null==B&&(B=!0);null==t&&(t="is_stuck");A=b(document);null==w&&(w=!0);J=function(a,d,n,C,F,u,r,G){var v,H,m,D,I,c,g,x,y,z,h,l;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);I=A.height();g=a.parent();null!=k&&(g=g.closest(k)); 7 | if(!g.length)throw"failed to find stick parent";v=m=!1;(h=null!=p?p&&a.closest(p):b("
    "))&&h.css("position",a.css("position"));x=function(){var c,f,e;if(!G&&(I=A.height(),c=parseInt(g.css("border-top-width"),10),f=parseInt(g.css("padding-top"),10),d=parseInt(g.css("padding-bottom"),10),n=g.offset().top+c+f,C=g.height(),m&&(v=m=!1,null==p&&(a.insertAfter(h),h.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(t),e=!0),F=a.offset().top-(parseInt(a.css("margin-top"),10)||0)-q, 8 | u=a.outerHeight(!0),r=a.css("float"),h&&h.css({width:a.outerWidth(!0),height:u,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),e))return l()};x();if(u!==C)return D=void 0,c=q,z=E,l=function(){var b,l,e,k;if(!G&&(e=!1,null!=z&&(--z,0>=z&&(z=E,x(),e=!0)),e||A.height()===I||x(),e=f.scrollTop(),null!=D&&(l=e-D),D=e,m?(w&&(k=e+u+c>C+n,v&&!k&&(v=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),eb&&!v&&(c-=l,c=Math.max(b-u,c),c=Math.min(q,c),m&&a.css({top:c+"px"})))):e>F&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(t),null==p&&(a.after(h),"left"!==r&&"right"!==r||h.append(a)),a.trigger("sticky_kit:stick")),m&&w&&(null==k&&(k=e+u+c>C+n),!v&&k)))return v=!0,"static"===g.css("position")&&g.css({position:"relative"}), 10 | a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")},y=function(){x();return l()},H=function(){G=!0;f.off("touchmove",l);f.off("scroll",l);f.off("resize",y);b(document.body).off("sticky_kit:recalc",y);a.off("sticky_kit:detach",H);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});g.position("position","");if(m)return null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),h.remove()),a.removeClass(t)},f.on("touchmove",l),f.on("scroll",l),f.on("resize", 11 | y),b(document.body).on("sticky_kit:recalc",y),a.on("sticky_kit:detach",H),setTimeout(l,0)}};n=0;for(K=this.length;n 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/news/index.html: -------------------------------------------------------------------------------- 1 | 2 | Changelog • MODISTools 6 | 7 | 8 |
    9 |
    50 | 51 | 52 | 53 |
    54 |
    55 | 59 | 60 |
    61 | 62 |
    • removing {raster} dependencies
    • 63 |
    64 |
    65 | 66 |
    • removing parallel processing in batch tool due to timeout issues
    • 67 |
    • set error = TRUE on vignette to prevent stopping during render
    • 68 |
    • correct batch downloading, missing argument in apply()
    • 69 |
    70 |
    71 | 72 |
    • added raster conversion function mt_to_raster() 73 |
    • 74 |
    • force integer values on buffer values
    • 75 |
    • removed keywords
    • 76 |
    77 |
    78 | 79 |
    • ropensci code review
    • 80 |
    • replaced NULL parameters with missing()
    • 81 |
    • output a tidy data frame
    • 82 |
    • include coordinate transform functions to sf objects
    • 83 |
    • pkgdown documentation generation
    • 84 |
    85 |
    86 | 87 |
    • ropensci refactoring
    • 88 |
    • version increment follows original package
    • 89 |
    • push to CRAN
    • 90 |
    91 |
    92 | 93 |
    • first draft
    • 94 |
    95 |
    96 | 97 | 100 | 101 |
    102 | 103 | 104 |
    107 | 108 |
    109 |

    Site built with pkgdown 2.0.6.

    110 |
    111 | 112 |
    113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /docs/pkgdown.css: -------------------------------------------------------------------------------- 1 | /* Sticky footer */ 2 | 3 | /** 4 | * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ 5 | * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css 6 | * 7 | * .Site -> body > .container 8 | * .Site-content -> body > .container .row 9 | * .footer -> footer 10 | * 11 | * Key idea seems to be to ensure that .container and __all its parents__ 12 | * have height set to 100% 13 | * 14 | */ 15 | 16 | html, body { 17 | height: 100%; 18 | } 19 | 20 | body { 21 | position: relative; 22 | } 23 | 24 | body > .container { 25 | display: flex; 26 | height: 100%; 27 | flex-direction: column; 28 | } 29 | 30 | body > .container .row { 31 | flex: 1 0 auto; 32 | } 33 | 34 | footer { 35 | margin-top: 45px; 36 | padding: 35px 0 36px; 37 | border-top: 1px solid #e5e5e5; 38 | color: #666; 39 | display: flex; 40 | flex-shrink: 0; 41 | } 42 | footer p { 43 | margin-bottom: 0; 44 | } 45 | footer div { 46 | flex: 1; 47 | } 48 | footer .pkgdown { 49 | text-align: right; 50 | } 51 | footer p { 52 | margin-bottom: 0; 53 | } 54 | 55 | img.icon { 56 | float: right; 57 | } 58 | 59 | /* Ensure in-page images don't run outside their container */ 60 | .contents img { 61 | max-width: 100%; 62 | height: auto; 63 | } 64 | 65 | /* Fix bug in bootstrap (only seen in firefox) */ 66 | summary { 67 | display: list-item; 68 | } 69 | 70 | /* Typographic tweaking ---------------------------------*/ 71 | 72 | .contents .page-header { 73 | margin-top: calc(-60px + 1em); 74 | } 75 | 76 | dd { 77 | margin-left: 3em; 78 | } 79 | 80 | /* Section anchors ---------------------------------*/ 81 | 82 | a.anchor { 83 | display: none; 84 | margin-left: 5px; 85 | width: 20px; 86 | height: 20px; 87 | 88 | background-image: url(./link.svg); 89 | background-repeat: no-repeat; 90 | background-size: 20px 20px; 91 | background-position: center center; 92 | } 93 | 94 | h1:hover .anchor, 95 | h2:hover .anchor, 96 | h3:hover .anchor, 97 | h4:hover .anchor, 98 | h5:hover .anchor, 99 | h6:hover .anchor { 100 | display: inline-block; 101 | } 102 | 103 | /* Fixes for fixed navbar --------------------------*/ 104 | 105 | .contents h1, .contents h2, .contents h3, .contents h4 { 106 | padding-top: 60px; 107 | margin-top: -40px; 108 | } 109 | 110 | /* Navbar submenu --------------------------*/ 111 | 112 | .dropdown-submenu { 113 | position: relative; 114 | } 115 | 116 | .dropdown-submenu>.dropdown-menu { 117 | top: 0; 118 | left: 100%; 119 | margin-top: -6px; 120 | margin-left: -1px; 121 | border-radius: 0 6px 6px 6px; 122 | } 123 | 124 | .dropdown-submenu:hover>.dropdown-menu { 125 | display: block; 126 | } 127 | 128 | .dropdown-submenu>a:after { 129 | display: block; 130 | content: " "; 131 | float: right; 132 | width: 0; 133 | height: 0; 134 | border-color: transparent; 135 | border-style: solid; 136 | border-width: 5px 0 5px 5px; 137 | border-left-color: #cccccc; 138 | margin-top: 5px; 139 | margin-right: -10px; 140 | } 141 | 142 | .dropdown-submenu:hover>a:after { 143 | border-left-color: #ffffff; 144 | } 145 | 146 | .dropdown-submenu.pull-left { 147 | float: none; 148 | } 149 | 150 | .dropdown-submenu.pull-left>.dropdown-menu { 151 | left: -100%; 152 | margin-left: 10px; 153 | border-radius: 6px 0 6px 6px; 154 | } 155 | 156 | /* Sidebar --------------------------*/ 157 | 158 | #pkgdown-sidebar { 159 | margin-top: 30px; 160 | position: -webkit-sticky; 161 | position: sticky; 162 | top: 70px; 163 | } 164 | 165 | #pkgdown-sidebar h2 { 166 | font-size: 1.5em; 167 | margin-top: 1em; 168 | } 169 | 170 | #pkgdown-sidebar h2:first-child { 171 | margin-top: 0; 172 | } 173 | 174 | #pkgdown-sidebar .list-unstyled li { 175 | margin-bottom: 0.5em; 176 | } 177 | 178 | /* bootstrap-toc tweaks ------------------------------------------------------*/ 179 | 180 | /* All levels of nav */ 181 | 182 | nav[data-toggle='toc'] .nav > li > a { 183 | padding: 4px 20px 4px 6px; 184 | font-size: 1.5rem; 185 | font-weight: 400; 186 | color: inherit; 187 | } 188 | 189 | nav[data-toggle='toc'] .nav > li > a:hover, 190 | nav[data-toggle='toc'] .nav > li > a:focus { 191 | padding-left: 5px; 192 | color: inherit; 193 | border-left: 1px solid #878787; 194 | } 195 | 196 | nav[data-toggle='toc'] .nav > .active > a, 197 | nav[data-toggle='toc'] .nav > .active:hover > a, 198 | nav[data-toggle='toc'] .nav > .active:focus > a { 199 | padding-left: 5px; 200 | font-size: 1.5rem; 201 | font-weight: 400; 202 | color: inherit; 203 | border-left: 2px solid #878787; 204 | } 205 | 206 | /* Nav: second level (shown on .active) */ 207 | 208 | nav[data-toggle='toc'] .nav .nav { 209 | display: none; /* Hide by default, but at >768px, show it */ 210 | padding-bottom: 10px; 211 | } 212 | 213 | nav[data-toggle='toc'] .nav .nav > li > a { 214 | padding-left: 16px; 215 | font-size: 1.35rem; 216 | } 217 | 218 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 219 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 220 | padding-left: 15px; 221 | } 222 | 223 | nav[data-toggle='toc'] .nav .nav > .active > a, 224 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 225 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 226 | padding-left: 15px; 227 | font-weight: 500; 228 | font-size: 1.35rem; 229 | } 230 | 231 | /* orcid ------------------------------------------------------------------- */ 232 | 233 | .orcid { 234 | font-size: 16px; 235 | color: #A6CE39; 236 | /* margins are required by official ORCID trademark and display guidelines */ 237 | margin-left:4px; 238 | margin-right:4px; 239 | vertical-align: middle; 240 | } 241 | 242 | /* Reference index & topics ----------------------------------------------- */ 243 | 244 | .ref-index th {font-weight: normal;} 245 | 246 | .ref-index td {vertical-align: top; min-width: 100px} 247 | .ref-index .icon {width: 40px;} 248 | .ref-index .alias {width: 40%;} 249 | .ref-index-icons .alias {width: calc(40% - 40px);} 250 | .ref-index .title {width: 60%;} 251 | 252 | .ref-arguments th {text-align: right; padding-right: 10px;} 253 | .ref-arguments th, .ref-arguments td {vertical-align: top; min-width: 100px} 254 | .ref-arguments .name {width: 20%;} 255 | .ref-arguments .desc {width: 80%;} 256 | 257 | /* Nice scrolling for wide elements --------------------------------------- */ 258 | 259 | table { 260 | display: block; 261 | overflow: auto; 262 | } 263 | 264 | /* Syntax highlighting ---------------------------------------------------- */ 265 | 266 | pre, code, pre code { 267 | background-color: #f8f8f8; 268 | color: #333; 269 | } 270 | pre, pre code { 271 | white-space: pre-wrap; 272 | word-break: break-all; 273 | overflow-wrap: break-word; 274 | } 275 | 276 | pre { 277 | border: 1px solid #eee; 278 | } 279 | 280 | pre .img, pre .r-plt { 281 | margin: 5px 0; 282 | } 283 | 284 | pre .img img, pre .r-plt img { 285 | background-color: #fff; 286 | } 287 | 288 | code a, pre a { 289 | color: #375f84; 290 | } 291 | 292 | a.sourceLine:hover { 293 | text-decoration: none; 294 | } 295 | 296 | .fl {color: #1514b5;} 297 | .fu {color: #000000;} /* function */ 298 | .ch,.st {color: #036a07;} /* string */ 299 | .kw {color: #264D66;} /* keyword */ 300 | .co {color: #888888;} /* comment */ 301 | 302 | .error {font-weight: bolder;} 303 | .warning {font-weight: bolder;} 304 | 305 | /* Clipboard --------------------------*/ 306 | 307 | .hasCopyButton { 308 | position: relative; 309 | } 310 | 311 | .btn-copy-ex { 312 | position: absolute; 313 | right: 0; 314 | top: 0; 315 | visibility: hidden; 316 | } 317 | 318 | .hasCopyButton:hover button.btn-copy-ex { 319 | visibility: visible; 320 | } 321 | 322 | /* headroom.js ------------------------ */ 323 | 324 | .headroom { 325 | will-change: transform; 326 | transition: transform 200ms linear; 327 | } 328 | .headroom--pinned { 329 | transform: translateY(0%); 330 | } 331 | .headroom--unpinned { 332 | transform: translateY(-100%); 333 | } 334 | 335 | /* mark.js ----------------------------*/ 336 | 337 | mark { 338 | background-color: rgba(255, 255, 51, 0.5); 339 | border-bottom: 2px solid rgba(255, 153, 51, 0.3); 340 | padding: 1px; 341 | } 342 | 343 | /* vertical spacing after htmlwidgets */ 344 | .html-widget { 345 | margin-bottom: 10px; 346 | } 347 | 348 | /* fontawesome ------------------------ */ 349 | 350 | .fab { 351 | font-family: "Font Awesome 5 Brands" !important; 352 | } 353 | 354 | /* don't display links in code chunks when printing */ 355 | /* source: https://stackoverflow.com/a/10781533 */ 356 | @media print { 357 | code a:link:after, code a:visited:after { 358 | content: ""; 359 | } 360 | } 361 | 362 | /* Section anchors --------------------------------- 363 | Added in pandoc 2.11: https://github.com/jgm/pandoc-templates/commit/9904bf71 364 | */ 365 | 366 | div.csl-bib-body { } 367 | div.csl-entry { 368 | clear: both; 369 | } 370 | .hanging-indent div.csl-entry { 371 | margin-left:2em; 372 | text-indent:-2em; 373 | } 374 | div.csl-left-margin { 375 | min-width:2em; 376 | float:left; 377 | } 378 | div.csl-right-inline { 379 | margin-left:2em; 380 | padding-left:1em; 381 | } 382 | div.csl-indent { 383 | margin-left: 2em; 384 | } 385 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('.navbar-fixed-top').headroom(); 6 | 7 | $('body').css('padding-top', $('.navbar').height() + 10); 8 | $(window).resize(function(){ 9 | $('body').css('padding-top', $('.navbar').height() + 10); 10 | }); 11 | 12 | $('[data-toggle="tooltip"]').tooltip(); 13 | 14 | var cur_path = paths(location.pathname); 15 | var links = $("#navbar ul li a"); 16 | var max_length = -1; 17 | var pos = -1; 18 | for (var i = 0; i < links.length; i++) { 19 | if (links[i].getAttribute("href") === "#") 20 | continue; 21 | // Ignore external links 22 | if (links[i].host !== location.host) 23 | continue; 24 | 25 | var nav_path = paths(links[i].pathname); 26 | 27 | var length = prefix_length(nav_path, cur_path); 28 | if (length > max_length) { 29 | max_length = length; 30 | pos = i; 31 | } 32 | } 33 | 34 | // Add class to parent
  • , and enclosing
  • if in dropdown 35 | if (pos >= 0) { 36 | var menu_anchor = $(links[pos]); 37 | menu_anchor.parent().addClass("active"); 38 | menu_anchor.closest("li.dropdown").addClass("active"); 39 | } 40 | }); 41 | 42 | function paths(pathname) { 43 | var pieces = pathname.split("/"); 44 | pieces.shift(); // always starts with / 45 | 46 | var end = pieces[pieces.length - 1]; 47 | if (end === "index.html" || end === "") 48 | pieces.pop(); 49 | return(pieces); 50 | } 51 | 52 | // Returns -1 if not found 53 | function prefix_length(needle, haystack) { 54 | if (needle.length > haystack.length) 55 | return(-1); 56 | 57 | // Special case for length-0 haystack, since for loop won't run 58 | if (haystack.length === 0) { 59 | return(needle.length === 0 ? 0 : -1); 60 | } 61 | 62 | for (var i = 0; i < haystack.length; i++) { 63 | if (needle[i] != haystack[i]) 64 | return(i); 65 | } 66 | 67 | return(haystack.length); 68 | } 69 | 70 | /* Clipboard --------------------------*/ 71 | 72 | function changeTooltipMessage(element, msg) { 73 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 74 | element.setAttribute('data-original-title', msg); 75 | $(element).tooltip('show'); 76 | element.setAttribute('data-original-title', tooltipOriginalTitle); 77 | } 78 | 79 | if(ClipboardJS.isSupported()) { 80 | $(document).ready(function() { 81 | var copyButton = ""; 82 | 83 | $("div.sourceCode").addClass("hasCopyButton"); 84 | 85 | // Insert copy buttons: 86 | $(copyButton).prependTo(".hasCopyButton"); 87 | 88 | // Initialize tooltips: 89 | $('.btn-copy-ex').tooltip({container: 'body'}); 90 | 91 | // Initialize clipboard: 92 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 93 | text: function(trigger) { 94 | return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); 95 | } 96 | }); 97 | 98 | clipboardBtnCopies.on('success', function(e) { 99 | changeTooltipMessage(e.trigger, 'Copied!'); 100 | e.clearSelection(); 101 | }); 102 | 103 | clipboardBtnCopies.on('error', function() { 104 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 105 | }); 106 | }); 107 | } 108 | })(window.jQuery || window.$) 109 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: '2.18' 2 | pkgdown: 2.0.6 3 | pkgdown_sha: ~ 4 | articles: 5 | modistools-vignette: modistools-vignette.html 6 | last_built: 2022-12-19T10:06Z 7 | 8 | -------------------------------------------------------------------------------- /docs/reference/Rplot001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ropensci-archive/MODISTools/be68d97df04f263454cf6f6566265718e158edfa/docs/reference/Rplot001.png -------------------------------------------------------------------------------- /docs/reference/arcachon_lai.html: -------------------------------------------------------------------------------- 1 | 2 | arcachon_lai — arcachon_lai • MODISTools 7 | 8 | 9 |
    10 |
    51 | 52 | 53 | 54 |
    55 |
    56 | 61 | 62 |
    63 |

    MODIS leaf area index (LAI) around the French town of Arcachon 64 | derived from the MODIS MOD15A2H product (band Lai_500m).

    65 |
    66 | 67 |
    68 |
    arcachon_lai
    69 |
    70 | 71 |
    72 |

    Format

    73 |

    A MODISTools tidy data frame

    74 |
    75 | 76 |
    77 | 80 |
    81 | 82 | 83 |
    86 | 87 |
    88 |

    Site built with pkgdown 2.0.6.

    89 |
    90 | 91 |
    92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /docs/reference/arcachon_lc.html: -------------------------------------------------------------------------------- 1 | 2 | arcachon_lc — arcachon_lc • MODISTools 7 | 8 | 9 |
    10 |
    51 | 52 | 53 | 54 |
    55 |
    56 | 61 | 62 |
    63 |

    MODIS land cover (IGBP) around the French town of Arcachon 64 | derived from the MODIS MCD12Q2 product (band LC_Type1).

    65 |
    66 | 67 |
    68 |
    arcachon_lc
    69 |
    70 | 71 |
    72 |

    Format

    73 |

    A MODISTools tidy data frame

    74 |
    75 | 76 |
    77 | 80 |
    81 | 82 | 83 |
    86 | 87 |
    88 |

    Site built with pkgdown 2.0.6.

    89 |
    90 | 91 |
    92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /docs/reference/index.html: -------------------------------------------------------------------------------- 1 | 2 | Function reference • MODISTools 6 | 7 | 8 |
    9 |
    50 | 51 | 52 | 53 |
    54 |
    55 | 58 | 59 | 63 | 66 | 67 | 70 | 71 | 74 | 75 | 78 | 79 | 82 | 83 | 86 | 87 | 90 | 91 | 94 | 95 | 98 | 99 | 102 | 103 | 106 | 107 |
    60 |

    All functions

    61 |

    62 |
    64 |

    arcachon_lai

    65 |

    arcachon_lai

    68 |

    arcachon_lc

    69 |

    arcachon_lc

    72 |

    mt_bands()

    73 |

    Download all available bands

    76 |

    mt_batch_subset()

    77 |

    Batch download MODIS Land Products subsets

    80 |

    mt_bbox()

    81 |

    Converts lower-left sinusoidal coordinates to lat-lon sf bounding box

    84 |

    mt_dates()

    85 |

    Download all available dates

    88 |

    mt_products()

    89 |

    Download all available products

    92 |

    mt_sites()

    93 |

    Download all available fixed sites

    96 |

    mt_subset()

    97 |

    Download MODIS Land Products subsets

    100 |

    mt_to_terra()

    101 |

    Convert tidy MODISTools data to terra SpatRaster

    104 |

    sin_to_ll()

    105 |

    Convert sinusoidal coordinates to lat / lon

    108 | 109 | 112 |
    113 | 114 | 115 |
    118 | 119 |
    120 |

    Site built with pkgdown 2.0.6.

    121 |
    122 | 123 |
    124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /docs/reference/mt_bands.html: -------------------------------------------------------------------------------- 1 | 2 | Download all available bands — mt_bands • MODISTools 6 | 7 | 8 |
    9 |
    50 | 51 | 52 | 53 |
    54 |
    55 | 60 | 61 |
    62 |

    Lists all available bands for a MODIS Land Products Subset product.

    63 |
    64 | 65 |
    66 |
    mt_bands(product)
    67 |
    68 | 69 |
    70 |

    Arguments

    71 |
    product
    72 |

    a valid MODIS product name

    73 | 74 |
    75 |
    76 |

    Value

    77 | 78 | 79 |

    A data frame of all available bands for a MODIS Land 80 | Products Subsets products

    81 |
    82 |
    83 |

    See also

    84 | 86 |
    87 | 88 |
    89 |

    Examples

    90 |
    
     91 | # \donttest{
     92 | # list all available MODIS Land Products Subsets products
     93 | bands <- mt_bands(product = "MCD12Q2")
     94 | head(bands)
     95 | #>                         band    description               units    valid_range
     96 | #> 1      Dormancy.Num_Modes_01 Onset_Dormancy days since 1-1-1970 11138 to 32766
     97 | #> 2      Dormancy.Num_Modes_02 Onset_Dormancy days since 1-1-1970 11138 to 32766
     98 | #> 3 EVI_Amplitude.Num_Modes_01  EVI_Amplitude           NBAR-EVI2     0 to 10000
     99 | #> 4 EVI_Amplitude.Num_Modes_02  EVI_Amplitude           NBAR-EVI2     0 to 10000
    100 | #> 5      EVI_Area.Num_Modes_01       EVI_Area           NBAR-EVI2      0 to 3700
    101 | #> 6      EVI_Area.Num_Modes_02       EVI_Area           NBAR-EVI2      0 to 3700
    102 | #>   fill_value scale_factor
    103 | #> 1      32767          1.0
    104 | #> 2      32767          1.0
    105 | #> 3      32767       0.0001
    106 | #> 4      32767       0.0001
    107 | #> 5      32767          0.1
    108 | #> 6      32767          0.1
    109 | 
    110 | # }
    111 | 
    112 | 
    113 |
    114 |
    115 | 118 |
    119 | 120 | 121 |
    124 | 125 |
    126 |

    Site built with pkgdown 2.0.6.

    127 |
    128 | 129 |
    130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/reference/mt_dates.html: -------------------------------------------------------------------------------- 1 | 2 | Download all available dates — mt_dates • MODISTools 7 | 8 | 9 |
    10 |
    51 | 52 | 53 | 54 |
    55 |
    56 | 61 | 62 |
    63 |

    Lists all available dates for a MODIS Land Products Subset product 64 | at a particular location.

    65 |
    66 | 67 |
    68 |
    mt_dates(product, lat, lon, site_id, network)
    69 |
    70 | 71 |
    72 |

    Arguments

    73 |
    product
    74 |

    a valid MODIS product name

    75 | 76 | 77 |
    lat
    78 |

    latitude in decimal degrees

    79 | 80 | 81 |
    lon
    82 |

    longitude in decimal degrees

    83 | 84 | 85 |
    site_id
    86 |

    site id (overides lat / lon)

    87 | 88 | 89 |
    network
    90 |

    the network for which to generate the site list, 91 | when not provided the complete list is provided

    92 | 93 |
    94 |
    95 |

    Value

    96 | 97 | 98 |

    A data frame of all available dates for a MODIS Land 99 | Products Subsets products at the given location.

    100 |
    101 |
    102 |

    See also

    103 | 105 |
    106 | 107 |
    108 |

    Examples

    109 |
    
    110 | # \donttest{
    111 | # list all available MODIS Land Products Subsets products
    112 | bands <- mt_dates(product = "MOD11A2", lat = 40, lon = -110)
    113 | head(bands)
    114 | #>   modis_date calendar_date
    115 | #> 1   A2000049    2000-02-18
    116 | #> 2   A2000057    2000-02-26
    117 | #> 3   A2000065    2000-03-05
    118 | #> 4   A2000073    2000-03-13
    119 | #> 5   A2000081    2000-03-21
    120 | #> 6   A2000089    2000-03-29
    121 | # }
    122 | 
    123 |
    124 |
    125 | 128 |
    129 | 130 | 131 |
    134 | 135 |
    136 |

    Site built with pkgdown 2.0.6.

    137 |
    138 | 139 |
    140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/reference/mt_products.html: -------------------------------------------------------------------------------- 1 | 2 | Download all available products — mt_products • MODISTools 6 | 7 | 8 |
    9 |
    50 | 51 | 52 | 53 |
    54 |
    55 | 60 | 61 |
    62 |

    Lists all available MODIS Land Products Subset products.

    63 |
    64 | 65 |
    66 |
    mt_products()
    67 |
    68 | 69 |
    70 |

    Value

    71 | 72 | 73 |

    A data frame of all available MODIS Land Products Subsets products

    74 |
    75 |
    76 |

    See also

    77 | 79 |
    80 | 81 |
    82 |

    Examples

    83 |
    
     84 | # \donttest{
     85 | # list all available MODIS Land Products Subsets products
     86 | products <- mt_products()
     87 | head(products)
     88 | #>        product
     89 | #> 1       Daymet
     90 | #> 2 ECO4ESIPTJPL
     91 | #> 3      ECO4WUE
     92 | #> 4       GEDI03
     93 | #> 5     GEDI04_B
     94 | #> 6      MCD12Q1
     95 | #>                                                                          description
     96 | #> 1 Daily Surface Weather Data (Daymet) on a 1-km Grid for North America, Version 4 R1
     97 | #> 2               ECOSTRESS Evaporative Stress Index PT-JPL (ESI) Daily L4 Global 70 m
     98 | #> 3                          ECOSTRESS Water Use Efficiency (WUE) Daily L4 Global 70 m
     99 | #> 4                GEDI Gridded Land Surface Metrics (LSM) L3 1km EASE-Grid, Version 2
    100 | #> 5       GEDI Gridded Aboveground Biomass Density (AGBD) L4B 1km EASE-Grid, Version 2
    101 | #> 6              MODIS/Terra+Aqua Land Cover Type (LC) Yearly L3 Global 500 m SIN Grid
    102 | #>   frequency resolution_meters
    103 | #> 1     1 day              1000
    104 | #> 2    Varies                70
    105 | #> 3    Varies                70
    106 | #> 4  One time              1000
    107 | #> 5  One time              1000
    108 | #> 6    1 year               500
    109 | # }
    110 | 
    111 | 
    112 |
    113 |
    114 | 117 |
    118 | 119 | 120 |
    123 | 124 |
    125 |

    Site built with pkgdown 2.0.6.

    126 |
    127 | 128 |
    129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /docs/reference/mt_read.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Read a MODISTools data file — mt_read • MODISTools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 44 | 45 | 46 | 47 | 48 | 49 |
    50 |
    51 | 105 | 106 | 107 |
    108 | 109 |
    110 |
    111 | 116 | 117 |
    118 | 119 |

    Read a MODISTools data file into a nested structure of class MODISTools.

    120 | 121 |
    122 | 123 |
    mt_read(filename)
    124 | 125 |

    Arguments

    126 | 127 | 128 | 129 | 130 | 131 | 132 |
    filename

    a MODISTools data file

    133 | 134 |

    Value

    135 | 136 |

    A nested data structure including site meta-data, the full 137 | header and the data as a `data.frame()`.

    138 | 139 | 140 |

    Examples

    141 |
    142 |
    # download data 143 | mt_subset(product = "MOD11A2", 144 | lat = 40, 145 | lon = -110, 146 | band = "LST_Day_1km", 147 | start = "2004-01-01", 148 | end = "2004-03-31", 149 | internal = FALSE) 150 | 151 | # read file 152 | df <- mt_read(paste0(tempdir(), 153 | "/sitename_MOD11A2_2004-01-01_2004-03-31.csv")) 154 | print(df)
    #> $header 155 | #> $header$xllcorner 156 | #> [1] "-9370036.39" 157 | #> 158 | #> $header$yllcorner 159 | #> [1] "4447802.08" 160 | #> 161 | #> $header$cellsize 162 | #> [1] "926.625433055834" 163 | #> 164 | #> $header$nrows 165 | #> [1] 1 166 | #> 167 | #> $header$ncols 168 | #> [1] 1 169 | #> 170 | #> $header$band 171 | #> [1] "LST_Day_1km" 172 | #> 173 | #> $header$units 174 | #> [1] "Kelvin" 175 | #> 176 | #> $header$scale 177 | #> [1] "0.02" 178 | #> 179 | #> $header$latitude 180 | #> [1] 40 181 | #> 182 | #> $header$longitude 183 | #> [1] -110 184 | #> 185 | #> $header$site 186 | #> [1] "sitename" 187 | #> 188 | #> $header$product 189 | #> [1] "MOD11A2" 190 | #> 191 | #> $header$start 192 | #> [1] "2004-01-01" 193 | #> 194 | #> $header$end 195 | #> [1] "2004-03-31" 196 | #> 197 | #> $header$complete 198 | #> [1] TRUE 199 | #> 200 | #> 201 | #> $data 202 | #> modis_date calendar_date band tile proc_date pixel data 203 | #> 1 A2004001 2004-01-01 LST_Day_1km h09v05 2015212185706 1 13098 204 | #> 2 A2004009 2004-01-09 LST_Day_1km h09v05 2015212201022 1 13062 205 | #> 3 A2004017 2004-01-17 LST_Day_1km h09v05 2015212213103 1 13297 206 | #> 4 A2004025 2004-01-25 LST_Day_1km h09v05 2015213005429 1 13323 207 | #> 5 A2004033 2004-02-02 LST_Day_1km h09v05 2015213090158 1 13315 208 | #> 6 A2004041 2004-02-10 LST_Day_1km h09v05 2015213165253 1 13227 209 | #> 7 A2004049 2004-02-18 LST_Day_1km h09v05 2015216182840 1 13739 210 | #> 8 A2004057 2004-02-26 LST_Day_1km h09v05 2015217020635 1 13783 211 | #> 9 A2004065 2004-03-05 LST_Day_1km h09v05 2015217091316 1 14748 212 | #> 10 A2004073 2004-03-13 LST_Day_1km h09v05 2015217164857 1 15105 213 | #> 11 A2004081 2004-03-21 LST_Day_1km h09v05 2015217230030 1 15290 214 | #> 12 A2004089 2004-03-29 LST_Day_1km h09v05 2015218055617 1 15410 215 | #> 216 | #> attr(,"class") 217 | #> [1] "MODISTools"
    218 |
    219 | 230 |
    231 | 232 |
    233 | 236 | 237 |
    238 |

    Site built with pkgdown.

    239 |
    240 | 241 |
    242 |
    243 | 244 | 245 | 246 | 247 | 248 | 249 | -------------------------------------------------------------------------------- /docs/reference/mt_sites.html: -------------------------------------------------------------------------------- 1 | 2 | Download all available fixed sites — mt_sites • MODISTools 6 | 7 | 8 |
    9 |
    50 | 51 | 52 | 53 |
    54 |
    55 | 60 | 61 |
    62 |

    Lists all available MODIS Land Products Subset pre-processed sites

    63 |
    64 | 65 |
    66 |
    mt_sites(network)
    67 |
    68 | 69 |
    70 |

    Arguments

    71 |
    network
    72 |

    the network for which to generate the site list, 73 | when not provided the complete list is provided

    74 | 75 |
    76 |
    77 |

    Value

    78 | 79 | 80 |

    A data frame of all available MODIS Land Products Subsets 81 | pre-processed sites

    82 |
    83 |
    84 |

    See also

    85 | 87 |
    88 | 89 |
    90 |

    Examples

    91 |
    
     92 | # \donttest{
     93 | # list all available MODIS Land Products Subsets products
     94 | sites <- mt_sites()
     95 | print(head(sites))
     96 | #>                   siteid                sitename network latitude longitude
     97 | #> 1  ae_abudhabi_abu_dhabi            AE Abu Dhabi AERONET 24.47611  54.32889
     98 | #> 2     ae_abudhabi_al_ain     AE Abu Dhabi Al Ain AERONET 24.24217  55.70517
     99 | #> 3  ae_abudhabi_al_dhafra  AE Abu Dhabi Al Dhafra AERONET 24.25428  54.54967
    100 | #> 4 ae_abudhabi_al_khaznah AE Abu Dhabi Al Khaznah AERONET 24.15861  55.10056
    101 | #> 5    ae_abudhabi_al_qlaa    AE Abu Dhabi Al Qlaa AERONET 24.13333  53.03333
    102 | #> 6      ae_abudhabi_dhabi            AE Abu Dhabi AERONET 24.48056  54.38278
    103 | #>      state              country
    104 | #> 1 AbuDhabi United Arab Emirates
    105 | #> 2 AbuDhabi United Arab Emirates
    106 | #> 3 AbuDhabi United Arab Emirates
    107 | #> 4 AbuDhabi United Arab Emirates
    108 | #> 5 AbuDhabi United Arab Emirates
    109 | #> 6 AbuDhabi United Arab Emirates
    110 | # }
    111 | 
    112 | 
    113 |
    114 |
    115 | 118 |
    119 | 120 | 121 |
    124 | 125 |
    126 |

    Site built with pkgdown 2.0.6.

    127 |
    128 | 129 |
    130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/reference/mt_write.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Write a MODISTools data structure to file — mt_write • MODISTools 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 44 | 45 | 46 | 47 | 48 | 49 |
    50 |
    51 | 105 | 106 | 107 |
    108 | 109 |
    110 |
    111 | 116 | 117 |
    118 | 119 |

    Writes a nested data structure of class MODISTools to file.

    120 | 121 |
    122 | 123 |
    mt_write(df = NULL, out_dir = tempdir())
    124 | 125 |

    Arguments

    126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 |
    df

    a nested data structure of class MODISTools

    out_dir

    output directory where to store data

    137 | 138 |

    Value

    139 | 140 |

    writes MODISTools data structure to file, retains proper header info.

    141 | 142 | 143 |

    Examples

    144 |
    145 |
    # download data 146 | subset <- mt_subset(product = "MOD11A2", 147 | lat = 40, 148 | lon = -110, 149 | band = "LST_Day_1km", 150 | start = "2004-01-01", 151 | end = "2004-02-01") 152 | # write the above file to disk 153 | mt_write(df = subset, 154 | out_dir = tempdir()) 155 | 156 | # read the data back in 157 | subset_disk <- mt_read(paste0(tempdir(), 158 | "/sitename_MOD11A2_2004-01-01_2004-02-01.csv")) 159 | 160 | # compare original to read from disk 161 | identical(subset, subset_disk)
    #> [1] TRUE
    162 |
    163 | 174 |
    175 | 176 |
    177 | 180 | 181 |
    182 |

    Site built with pkgdown.

    183 |
    184 | 185 |
    186 |
    187 | 188 | 189 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /docs/reference/my_sites.csv: -------------------------------------------------------------------------------- 1 | site_name,lat,lon 2 | test 1,40,-110 3 | test 2,40,-110 4 | -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /404.html 5 | 6 | 7 | /CONDUCT.html 8 | 9 | 10 | /LICENSE-text.html 11 | 12 | 13 | /articles/index.html 14 | 15 | 16 | /articles/modistools-vignette.html 17 | 18 | 19 | /authors.html 20 | 21 | 22 | /index.html 23 | 24 | 25 | /news/index.html 26 | 27 | 28 | /reference/arcachon_lai.html 29 | 30 | 31 | /reference/arcachon_lc.html 32 | 33 | 34 | /reference/index.html 35 | 36 | 37 | /reference/ll_to_bb.html 38 | 39 | 40 | /reference/mt_bands.html 41 | 42 | 43 | /reference/mt_batch_subset.html 44 | 45 | 46 | /reference/mt_bbox.html 47 | 48 | 49 | /reference/mt_dates.html 50 | 51 | 52 | /reference/mt_products.html 53 | 54 | 55 | /reference/mt_read.html 56 | 57 | 58 | /reference/mt_sites.html 59 | 60 | 61 | /reference/mt_subset.html 62 | 63 | 64 | /reference/mt_to_raster.html 65 | 66 | 67 | /reference/mt_to_terra.html 68 | 69 | 70 | /reference/mt_write.html 71 | 72 | 73 | /reference/sin_to_ll.html 74 | 75 | 76 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | citHeader("To cite package 'MODISTools' in publications use:") 2 | 3 | citEntry(entry = "Misc", 4 | title = "The MODISTools package: an interface to the MODIS Land Products Subsets Web Services", 5 | author = personList(as.person("Koen Hufkens")), 6 | year = "2022", 7 | url = "https://github.com/ropensci/MODISTools", 8 | textVersion = 9 | paste("Hufkens (2022).", 10 | "The MODISTools package: an interface to the MODIS Land Products Subsets Web Services", 11 | "https://github.com/ropensci/MODISTools") 12 | ) 13 | -------------------------------------------------------------------------------- /man/arcachon_lai.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{arcachon_lai} 5 | \alias{arcachon_lai} 6 | \title{arcachon_lai} 7 | \format{ 8 | A MODISTools tidy data frame 9 | } 10 | \usage{ 11 | arcachon_lai 12 | } 13 | \description{ 14 | MODIS leaf area index (LAI) around the French town of Arcachon 15 | derived from the MODIS MOD15A2H product (band Lai_500m). 16 | } 17 | \keyword{datasets} 18 | -------------------------------------------------------------------------------- /man/arcachon_lc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{arcachon_lc} 5 | \alias{arcachon_lc} 6 | \title{arcachon_lc} 7 | \format{ 8 | A MODISTools tidy data frame 9 | } 10 | \usage{ 11 | arcachon_lc 12 | } 13 | \description{ 14 | MODIS land cover (IGBP) around the French town of Arcachon 15 | derived from the MODIS MCD12Q2 product (band LC_Type1). 16 | } 17 | \keyword{datasets} 18 | -------------------------------------------------------------------------------- /man/mt_bands.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mt_bands.R 3 | \name{mt_bands} 4 | \alias{mt_bands} 5 | \title{Download all available bands} 6 | \usage{ 7 | mt_bands(product) 8 | } 9 | \arguments{ 10 | \item{product}{a valid MODIS product name} 11 | } 12 | \value{ 13 | A data frame of all available bands for a MODIS Land 14 | Products Subsets products 15 | } 16 | \description{ 17 | Lists all available bands for a MODIS Land Products Subset product. 18 | } 19 | \examples{ 20 | 21 | \donttest{ 22 | # list all available MODIS Land Products Subsets products 23 | bands <- mt_bands(product = "MCD12Q2") 24 | head(bands) 25 | 26 | } 27 | 28 | } 29 | \seealso{ 30 | \code{\link[MODISTools]{mt_products}} 31 | \code{\link[MODISTools]{mt_sites}} \code{\link[MODISTools]{mt_dates}} 32 | } 33 | -------------------------------------------------------------------------------- /man/mt_batch_subset.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mt_batch_subset.R 3 | \name{mt_batch_subset} 4 | \alias{mt_batch_subset} 5 | \title{Batch download MODIS Land Products subsets} 6 | \usage{ 7 | mt_batch_subset( 8 | df, 9 | product, 10 | band, 11 | start = "2000-01-01", 12 | end = format(Sys.time(), "\%Y-\%m-\%d"), 13 | km_lr = 0, 14 | km_ab = 0, 15 | out_dir = tempdir(), 16 | internal = TRUE 17 | ) 18 | } 19 | \arguments{ 20 | \item{df}{a CSV file or data frame holding locations and their sitenames to 21 | batch process with column names site_name, lat, lon holding the respective 22 | sitenames, latitude and longitude. When providing a CSV make sure that the 23 | data are comma separated.} 24 | 25 | \item{product}{a valid MODIS product name} 26 | 27 | \item{band}{band to download} 28 | 29 | \item{start}{start date} 30 | 31 | \item{end}{end date} 32 | 33 | \item{km_lr}{km left-right to sample} 34 | 35 | \item{km_ab}{km above-below to sample} 36 | 37 | \item{out_dir}{location where to store all data} 38 | 39 | \item{internal}{should the data be returned as an internal data structure 40 | \code{TRUE} or \code{FALSE} (default = \code{TRUE})} 41 | } 42 | \value{ 43 | A data frame combining meta-data and actual data values, data from 44 | different sites is concatenated into one large dataframe. Subsets can be 45 | created by searching on sitename. 46 | } 47 | \description{ 48 | Lists all available dates for a MODIS Land Products Subset product 49 | at a particular location. 50 | } 51 | \examples{ 52 | 53 | \dontrun{ 54 | # create data frame with a site_name, lat and lon column 55 | # holding the respective names of sites and their location 56 | df <- data.frame("site_name" = paste("test",1:2)) 57 | df$lat <- 40 58 | df$lon <- -110 59 | 60 | print(df) 61 | 62 | # test batch download 63 | subsets <- mt_batch_subset(df = df, 64 | product = "MOD11A2", 65 | band = "LST_Day_1km", 66 | internal = TRUE, 67 | start = "2004-01-01", 68 | end = "2004-03-31") 69 | 70 | # the same can be done using a CSV file with 71 | # a data structure similar to the dataframe above 72 | 73 | write.table(df, file.path(tempdir(),"my_sites.csv"), 74 | quote = FALSE, 75 | row.names = FALSE, 76 | col.names = TRUE, 77 | sep = ",") 78 | 79 | # test batch download form CSV 80 | subsets <- mt_batch_subset(df = file.path(tempdir(),"my_sites.csv"), 81 | product = "MOD11A2", 82 | band = "LST_Day_1km", 83 | internal = TRUE, 84 | start = "2004-01-01", 85 | end = "2004-03-31" 86 | ) 87 | 88 | head(subsets) 89 | } 90 | } 91 | \seealso{ 92 | \code{\link[MODISTools]{mt_sites}} 93 | \code{\link[MODISTools]{mt_dates}} \code{\link[MODISTools]{mt_bands}} 94 | \code{\link[MODISTools]{mt_products}} 95 | \code{\link[MODISTools]{mt_subset}} 96 | } 97 | -------------------------------------------------------------------------------- /man/mt_bbox.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/coordinate_conversion.R 3 | \name{mt_bbox} 4 | \alias{mt_bbox} 5 | \title{Converts lower-left sinusoidal coordinates to lat-lon sf bounding box} 6 | \usage{ 7 | mt_bbox(xllcorner, yllcorner, cellsize, nrows, ncols, transform = TRUE) 8 | } 9 | \arguments{ 10 | \item{xllcorner}{lower left x coordinate as provided by 11 | \code{\link[MODISTools]{mt_subset}}} 12 | 13 | \item{yllcorner}{lower left y coordinate as provided by 14 | \code{\link[MODISTools]{mt_subset}}} 15 | 16 | \item{cellsize}{cell size provided by \code{\link[MODISTools]{mt_subset}}} 17 | 18 | \item{nrows}{cell size provided by \code{\link[MODISTools]{mt_subset}}} 19 | 20 | \item{ncols}{cell size provided by \code{\link[MODISTools]{mt_subset}}} 21 | 22 | \item{transform}{transform the bounding box from sin to lat long coordinates, 23 | \code{TRUE} or \code{FALSE} (default = \code{TRUE})} 24 | } 25 | \description{ 26 | Converts lower-left sinusoidal coordinates to lat-lon sf bounding box 27 | } 28 | \examples{ 29 | 30 | \donttest{ 31 | # Download some test data 32 | subset <- mt_subset(product = "MOD11A2", 33 | lat = 40, 34 | lon = -110, 35 | band = "LST_Day_1km", 36 | start = "2004-01-01", 37 | end = "2004-03-31", 38 | progress = FALSE) 39 | 40 | # convert sinusoidal to lat / lon 41 | lat_lon <- sin_to_ll(subset$xllcorner, subset$yllcorner) 42 | 43 | # bind with the original dataframe 44 | subset <- cbind(subset, lat_lon) 45 | 46 | # convert to bounding box 47 | bb <- apply(subset, 1, function(x){ 48 | mt_bbox(xllcorner = x['xllcorner'], 49 | yllcorner = x['yllcorner'], 50 | cellsize = x['cellsize'], 51 | nrows = x['nrows'], 52 | ncols = x['ncols']) 53 | }) 54 | 55 | head(bb) 56 | } 57 | } 58 | \seealso{ 59 | \code{\link[MODISTools]{sin_to_ll}}, 60 | \code{\link[MODISTools]{mt_subset}} 61 | } 62 | -------------------------------------------------------------------------------- /man/mt_dates.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mt_dates.R 3 | \name{mt_dates} 4 | \alias{mt_dates} 5 | \title{Download all available dates} 6 | \usage{ 7 | mt_dates(product, lat, lon, site_id, network) 8 | } 9 | \arguments{ 10 | \item{product}{a valid MODIS product name} 11 | 12 | \item{lat}{latitude in decimal degrees} 13 | 14 | \item{lon}{longitude in decimal degrees} 15 | 16 | \item{site_id}{site id (overides lat / lon)} 17 | 18 | \item{network}{the network for which to generate the site list, 19 | when not provided the complete list is provided} 20 | } 21 | \value{ 22 | A data frame of all available dates for a MODIS Land 23 | Products Subsets products at the given location. 24 | } 25 | \description{ 26 | Lists all available dates for a MODIS Land Products Subset product 27 | at a particular location. 28 | } 29 | \examples{ 30 | 31 | \donttest{ 32 | # list all available MODIS Land Products Subsets products 33 | bands <- mt_dates(product = "MOD11A2", lat = 40, lon = -110) 34 | head(bands) 35 | } 36 | } 37 | \seealso{ 38 | \code{\link[MODISTools]{mt_products}} 39 | \code{\link[MODISTools]{mt_sites}} \code{\link[MODISTools]{mt_bands}} 40 | } 41 | -------------------------------------------------------------------------------- /man/mt_products.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mt_products.R 3 | \name{mt_products} 4 | \alias{mt_products} 5 | \title{Download all available products} 6 | \usage{ 7 | mt_products() 8 | } 9 | \value{ 10 | A data frame of all available MODIS Land Products Subsets products 11 | } 12 | \description{ 13 | Lists all available MODIS Land Products Subset products. 14 | } 15 | \examples{ 16 | 17 | \donttest{ 18 | # list all available MODIS Land Products Subsets products 19 | products <- mt_products() 20 | head(products) 21 | } 22 | 23 | } 24 | \seealso{ 25 | \code{\link[MODISTools]{mt_bands}} 26 | \code{\link[MODISTools]{mt_sites}} \code{\link[MODISTools]{mt_dates}} 27 | } 28 | -------------------------------------------------------------------------------- /man/mt_sites.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mt_sites.R 3 | \name{mt_sites} 4 | \alias{mt_sites} 5 | \title{Download all available fixed sites} 6 | \usage{ 7 | mt_sites(network) 8 | } 9 | \arguments{ 10 | \item{network}{the network for which to generate the site list, 11 | when not provided the complete list is provided} 12 | } 13 | \value{ 14 | A data frame of all available MODIS Land Products Subsets 15 | pre-processed sites 16 | } 17 | \description{ 18 | Lists all available MODIS Land Products Subset pre-processed sites 19 | } 20 | \examples{ 21 | 22 | \donttest{ 23 | # list all available MODIS Land Products Subsets products 24 | sites <- mt_sites() 25 | print(head(sites)) 26 | } 27 | 28 | } 29 | \seealso{ 30 | \code{\link[MODISTools]{mt_products}} 31 | \code{\link[MODISTools]{mt_bands}} \code{\link[MODISTools]{mt_dates}} 32 | } 33 | -------------------------------------------------------------------------------- /man/mt_subset.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mt_subset.R 3 | \name{mt_subset} 4 | \alias{mt_subset} 5 | \title{Download MODIS Land Products subsets} 6 | \usage{ 7 | mt_subset( 8 | product, 9 | band, 10 | lat, 11 | lon, 12 | start = "2000-01-01", 13 | end = format(Sys.time(), "\%Y-\%m-\%d"), 14 | km_lr = 0, 15 | km_ab = 0, 16 | site_id, 17 | network, 18 | site_name = "sitename", 19 | out_dir = tempdir(), 20 | internal = TRUE, 21 | progress = TRUE 22 | ) 23 | } 24 | \arguments{ 25 | \item{product}{a valid MODIS product name} 26 | 27 | \item{band}{band or bands (as a character vector) to download} 28 | 29 | \item{lat}{latitude in decimal degrees} 30 | 31 | \item{lon}{longitude in decimal degrees} 32 | 33 | \item{start}{start date} 34 | 35 | \item{end}{end date} 36 | 37 | \item{km_lr}{km left-right to sample (rounded to the nearest integer)} 38 | 39 | \item{km_ab}{km above-below to sample (rounded to the nearest integer)} 40 | 41 | \item{site_id}{site id (overides lat / lon)} 42 | 43 | \item{network}{the network for which to generate the site list, 44 | when not provided the complete list is provided} 45 | 46 | \item{site_name}{arbitrary site name used in writing data to file 47 | (default = sitename)} 48 | 49 | \item{out_dir}{path where to store the data if writing to disk 50 | (default = tempdir())} 51 | 52 | \item{internal}{should the data be returned as an internal data structure 53 | \code{TRUE} or \code{FALSE} (default = \code{TRUE})} 54 | 55 | \item{progress}{show download progress} 56 | } 57 | \value{ 58 | A data frame combining meta-data and actual data values. 59 | } 60 | \description{ 61 | Download a MODIS Land Products Subset product 62 | for a given point location buffered with a given amount of kilometers 63 | left-right, top-bottom for a given location (provided as latitude and 64 | longitude values). 65 | } 66 | \examples{ 67 | 68 | \donttest{ 69 | # list all available MODIS Land Products Subsets products 70 | # download data 71 | subset <- mt_subset(product = "MOD11A2", 72 | lat = 40, 73 | lon = -110, 74 | band = "LST_Day_1km", 75 | start = "2004-01-01", 76 | end = "2004-03-31", 77 | progress = FALSE) 78 | head(subset) 79 | } 80 | } 81 | \seealso{ 82 | \code{\link[MODISTools]{mt_sites}} 83 | \code{\link[MODISTools]{mt_dates}} \code{\link[MODISTools]{mt_bands}} 84 | \code{\link[MODISTools]{mt_products}} 85 | \code{\link[MODISTools]{mt_batch_subset}} 86 | } 87 | -------------------------------------------------------------------------------- /man/mt_to_terra.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mt_to_terra.R 3 | \name{mt_to_terra} 4 | \alias{mt_to_terra} 5 | \title{Convert tidy MODISTools data to terra SpatRaster} 6 | \usage{ 7 | mt_to_terra(df, reproject = FALSE) 8 | } 9 | \arguments{ 10 | \item{df}{a valid MODISTools data frame with a single band (filter for a 11 | particular band using the dplyr \code{filter()} function or base \code{subset()}} 12 | 13 | \item{reproject}{reproject output to lat / long (default = \code{FALSE})} 14 | } 15 | \value{ 16 | A terra SpatRaster populated with the tidy dataframe values 17 | } 18 | \description{ 19 | Convert tidy MODISTools data to a terra SpatRaster for easy 20 | spatial processing and plotting. 21 | } 22 | \examples{ 23 | 24 | \donttest{ 25 | # list all available MODIS Land Products Subsets products 26 | # download data 27 | LC <- mt_subset(product = "MCD12Q1", 28 | lat = 48.383662, 29 | lon = 2.610250, 30 | band = "LC_Type1", 31 | start = "2005-01-01", 32 | end = "2005-12-30", 33 | km_lr = 2, 34 | km_ab = 2, 35 | site_name = "testsite", 36 | internal = TRUE, 37 | progress = FALSE) 38 | 39 | head(LC) 40 | 41 | # convert to raster 42 | LC_r <- mt_to_terra(df = LC) 43 | } 44 | } 45 | \seealso{ 46 | \code{\link[MODISTools]{mt_subset}} 47 | \code{\link[MODISTools]{mt_batch_subset}} 48 | } 49 | -------------------------------------------------------------------------------- /man/sin_to_ll.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/coordinate_conversion.R 3 | \name{sin_to_ll} 4 | \alias{sin_to_ll} 5 | \title{Convert sinusoidal coordinates to lat / lon} 6 | \usage{ 7 | sin_to_ll(x, y) 8 | } 9 | \arguments{ 10 | \item{x}{sinusoidal x coordinate (vector)} 11 | 12 | \item{y}{sinusoidal y coordinate (vector)} 13 | } 14 | \description{ 15 | A full description of the sinusoidal projection is provided on the 16 | lpdaac page: 17 | https://lpdaac.usgs.gov/dataset_discovery/modis 18 | and wikipedia: 19 | https://en.wikipedia.org/wiki/Sinusoidal_projection 20 | } 21 | \examples{ 22 | 23 | \donttest{ 24 | # Download some test data 25 | subset <- mt_subset(product = "MOD11A2", 26 | lat = 40, 27 | lon = -110, 28 | band = "LST_Day_1km", 29 | start = "2004-01-01", 30 | end = "2004-03-31", 31 | progress = FALSE) 32 | 33 | # convert sinusoidal to lat / lon 34 | lat_lon <- sin_to_ll(subset$xllcorner, subset$yllcorner) 35 | 36 | # bind with the original dataframe 37 | subset <- cbind(subset, lat_lon) 38 | head(subset) 39 | } 40 | } 41 | \seealso{ 42 | \code{\link[MODISTools]{mt_bbox}} 43 | } 44 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | # Run all unit tests 2 | 3 | testthat::test_check("MODISTools") 4 | -------------------------------------------------------------------------------- /tests/testthat/test_coordinate_conversions.R: -------------------------------------------------------------------------------- 1 | context("Ancillary functions") 2 | 3 | # test coordinate conversions 4 | test_that("test coordinate transforms",{ 5 | skip_on_cran() 6 | subset <- mt_subset( 7 | product = "MOD11A2", 8 | lat = 40, 9 | lon = -110, 10 | band = "LST_Day_1km", 11 | start = "2004-01-01", 12 | end = "2004-03-31", 13 | progress = FALSE 14 | ) 15 | 16 | # test conversion 17 | expect_is( 18 | sin_to_ll(x = subset$xllcorner, y = subset$yllcorner) 19 | , 20 | "data.frame" 21 | ) 22 | 23 | # test conversion missing parameter 24 | expect_error( 25 | sin_to_ll(x = subset$xllcorner) 26 | ) 27 | 28 | # test sf bounding box conversion 29 | expect_is( 30 | apply(subset,1, function(x){ 31 | mt_bbox(xllcorner = x['xllcorner'], 32 | yllcorner = x['yllcorner'], 33 | cellsize = x['cellsize'], 34 | nrows = x['nrows'], 35 | ncols = x['ncols']) 36 | })[[1]], 37 | "sfc" 38 | ) 39 | 40 | # test sf bounding box conversion missing parameter 41 | expect_error( 42 | apply(sbuset, 1, function(x){ 43 | mt_bbox(cellsize = x['cellsize'], 44 | nrows = x['nrows'], 45 | ncols = x['ncols']) 46 | }) 47 | ) 48 | }) 49 | 50 | # test raster conversions 51 | test_that("test terra conversion",{ 52 | skip_on_cran() 53 | subset <- mt_subset( 54 | product = "MOD11A2", 55 | lat = 40, 56 | lon = -110, 57 | band = "LST_Day_1km", 58 | start = "2004-01-01", 59 | end = "2004-03-31", 60 | progress = FALSE 61 | ) 62 | 63 | multi_band <- mt_subset(product = "MCD12Q1", 64 | lat = 48.383662, 65 | lon = 2.610250, 66 | band = c("LC_Type1","LC_Type2"), 67 | start = "2005-01-01", 68 | end = "2005-06-30", 69 | km_lr = 2, 70 | km_ab = 2, 71 | site_name = "testsite", 72 | internal = TRUE, 73 | progress = FALSE) 74 | 75 | # good conversion into stack 76 | expect_silent(mt_to_terra(subset)) 77 | 78 | # multi-band error 79 | expect_error(mt_to_terra(multi_band)) 80 | 81 | # not a data frame 82 | expect_error(mt_to_terra(df = "not a dataframe")) 83 | 84 | # missing input 85 | expect_error(mt_to_terra()) 86 | }) 87 | 88 | -------------------------------------------------------------------------------- /tests/testthat/test_download_functions.R: -------------------------------------------------------------------------------- 1 | context("Test downloads") 2 | 3 | # test functions without parameters 4 | # only can fail upon server error 5 | test_that("test mt_products()",{ 6 | skip_on_cran() 7 | expect_is(mt_products(), "data.frame") 8 | }) 9 | 10 | test_that("test mt_sites()",{ 11 | skip_on_cran() 12 | expect_is(mt_sites(), "data.frame") 13 | }) 14 | 15 | test_that("test mt_bands()",{ 16 | skip_on_cran() 17 | expect_is(mt_bands(product = "MOD11A2"), "data.frame") 18 | expect_error(mt_bands(product = "MOD11A6")) 19 | }) 20 | 21 | # download tests 22 | test_that("test mt_dates()",{ 23 | skip_on_cran() 24 | 25 | # check dates 26 | expect_is( 27 | mt_dates( 28 | product = "MOD11A2", 29 | lat = 40, 30 | lon = -110 31 | ), 32 | "data.frame" 33 | ) 34 | 35 | # error wrong product 36 | expect_error( 37 | mt_dates( 38 | product = "MOD11A6", 39 | lat = 40, 40 | lon = -110 41 | ) 42 | ) 43 | 44 | # error missing latitude 45 | expect_error( 46 | mt_dates( 47 | product = "MOD11A2", 48 | lon = -110 49 | ) 50 | ) 51 | 52 | expect_is( 53 | mt_dates( 54 | product = "MOD11A2", 55 | site_id = mt_sites()$siteid[1] 56 | ), 57 | "data.frame" 58 | ) 59 | 60 | expect_error( 61 | mt_dates( 62 | product = "MOD11A2", 63 | site_id = "test" 64 | ) 65 | ) 66 | }) 67 | 68 | test_that("test mt_subset()",{ 69 | skip_on_cran() 70 | 71 | # good query 72 | expect_is( 73 | mt_subset( 74 | product = "MOD11A2", 75 | lat = 40, 76 | lon = -110, 77 | band = "LST_Day_1km", 78 | start = "2004-01-01", 79 | end = "2004-03-31", 80 | progress = FALSE 81 | ), 82 | "data.frame" 83 | ) 84 | 85 | # dates out of range 86 | expect_error( 87 | mt_subset( 88 | product = "MOD11A2", 89 | lat = 40, 90 | lon = -110, 91 | band = "LST_Day_1km", 92 | start = "1990-01-01", 93 | end = "1990-02-20", 94 | progress = FALSE 95 | ) 96 | ) 97 | 98 | # no band provided 99 | expect_error( 100 | mt_subset( 101 | product = "MOD11A2", 102 | lat = 40, 103 | lon = -110, 104 | start = "2004-01-01", 105 | end = "2004-02-20", 106 | progress = FALSE 107 | ) 108 | ) 109 | 110 | # bad band provided 111 | expect_error( 112 | mt_subset( 113 | product = "MOD11A2", 114 | lat = 40, 115 | lon = -110, 116 | band = "LST_Day_0km", 117 | start = "2004-01-01", 118 | end = "2004-02-20", 119 | progress = FALSE 120 | ) 121 | ) 122 | 123 | # missing coordinate 124 | expect_error( 125 | mt_subset( 126 | product = "MOD11A2", 127 | lat = 40, 128 | band = "LST_Day_1km", 129 | start = "2004-01-01", 130 | end = "2004-03-31" 131 | ) 132 | ) 133 | 134 | # no product provided 135 | expect_error( 136 | mt_subset( 137 | lat = 40, 138 | lon = -110, 139 | band = "LST_Day_1km", 140 | start = "2004-01-01", 141 | end = "2004-03-31" 142 | ) 143 | ) 144 | 145 | # wrong product provided 146 | expect_error( 147 | mt_subset( 148 | product = "MOD11AZ", 149 | lat = 40, 150 | lon = -110, 151 | band = "LST_Day_1km", 152 | start = "2004-01-01", 153 | end = "2004-03-31" 154 | ) 155 | ) 156 | 157 | # good site query 158 | expect_is( 159 | mt_subset( 160 | product = "MOD11A2", 161 | site_id = "us_tennessee_neon_ornl", 162 | band = "LST_Day_1km", 163 | start = "2004-01-01", 164 | end = "2004-03-31" 165 | ), 166 | "data.frame" 167 | ) 168 | 169 | # bad site query 170 | expect_error( 171 | mt_subset( 172 | product = "MOD11A2", 173 | site_id = "test", 174 | band = "LST_Day_1km", 175 | start = "2004-01-01", 176 | end = "2004-03-31" 177 | ) 178 | ) 179 | 180 | # write to disk test 181 | expect_silent( 182 | mt_subset( 183 | product = "MOD11A2", 184 | lat = 40, 185 | lon = -110, 186 | band = "LST_Day_1km", 187 | start = "2004-01-01", 188 | end = "2004-03-31", 189 | internal = FALSE, 190 | progress = FALSE 191 | ) 192 | ) 193 | }) 194 | 195 | # create data frame with a site_name, lat and lon column 196 | # holding the respective names of sites and their location 197 | df <- data.frame("site_name" = paste("test",1:2)) 198 | df$lat <- 40 199 | df$lon <- -110 200 | 201 | write.table(df, paste0(tempdir(),"/batch.csv"), 202 | quote = FALSE, 203 | row.names = FALSE, 204 | col.names = TRUE, 205 | sep = ",") 206 | 207 | test_that("test mt_batch_subset()",{ 208 | skip_on_cran() 209 | 210 | # test batch download 211 | expect_is( 212 | mt_batch_subset( 213 | df = df, 214 | product = "MOD11A2", 215 | band = "LST_Day_1km", 216 | internal = TRUE, 217 | start = "2004-01-01", 218 | end = "2004-03-31" 219 | ), 220 | "data.frame" 221 | ) 222 | 223 | # write data to disk 224 | expect_silent( 225 | mt_batch_subset( 226 | df = df, 227 | product = "MOD11A2", 228 | band = "LST_Day_1km", 229 | start = "2004-01-01", 230 | end = "2004-03-31", 231 | internal = FALSE 232 | ) 233 | ) 234 | 235 | # test batch download from csv 236 | expect_is( 237 | mt_batch_subset( 238 | df = paste0(tempdir(), "/batch.csv"), 239 | product = "MOD11A2", 240 | band = "LST_Day_1km", 241 | internal = TRUE, 242 | start = "2004-01-01", 243 | end = "2004-03-31" 244 | ), 245 | "data.frame" 246 | ) 247 | 248 | # error, misssing csv 249 | expect_error( 250 | mt_batch_subset( 251 | df = "fail.csv", 252 | product = "MOD11A2", 253 | band = "LST_Day_1km", 254 | internal = TRUE, 255 | start = "2004-01-01", 256 | end = "2004-03-31" 257 | ) 258 | ) 259 | 260 | # error missing data frame parameter 261 | expect_error( 262 | mt_batch_subset( 263 | product = "MOD11A2", 264 | band = "LST_Day_1km", 265 | internal = TRUE, 266 | start = "2004-01-01", 267 | end = "2004-03-31" 268 | ) 269 | ) 270 | 271 | # error bad product name 272 | expect_error( 273 | mt_batch_subset( 274 | df = df, 275 | product = "MOD11AZ", 276 | band = "LST_Day_1km", 277 | internal = TRUE, 278 | start = "2004-01-01", 279 | end = "2004-03-31" 280 | ) 281 | ) 282 | 283 | # error missing product 284 | expect_error( 285 | mt_batch_subset( 286 | df = df, 287 | band = "LST_Day_1km", 288 | internal = TRUE, 289 | start = "2004-01-01", 290 | end = "2004-03-31" 291 | ) 292 | ) 293 | 294 | # error bad band name 295 | expect_error( 296 | mt_batch_subset( 297 | df = df, 298 | product = "MOD11A2", 299 | band = "LST_Day_0km", 300 | internal = TRUE, 301 | start = "2004-01-01", 302 | end = "2004-03-31" 303 | ) 304 | ) 305 | 306 | # missing band name 307 | expect_error( 308 | mt_batch_subset( 309 | df = df, 310 | product = "MOD11A2", 311 | internal = TRUE, 312 | start = "2004-01-01", 313 | end = "2004-03-31" 314 | ) 315 | ) 316 | }) 317 | -------------------------------------------------------------------------------- /tests/testthat/test_server_errors.R: -------------------------------------------------------------------------------- 1 | context("Test server error messages") 2 | 3 | test_that("error messages from server are shown to the user", { 4 | skip_on_cran() 5 | 6 | # temporary wrapper 7 | ss <- function(lon, lat) { 8 | mt_subset(product = "MOD11A2", 9 | lat = lat, 10 | lon = lon, 11 | band = "LST_Day_1km", 12 | start = "2004-01-01", 13 | end = "2004-01-02", 14 | progress = FALSE) 15 | } 16 | 17 | expect_silent( 18 | x <- ss(-110, 40) 19 | ) 20 | expect_error( 21 | ss(40, -110) 22 | ) 23 | expect_error( 24 | ss(400, -40) 25 | ) 26 | }) 27 | 28 | -------------------------------------------------------------------------------- /vignettes/modistools-vignette.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "MODISTools" 3 | author: "Koen Hufkens" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{MODISTools} 8 | %\VignetteEngine{knitr::knitr} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r setup, include = FALSE} 13 | knitr::opts_chunk$set( 14 | error = TRUE, 15 | collapse = TRUE, 16 | comment = "#>" 17 | ) 18 | 19 | # load the library 20 | library(MODISTools) 21 | library(terra) 22 | library(ggplot2) 23 | library(dplyr) 24 | library(sf) 25 | 26 | # pre-load data 27 | data("arcachon_lai") 28 | data("arcachon_lc") 29 | 30 | ``` 31 | 32 | The MODISTools package has as goal to facilitate the interface between R and the MODIS Land Product Subset API at the Oak Ridge National Laboratory Distributed Active Archive Center (DAAC). This programmatic interface to the ['MODIS Land Products Subsets' web services](https://modis.ornl.gov/data/modis_webservice.html) allows for easy downloads of 'MODIS' time series (of single pixels or small regions of interest) directly to your R workspace or your computer. Below an example is provided on how to download a MODIS time series as well as list ancillary data. 33 | 34 | # Listing products / bands / dates 35 | 36 | In order to assess which products are available, which product bands are provided and which temporal range is covered one has to list these ancillary data. All these options can be queried using the `mt_*()` functions. 37 | 38 | To list all available products use the `mt_products()` function. 39 | 40 | ```{r eval = TRUE} 41 | products <- mt_products() 42 | head(products) 43 | ``` 44 | 45 | Once you have settled on the product you want to use in your analysis you will have to select a band, or multiple bands you want to download for a given location. To list all available bands for a given product use the mt_bands() function. You can use the `mt_bands()` function to list all available bands for a given product. Below I list all bands for the MOD13Q1 vegetation index product. 46 | 47 | ```{r eval = TRUE} 48 | bands <- mt_bands(product = "MOD13Q1") 49 | head(bands) 50 | ``` 51 | 52 | > Note the band names (listed in band column) you want to download, this variable will need to be passed in the final download statement. 53 | 54 | Similarly you can list all available dates (temporal coverage) for a given product and location defined using a latitude and longitude with the `mt_dates()` function. 55 | 56 | ```{r eval = TRUE} 57 | dates <- mt_dates(product = "MOD13Q1", lat = 42, lon = -110) 58 | head(dates) 59 | ``` 60 | 61 | # Downloading MODIS time series 62 | 63 | Once you decide on which data to download using the above functions you can use these parameters to download a time series using the `mt_subset()` function. The below query downloads MOD15A2H based leaf area index (LAI) data for the year 2014 for an area around the Arcachon basin in the south west of France. We will also download land cover data (MCD12Q1, IGBP) at a similar scale. The location is named 'arcachon'. The output is saved to a variables called subset and LC in the R workspace (as defined by the parameter internal = TRUE, when set to FALSE the data is written to file). Keep in mind that this operation might take a while. 64 | 65 | ```{r eval = FALSE} 66 | # download the MODIS land cover (IGBP) and NDVI data 67 | # for a region around the French city and basin of Arcachon 68 | arcachon_lai <- mt_subset(product = "MOD15A2H", 69 | lat = 44.656286, 70 | lon = -1.174748, 71 | band = "Lai_500m", 72 | start = "2004-01-01", 73 | end = "2004-12-30", 74 | km_lr = 20, 75 | km_ab = 20, 76 | site_name = "arcachon", 77 | internal = TRUE, 78 | progress = FALSE 79 | ) 80 | 81 | arcachon_lc <- mt_subset( 82 | product = "MCD12Q1", 83 | lat = 44.656286, 84 | lon = -1.174748, 85 | band = "LC_Type1", 86 | start = "2004-01-01", 87 | end = "2004-3-20", 88 | km_lr = 20, 89 | km_ab = 20, 90 | site_name = "arcachon", 91 | internal = TRUE, 92 | progress = FALSE 93 | ) 94 | ``` 95 | 96 | The output format is a *tidy* data frame, as shown above. When witten to a csv with the parameter `internal = FALSE` this will result in a flat file on disk. 97 | 98 | ```{r} 99 | head(arcachon_lai) 100 | head(arcachon_lc) 101 | ``` 102 | 103 | Note that when a a region is defined using km_lr and km_ab multiple pixels might be returned. These are indexed using the `pixel` column in the data frame containing the time series data. The remote sensing values are listed in the `value` column. When no band is specified all bands of a given product are returned, be mindful of the fact that different bands might require different multipliers to represent their true values. 104 | 105 | When a large selection of locations is needed you might benefit from using the batch download function `mt_batch_subset()`, which provides a wrapper around the `mt_subset()` function in order to speed up large download batches. This function has a similar syntax to `mt_subset()` but requires a data frame defining site names (site_name) and locations (lat / lon) (or a comma delimited file with the same structure) to specify a list of download locations. 106 | 107 | ```{r eval = TRUE} 108 | # create data frame with a site_name, lat and lon column 109 | # holding the respective names of sites and their location 110 | df <- data.frame("site_name" = paste("test",1:2), stringsAsFactors = FALSE) 111 | df$lat <- 40 112 | df$lon <- -110 113 | 114 | # an example batch download data frame 115 | head(df) 116 | ``` 117 | 118 | ```{r eval = FALSE} 119 | # test batch download 120 | subsets <- mt_batch_subset(df = df, 121 | product = "MOD13Q1", 122 | band = "250m_16_days_NDVI", 123 | km_lr = 1, 124 | km_ab = 1, 125 | start = "2004-01-01", 126 | end = "2004-12-30", 127 | internal = TRUE) 128 | ``` 129 | 130 | # Worked example using LAI values around the bay of Arcachon 131 | 132 | The below example processes the data downloaded above to look at differences in the seasonal changes in leaf area index (LAI, or the amount of leaves per unit ground area) for the Arcachon bay in south-west France. To do this we merge the land cover and LAI data on a pixel by pixel basis. 133 | 134 | ```{r} 135 | # merge land cover and lai data 136 | arcachon <- arcachon_lc %>% 137 | rename("lc" = "value") %>% 138 | select("lc","pixel") %>% 139 | right_join(arcachon_lai, by = "pixel") 140 | ``` 141 | 142 | Then, filter out all non valid values (> 100), only select evergreen and deciduous land cover classes (1 and 5, or, ENF and DBF respectivelly), convert them to more readable labels, and across these land cover classes take the median per acquisition date. 143 | 144 | ```{r} 145 | # create a plot of the data - accounting for the multiplier (scale) component 146 | arcachon <- arcachon %>% 147 | filter(value <= 100, 148 | lc %in% c("1","5")) %>% # retain everything but fill values 149 | mutate(lc = ifelse(lc == 1, "ENF","DBF")) %>% 150 | group_by(lc, calendar_date) %>% # group by lc and date 151 | summarize(doy = as.numeric(format(as.Date(calendar_date)[1],"%j")), 152 | lai_mean = median(value * as.double(scale))) 153 | ``` 154 | 155 | Finally, the plot will show you the seasonal time series of LAI for both land cover classes (ENF and DBF). Note the difference in timing and amplitude between both these forest types, where the evergreen (ENF) pixels show lower LAI values and a more gradual seasonal pattern compared to the deciduous trees. 156 | 157 | ```{r fig.width = 7, fig.height=3} 158 | # plot LAI by date and per land cover class 159 | ggplot(arcachon, aes(x = doy, y = lai_mean)) + 160 | geom_point() + 161 | geom_smooth(span = 0.3, method = "loess") + 162 | labs(x = "day of year (DOY)", 163 | y = "leaf area index (LAI)") + 164 | theme_minimal() + 165 | facet_wrap(~ lc) 166 | ``` 167 | 168 | # Conversion of corner coordinates 169 | 170 | Corner coordinates of the pixel area extracted are provided, these can be used to calculate the coverage of the extracted area. Coordinates are provided in the original sinusoidal grid coordinates and first have to be transformed into latitude longitude (for convenience). 171 | 172 | ```{r } 173 | # convert the coordinates 174 | lat_lon <- sin_to_ll(arcachon_lc$xllcorner, arcachon_lc$yllcorner) 175 | 176 | # bind with the original dataframe 177 | subset <- cbind(arcachon_lc, lat_lon) 178 | 179 | head(subset) 180 | ``` 181 | 182 | Together with meta-data regarding cell size, number of columns and rows the bounding box of the extracted data can be calculated. 183 | 184 | ```{r fig.width = 5, fig.height=5} 185 | # convert to bounding box 186 | bb <- apply(arcachon_lc, 1, function(x){ 187 | mt_bbox(xllcorner = x['xllcorner'], 188 | yllcorner = x['yllcorner'], 189 | cellsize = x['cellsize'], 190 | nrows = x['nrows'], 191 | ncols = x['ncols']) 192 | }) 193 | 194 | # plot one bounding box 195 | plot(bb[[1]]) 196 | 197 | # add the location of the queried coordinate within the polygon 198 | points(arcachon_lc$longitude[1], 199 | arcachon_lc$latitude[1], 200 | pch = 20, 201 | col = "red") 202 | ``` 203 | 204 | # Conversion to (gridded) raster data 205 | 206 | Although the package is often used to deal with single pixel locations the provisions to download a small region of interest defined by kilometers left-right (west-east) or top-bottom (north-south) allows you to grab small geographic regions for further analysis. The default tidy dataframe format isn't ideal for visualizing this inherently spatial data. Therefore a helper function `mt_to_raster()` is available to convert the tidy dataframe to a gridded (georeferenced) raster format. 207 | 208 | Below a small region (20x20km) is downloaded around the seaside town of Arcachon, France for the [MODIS land cover product (MCD12Q1)](https://lpdaac.usgs.gov/products/mcd12q1v006/). The data is converted using `mt_to_raster()` with a reproject parameter set to true to plot latitude and longitude coordinates (instead of the default sinusoidal ones). 209 | 210 | 211 | ```{r fig.width = 5, fig.height=5} 212 | # convert to raster, when reproject is TRUE 213 | # the data is reprojected to lat / lon if FALSE 214 | # the data is shown in its original sinuidal projection 215 | LC_r <- mt_to_terra(df = arcachon_lc, reproject = TRUE) 216 | 217 | # plot the raster data as a map 218 | plot(LC_r) 219 | ``` 220 | --------------------------------------------------------------------------------