Skip to content

Instantly share code, notes, and snippets.

@mschmidty
Last active May 22, 2026 02:40
Show Gist options
  • Select an option

  • Save mschmidty/df27ba5671f23eb71c01b3f3c50aeb9e to your computer and use it in GitHub Desktop.

Select an option

Save mschmidty/df27ba5671f23eb71c01b3f3c50aeb9e to your computer and use it in GitHub Desktop.
rgee function for getting terrain data and returing a raster or extracted points
tar_extract_terrain <- function(
geom_input,
scale = 30,
file_prefix = "rgee_terrain"
) {
# --- 1. Compute Earth Engine Terrain Stack ---
dem <- ee$ImageCollection('COPERNICUS/DEM/GLO30')$select('DEM')$mosaic()
terrain_products <- ee$Terrain$products(dem)
slope <- terrain_products$select('slope')
aspect <- terrain_products$select('aspect')
tpi_kernel <- ee$Kernel$circle(radius = 3, units = 'pixels')
mean_dem <- dem$focal_mean(kernel = tpi_kernel)
tpi <- dem$subtract(mean_dem)$rename('TPI')
tri_kernel <- ee$Kernel$square(radius = 1, units = 'pixels')
tri <- dem$reduceNeighborhood(
reducer = ee$Reducer$stdDev(),
kernel = tri_kernel
)$rename('TRI')
terrain_stack <- dem$addBands(slope)$addBands(aspect)$addBands(tpi)$addBands(
tri
)$rename(c('elevation', 'slope', 'aspect', 'TPI', 'TRI'))
# --- 2. Polymorphic Input Normalization & Routing ---
is_ee_raster <- inherits(geom_input, "ee.image.Image") ||
inherits(geom_input, "ee.imagecollection.ImageCollection")
if (is_ee_raster) {
geom_type <- "Raster"
ee_raster_geometry <- geom_input$geometry()
processed_ee <- terrain_stack$clip(ee_raster_geometry)
} else {
if (inherits(geom_input, "sf") || inherits(geom_input, "sfc")) {
message("Local R 'sf' layer detected. Converting to GEE environment...")
geom_string <- as.character(sf::st_geometry_type(
geom_input,
by_geometry = FALSE
))
ee_geom <- sf_as_ee(geom_input)
} else {
if (inherits(geom_input, "ee.geometry.Geometry")) {
ee_type_obj <- geom_input$type()
geom_string <- ee_type_obj$getInfo()
} else {
ee_geom_obj <- geom_input$geometry()
ee_type_obj <- ee_geom_obj$type()
geom_string <- ee_type_obj$getInfo()
}
ee_geom <- geom_input
}
if (grepl("Point", geom_string, ignore.case = TRUE)) {
geom_type <- "Points"
processed_ee <- terrain_stack$sampleRegions(
collection = ee_geom,
scale = scale,
geometries = TRUE
)
} else {
geom_type <- "Polygon"
processed_ee <- terrain_stack$clip(ee_geom)
}
}
task_desc <- paste0(file_prefix, "_", format(Sys.time(), "%Y%m%d_%H%M%S"))
if (geom_type == "Points") {
message("Launching GEE point extraction table export...")
task <- ee$batch$Export$table$toDrive(
collection = processed_ee,
description = task_desc,
fileFormat = "CSV"
)
ext <- ".csv"
} else {
message("Launching GEE regional raster mosaic export...")
export_region <- if (is_ee_raster) geom_input$geometry() else ee_geom
task <- ee$batch$Export$image$toDrive(
image = processed_ee,
description = task_desc,
scale = scale,
region = export_region,
fileFormat = "GeoTIFF"
)
ext <- ".tif"
}
# --- 3. FIX: Custom Safe Monitoring Loop (Bypasses ee_monitoring Overflow) ---
task$start()
message(
"Task dispatched safely to Earth Engine Cloud. Monitoring execution state..."
)
# Manual polling loop to avoid reticulate C long type casting errors
repeat {
status_state <- task$status()$state
message(paste("Current Cloud State:", status_state))
if (status_state %in% c("COMPLETED", "FAILED", "CANCELLED")) {
break
}
Sys.sleep(10) # Check status every 10 seconds to keep targets synchronized
}
if (status_state != "COMPLETED") {
stop(paste(
"Earth Engine processing failed with cloud execution state:",
status_state
))
}
# --- 4. Locate and Download the File via 'googledrive' ---
message("Locating generated asset inside Google Drive filesystem...")
target_filename <- paste0(task_desc, ext)
Sys.sleep(5)
drive_file <- drive_find(name = target_filename, n_max = 1)
if (nrow(drive_file) == 0) {
stop(paste(
"Could not find file",
target_filename,
"in your Google Drive root directory."
))
}
tmp_path <- tempfile(fileext = ext)
message(paste("Downloading dataset locally to path:", tmp_path))
drive_download(
file = as_id(drive_file$id),
path = tmp_path,
overwrite = TRUE
)
drive_rm(as_id(drive_file$id))
# --- 5. Ingest Data Back into R Memory Context ---
if (geom_type == "Points") {
point_df <- read.csv(tmp_path)
result <- st_read(point_df, geometry_column = ".geo", quiet = TRUE)
} else {
result <- terra::rast(tmp_path)
}
return(result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment