基于rstac从EarthData筛选指定年月范围HLS数据集的技术咨询
解决方案:EarthData HLS数据集按年季筛选(rstac实现)
1. 能否直接通过stac_search跨年份筛选指定月份数据?
可以,但需要用CQL2过滤表达式精准匹配每年7月1日至9月15日的时间范围,而非单纯依赖datetime参数的全局区间。EarthData的STAC服务支持CQL2查询,你可通过rstac的cql_filter参数实现跨年份的季候筛选。
核心逻辑是针对item的datetime字段提取月、日做条件判断:
- 筛选7月整月
- 筛选8月整月
- 筛选9月1日至15日
对应的代码示例:
library(rstac) # 初始化STAC客户端 client <- stac("https://cmr.earthdata.nasa.gov/stac/LPCLOUD/") # 构造CQL2过滤表达式 cql_expr <- " (datetime >= '1984-01-01T00:00:00Z' AND datetime <= '2024-12-31T23:59:59Z') AND ( (month(datetime) = 7) OR (month(datetime) = 8) OR (month(datetime) = 9 AND day(datetime) <= 15) ) " # 执行查询 search_result <- client %>% stac_search( collections = c("HLSS30.v2.0", "HLSL30.v2.0"), cql_filter = cql_expr ) %>% get_request()
注:部分STAC服务对month()、day()这类日期函数支持有限,若查询报错,可切换至下文的替代方案。
2. 替代筛选方案:本地后处理
如果STAC服务不支持复杂CQL2日期函数,可先获取1984-2024年全量HLS数据的item列表,再在R中本地筛选符合日期范围的条目:
# 获取全量item(自动处理分页) full_result <- client %>% stac_search( collections = c("HLSS30.v2.0", "HLSL30.v2.0"), datetime = "1984-01-01/2024-12-31" ) %>% items_fetch_all() # 转换为数据框并提取日期 items_df <- items_as_dataframe(full_result) items_df$date <- as.Date(substr(items_df$datetime, 1, 10)) # 筛选目标日期范围 filtered_df <- items_df %>% mutate( month = lubridate::month(date), day = lubridate::day(date) ) %>% filter( (month == 7) | (month == 8) | (month == 9 & day <= 15) ) # 转换回rstac的items对象(用于后续下载) filtered_items <- items_from_dataframe(filtered_df)
3. 循环遍历年份查询并合并:完全可行
这种方式逻辑简单、兼容性强,尤其适合STAC服务对复杂过滤支持不佳的场景。你可以循环1984到2024的每一年,构造当年的7.1-9.15时间范围,分别查询后合并结果:
# 初始化空列表存储结果 all_items <- list() # 循环年份执行查询 for (year in 1984:2024) { start_date <- paste0(year, "-07-01") end_date <- paste0(year, "-09-15") year_result <- client %>% stac_search( collections = c("HLSS30.v2.0", "HLSL30.v2.0"), datetime = paste(start_date, end_date, sep = "/") ) %>% items_fetch_all() all_items[[as.character(year)]] <- year_result } # 合并所有年份的items combined_items <- items_merge(all_items) # 可选:转换为数据框查看 combined_df <- items_as_dataframe(combined_items)
关键注意事项
- EarthData的STAC服务需要身份验证,查询前需配置账号信息:
stac_auth(client, username = "your_username", password = "your_password") - 数据量较大时,
items_fetch_all()会自动处理分页,确保获取所有符合条件的条目。
内容的提问来源于stack exchange,提问作者M. Beausoleil
相关产品推荐
相关产品推荐

