{"id":48918874,"url":"https://github.com/rmbl-sdp/rsdp","last_synced_at":"2026-04-17T04:07:09.827Z","repository":{"id":74595194,"uuid":"586036468","full_name":"rmbl-sdp/rSDP","owner":"rmbl-sdp","description":"R Interface for Spatial Data in the RMBL Spatial Data Platform","archived":false,"fork":false,"pushed_at":"2026-04-10T00:12:39.000Z","size":34821,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-04-10T00:25:46.848Z","etag":null,"topics":["data-science","dataset","rstats","spatial-data","spatio-temporal-data"],"latest_commit_sha":null,"homepage":"https://rmbl-sdp.github.io/rSDP","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc-by-4.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rmbl-sdp.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-01-06T19:12:04.000Z","updated_at":"2026-04-10T00:12:45.000Z","dependencies_parsed_at":"2023-09-25T06:57:21.512Z","dependency_job_id":null,"html_url":"https://github.com/rmbl-sdp/rSDP","commit_stats":{"total_commits":42,"total_committers":1,"mean_commits":42.0,"dds":0.0,"last_synced_commit":"f32092b048306fd2cf6f005c75e5573ba76f4867"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rmbl-sdp/rSDP","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmbl-sdp%2FrSDP","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmbl-sdp%2FrSDP/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmbl-sdp%2FrSDP/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmbl-sdp%2FrSDP/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rmbl-sdp","download_url":"https://codeload.github.com/rmbl-sdp/rSDP/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rmbl-sdp%2FrSDP/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31914486,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T18:22:33.417Z","status":"online","status_checked_at":"2026-04-17T02:00:06.879Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-science","dataset","rstats","spatial-data","spatio-temporal-data"],"created_at":"2026-04-17T04:07:08.975Z","updated_at":"2026-04-17T04:07:09.820Z","avatar_url":"https://github.com/rmbl-sdp.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\n```\n\n# rSDP \u003cimg src=\"man/figures/logo.png\" align=\"right\" /\u003e\n\n\u003c!-- badges: start --\u003e\n`r lifecycle::badge('experimental')`\n\u003c!-- badges: end --\u003e\n\nThe rSDP package provides a simple interface for discovering, querying, and subsetting data products that are incorporated into the RMBL Spatial Data Platform. The RMBL SDP provides a set of curated, high-resolution, and high-fidelity geospatial datasets for a set of domains in Western Colorado (USA) in the vicinity of [Rocky Mountain Biological Laboratory](https://rmbl.org). For more information about the RMBL SDP [see here](https://www.rmbl.org/scientists/resources/spatial-data-platform/).\n\nSDP data products are provided as geospatial raster datasets in [cloud-optimized Geotiff]() (COG) format. The rSDP package provides functions to access these datasets in cloud storage (Amazon S3) without downloading.\n\n## Installation\n\nYou can install the latest version of rSDP from [GitHub](https://github.com/) with:\n\n```{r install, eval=FALSE}\n# install.packages(\"remotes\")\nremotes::install_github(\"rmbl-sdp/rSDP\")\n```\n\nInstalling the development version of the `leaflet` package is currently required for web maps.\n\n```{r leaflet install, eval=FALSE}\nremotes::install_github(\"rstudio/leaflet\")\n```\n\n## Discovering SDP Data and Metadata\n\nThe package provides functions `sdp_get_catalog()`, and `sdp_get_metadata()` that download information about what datasets are currently available and what their spatial attributes are.\n\n```{r example}\nlibrary(rSDP)\n\n## Gets entries for vegetation data products in the Upper Gunnison (UG) domain.\nsdp_cat \u003c- sdp_get_catalog(domains=\"UG\", \n                           types=\"Vegetation\",\n                           deprecated=FALSE,\n                           return_stac=FALSE)\nsdp_cat[,1:5]\n```\n\n```{r example2}\n## Grabs detailed metadata for a specific dataset.\nitem_meta \u003c- sdp_get_metadata(catalog_id=\"R1D001\",return_list=TRUE)\n\n## Prints the detailed description.\nitem_description \u003c- item_meta$qgis$abstract[[1]]\nprint(item_description)\n```\n## Accessing SDP data in the cloud.\n\nThe function `sdp_get_raster()`, creates R representations of cloud-based datasets that can be used for further processing, returning a `SpatRaster` which can be further manipulated using functions in the `terra` package.\n\n```{r example3}\n## Creates a `SpatRaster` object for a dataset.\ndem \u003c- sdp_get_raster(catalog_id=\"R3D009\")\nterra::plot(dem)\n```\nAlternatively, you can plot these data on a web map:\n\n```{r example plet, eval=FALSE}\nterra::plet(dem,tiles=\"Esri.WorldImagery\")\n```\n## Downloading SDP data locally.\n\nBy default, `sdp_get_raster()` connects to cloud-based datasets without downloading them locally, but specifying `download_files=TRUE` and providing a local file path will download the raster data to disk. This can sometimes speed up operations that would be prohibitively slow with cloud-based data sources:\n\n```{r example3b, eval=FALSE}\n## Creates a local `SpatRaster`\ndem_local \u003c- sdp_get_raster(catalog_id=\"R3D009\",\n                            download_files=TRUE,\n                            download_path=\"~/Downloads\", \n                            overwrite=FALSE)\n```\n\n## Extracting samples of SDP data.\n\nThe function `sdp_extract_data()` extracts samples from datasets at locations represented by points, lines, or polygons.\n```{r example4}\n## Extracts values of an SDP dataset.\nelev \u003c- sdp_get_raster(catalog_id=\"R3D009\")\nslope \u003c- sdp_get_raster(catalog_id=\"R3D012\")\n\nlocation_df \u003c- data.frame(SiteName=c(\"Roaring Judy\",\"Gothic\",\"Galena Lake\"),\n                          Lat=c(38.716995,38.958446,39.021644),\n                          Lon=c(-106.853186,-106.988934,-107.072569))\nlocation_sv \u003c- terra::vect(location_df,geom=c(\"Lon\",\"Lat\"),crs=\"EPSG:4327\")\n\ndem_sample \u003c- sdp_extract_data(raster=elev,locations=location_sv)\nslope_sample \u003c- sdp_extract_data(raster=slope,locations=dem_sample)\nplot(slope_sample$UG_dem_3m_v1,slope_sample$UG_dem_slope_1m_v1,xlab=\"Elevation (m).\",\n     ylab=\"Slope (degrees)\")\n```\n\nWith line or polygon locations `sdp_extract_data()` summarizes raster values by line or polygon. The default method computes the mean value for each polygon, but you can also specify other summary functions using the `sum_fun` argument. \n\n```{r example5}\nslope \u003c- sdp_get_raster(catalog_id=\"R3D012\")\n\nlocation_poly \u003c- data.frame(SiteName=c(\"Wet\",\"Conifer\",\"Rocky\"),\n                            WKT=c(\"POLYGON ((327651 4313638,327620 4313727,327693 4313759, 327651 4313638))\",\n                                   \"POLYGON ((327340 4314059,327450 4314026,327418 4313970,327340 4314059))\",\n                                   \"POLYGON ((328193 4314314,328285 4314274,328244 4314223, 328193 4314314))\"))\nlocation_poly_sv \u003c- terra::vect(location_poly,geom=\"WKT\",crs=\"EPSG:32613\")\n\nslope_site_mean \u003c- sdp_extract_data(raster=slope,locations=location_poly_sv)\nslope_site_sd \u003c- sdp_extract_data(raster=slope,locations=slope_site_mean,\n                                  sum_fun=sd,bind=TRUE)\nnames(slope_site_sd) \u003c- c(\"SiteName\",\"ID\",\"Slope_mean\",\"ID2\",\"Slope_sd\")\n\nplot(slope_site_sd$Slope_mean,slope_site_sd$Slope_sd,xlab=\"Slope Mean (deg.)\",\n     ylab=\"Slope Standard Deviation\",pch=\"\")\ntext(slope_site_sd$Slope_mean,slope_site_sd$Slope_sd,labels=slope_site_sd$SiteName)\n```\nYou can also return all the cell values intersecting each line or polygon by specifying `sum_fun=NULL`. Passing the argument `exact=TRUE` with polygon features returns the proportion of each raster cell included in the polygon (useful for computing area-weighted means.)\n\n```{r example6, warning=FALSE}\nslope_allcells \u003c- sdp_extract_data(raster=slope,locations=slope_site_mean,\n                                  sum_fun=NULL,exact=TRUE,bind=FALSE)\nhead(slope_allcells)\n```\n\n## Working with raster time-series\n\nThe `sdp_get_raster()` and `sdp_extract_data()` functions also provide some convenience features for subsetting time-series datasets by day or year.\n\n```{r example7}\n## Connects to rasters from a temporal subset of daily data.\ntmax \u003c- sdp_get_raster(\"R4D004\",date_start=as.Date(\"2011-12-01\"),date_end=as.Date(\"2011-12-30\"))\n\n## Further subsets when extracting data\ntmax_sample \u003c- sdp_extract_data(tmax,location_sv,date_start=as.Date(\"2011-12-01\"),date_end=as.Date(\"2011-12-20\"))\ntmax_df \u003c- as.data.frame(tmax_sample)\ndates \u003c- as.Date(names(tmax_df)[3:ncol(tmax_sample)])\nsites \u003c- tmax_df$SiteName\n\n##Plots the result\nplot(dates,tmax_df[1,3:ncol(tmax_sample)],type=\"l\",ylab=\"Tmax (C)\",ylim=c(-15,7))\npoints(dates,tmax_df[2,3:ncol(tmax_sample)],type=\"l\",col=3)\npoints(dates,tmax_df[3,3:ncol(tmax_sample)],type=\"l\",col=4)\nlegend(\"bottomright\", legend=sites,col=c(1,3,4),bty=\"n\",lty=1)\n\n##Retrieving rasters from a subset of years.\nsnow_yearly \u003c- sdp_get_raster(\"R4D001\",years=c(2012,2019))\nterra::plot(snow_yearly,range=c(60,230))\n```\n\n## Extracting data from large time-series datasets.\n\nFor extracting subsets of large datasets, it's sometimes a good idea to loop over small subsets rather than extracting from a single large raster object with many (sometimes hundreds) of layers.\n\n```{r example8, warning=FALSE}\n## Extracts with a single call.\nstart1 \u003c- Sys.time()\ntmax1 \u003c- sdp_get_raster(\"R4D004\",date_start=as.Date(\"2004-10-01\"),date_end=as.Date(\"2004-10-31\"))\n\ntmax_extr1 \u003c- sdp_extract_data(tmax1,location_sv,verbose=FALSE)\nelapsed1 \u003c- Sys.time() - start1\n\n## Loops over layers (different subset to avoid cacheing).\nstart2 \u003c- Sys.time()\ntmax2 \u003c- sdp_get_raster(\"R4D004\",date_start=as.Date(\"2005-10-01\"),date_end=as.Date(\"2005-10-31\"),\n                        verbose=FALSE)\nlocations_proj \u003c- terra:::project(location_sv,\"EPSG:32613\")\n\nextr_list \u003c- list()\nfor(i in 1:terra::nlyr(tmax2)){\n  extr_dat \u003c- sdp_extract_data(tmax2[[i]],locations_proj,verbose=FALSE)[,3]\n  extr_list[[i]] \u003c- extr_dat\n}\ntmax_extr2 \u003c- do.call(cbind,extr_list)\nelapsed2 \u003c- Sys.time() - start2\n\n## Loops over creating the raster object itself. \n## This is slower single threaded, but can be more easily made parallel.\nstart3 \u003c- Sys.time()\ndays \u003c- seq(as.Date(\"2006-10-01\"),as.Date(\"2006-10-31\"),by=\"day\")\nextr_list3 \u003c- list()\nfor(i in 1:length(days)){\n  tmax3 \u003c- sdp_get_raster(\"R4D004\",date_start=days[i],date_end=days[i],verbose=FALSE)\n  extr_dat \u003c- sdp_extract_data(tmax3,locations_proj,verbose=FALSE)[,3]\n  extr_list3[[i]] \u003c- extr_dat\n}\ntmax_extr3 \u003c- do.call(cbind,extr_list3)\nelapsed3 \u003c- Sys.time() - start3\n\n## Parallel extraction via foreach.\nlibrary(foreach)\nlibrary(doParallel)\nlibrary(sf)\n\n## Can't pass SpatVector or SpatRaster objects via Foreach, so convert to sf.\nlocations_sf \u003c- st_as_sf(location_sv)\n\nstart4 \u003c- Sys.time()\ncl \u003c- parallel::makeCluster(4)\ndoParallel::registerDoParallel(cl)\ndays \u003c- seq(as.Date(\"2007-10-01\"),as.Date(\"2007-10-31\"),by=\"day\")\n\nextr_list4 \u003c- foreach::foreach(i=1:length(days),.packages=c(\"sf\",\"terra\",\"rSDP\")) %dopar% {\n  tmax4 \u003c- sdp_get_raster(\"R4D007\",date_start=days[i],\n                         date_end=days[i],verbose=FALSE)\n   locations_sv \u003c- vect(locations_sf)\n   extr_dat \u003c- sdp_extract_data(tmax4,locations=locations_sv,\n                                verbose=FALSE,return_type=\"sf\")[,4]\n   (st_drop_geometry(extr_dat))\n}\nparallel::stopCluster(cl)\ntmax_extr4 \u003c- do.call(cbind,extr_list4)\nelapsed4 \u003c- Sys.time() - start4\n\n##Collects timings.\ntimings \u003c- data.frame(approach=c(\"Single Call\",\"Looping sdp_extract_data()\",\"Looping over sdp_get_raster()\",\"Foreach\"),\n                      timing=c(elapsed1,elapsed2,elapsed3,elapsed4))\ntimings\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frmbl-sdp%2Frsdp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frmbl-sdp%2Frsdp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frmbl-sdp%2Frsdp/lists"}