-
-
Save stijnvanhoey/f7522feec20de928801f31373f571008 to your computer and use it in GitHub Desktop.
library(glue) | |
library(httr) | |
library(tidyverse) | |
library(jsonlite) | |
#' Search for planet labs images | |
#' | |
#' Credits to https://www.lentilcurtain.com/posts/accessing-planet-labs-data-api-from-r/ | |
#' | |
#' @param bbox bounding box | |
#' @param date_end date of last image (date) | |
#' @param date_start date of first image (date) | |
#' @param cloud_lim cloud cover limit (double) | |
#' @param cover_lim type of image (string) | |
#' @param item_name char, | |
#' @param api_key char, planet labs API Key (to request) | |
#' | |
#' @return | |
#' @export | |
#' | |
#' @examples | |
planet_search_asset <- function(bbox, date_end, date_start, | |
cloud_lim=0.2, cover_lim=0.5, | |
item_name="PSScene4Band", | |
api_key) { | |
#convert shapefile to geojson | |
#shapefile of bounding box must be EPSG:4326 Projection | |
geo_json_geometry <- list( | |
type = jsonlite::unbox("Polygon"), | |
coordinates = list(list( | |
c(bbox@xmin, | |
bbox@ymin), | |
c(bbox@xmin, | |
bbox@ymax), | |
c(bbox@xmax, | |
bbox@ymax), | |
c(bbox@xmax, | |
bbox@ymin), | |
c(bbox@xmin, | |
bbox@ymin) | |
)) | |
) | |
# filter for items the overlap with our chosen geometry | |
geometry_filter <- list( | |
type = jsonlite::unbox("GeometryFilter"), | |
field_name = jsonlite::unbox("geometry"), | |
config = geo_json_geometry | |
) | |
# we will search for images for up to a month before the date | |
# are interested in | |
dategte <- paste0(date_start, "T00:00:00.000Z") | |
datelte <- paste0(date_end, "T00:00:00.000Z") | |
# filter images by daterange | |
date_range_filter <- list( | |
type = jsonlite::unbox("DateRangeFilter"), | |
field_name = jsonlite::unbox("acquired"), | |
config = list( | |
gte = jsonlite::unbox(dategte), | |
lte = jsonlite::unbox(datelte)) | |
) | |
# filter by cloud cover | |
cloud_cover_filter <- list( | |
type = jsonlite::unbox("RangeFilter"), | |
field_name = jsonlite::unbox("cloud_cover"), | |
config = list( | |
lte = jsonlite::unbox(cloud_lim)) | |
) | |
# filter by coverage of bounding box | |
coverage_filter <- list( | |
type = jsonlite::unbox("RangeFilter"), | |
field_name = unbox("usable_data"), | |
config = list( | |
gte = jsonlite::unbox(cover_lim)) | |
) | |
# combine filters | |
filter_configs <- list( | |
type = jsonlite::unbox("AndFilter"), | |
config = list(date_range_filter, cloud_cover_filter, | |
geometry_filter, coverage_filter) | |
) | |
#build request | |
search_endpoint_request <- list( | |
item_types = item_name, | |
filter = filter_configs | |
) | |
#convert request to JSON | |
body_json <- jsonlite::toJSON(search_endpoint_request, pretty = TRUE) | |
#API request config | |
url <- 'https://api.planet.com/data/v1/quick-search' | |
body <- body_json | |
#send API request | |
request <- httr::POST(url, body = body_json, content_type_json(), | |
authenticate(api_key, "")) | |
#get request content | |
response <- httr::content(request) | |
return(response) | |
} | |
#' Setup api key header for planet API calls | |
#' | |
#' @param api_key char key received from planet labs | |
#' | |
#' @return formatted authentification header | |
#' | |
#' @examples | |
#' api_key <- "THIS_IS_YOUR_KEY" | |
#' planet_translate_key(api_key) | |
planet_translate_key <- function(api_key) { | |
glue::glue("api-key {api_key}") | |
} | |
#' Check current activity of an asset | |
#' | |
#' Can be used to check the current activity of the asset or to get the | |
#' activiation link if not yet active. | |
#' | |
#' @param itemtype char, type of asset to download, e.g. 'PSOrthoTile' | |
#' @param item_ID char, planet labs asset ID | |
#' @param api_key char key received from planet labs | |
#' | |
#' @return content of response | |
#' @export | |
#' | |
#' @examples | |
#' planet_activate_asset("PSOrthoTile", | |
#' "846486_3162616_2017-10-18_0c81", | |
#' "YOUR_KEY_FROM_PLANET_LABS") | |
planet_get_item <- function(itemtype, item_ID, api_key) { | |
url <- glue::glue("https://api.planet.com/data/v1/item-types/{itemtype}/items/{item_ID}/assets/") | |
response <- GET(url, | |
add_headers(Authorization = planet_translate_key(api_key)), | |
config("location")) | |
return(content(response)) | |
} | |
#' Activate an asset of planet labs | |
#' | |
#' @param itemtype char, type of asset to download, e.g. 'PSOrthoTile' | |
#' @param item_ID char, planet labs asset ID | |
#' @param api_key char key received from planet labs | |
#' @param asset_type char, type of asset to download, e.g. visual, analytic | |
#' | |
#' @return response of the activation | |
#' | |
#' @examples | |
planet_activate_asset <- function(itemtype, item_ID, api_key, | |
asset_type = "visual") { | |
response <- planet_get_item(itemtype, item_ID, api_key) | |
activation_link <- response[[asset_type]][["_links"]][["activate"]] | |
# Activate the asset with activation link | |
post_response <- POST(activation_link, | |
add_headers(Authorization = planet_translate_key(api_key))) | |
return(post_response) | |
} | |
#' Download asset after activation | |
#' | |
#' @param itemtype char, type of asset to download, e.g. 'PSOrthoTile' | |
#' @param item_ID char, planet labs asset ID | |
#' @param api_key char, key received from planet labs | |
#' @param fpath char, local file path to store downloaded images | |
#' @param asset_type char, type of asset to download, e.g. visual, analytic | |
#' | |
#' @examples | |
#' planet_download_asset("PSOrthoTile", | |
#' "846486_3162616_2017-10-18_0c81", | |
#' "YOUR_KEY_FROM_PLANET_LABS") | |
planet_download_asset <- function(itemtype, item_ID, api_key, | |
fpath = "data", | |
asset_type = "visual") { | |
# wait until ativated | |
response <- planet_get_item(itemtype, item_ID, api_key) | |
current_status <- response$visual$status | |
while (current_status != "active") { | |
message("Not yet activated, waiting...") | |
Sys.sleep(2) | |
response <- planet_get_item(itemtype, item_ID, api_key) | |
current_status <- response$visual$status | |
} | |
response <- planet_get_item(itemtype, item_ID, api_key) | |
image_url <- response[[asset_type]]$location | |
# download | |
message("Downloading...") | |
GET(image_url, | |
write_disk(file.path(fpath, glue::glue("{itemtype}_{item_ID}.tif"))), | |
overwrite = TRUE) | |
message("... done with image", glue::glue("{itemtype}_{item_ID}.tif")) | |
} | |
library(tidyverse) | |
library(httr) | |
library(sp) | |
library(raster) | |
library(rgdal) | |
# load the functionalities | |
source('src/planet_labs_api.R') | |
# YOUR API KEY FROM PLANET LABS | |
api_key <- "YOUR_PLANET_API_KEY" # keep secret! | |
# search assets | |
date_start <- "2010-07-01" | |
date_end <- "2018-08-01" | |
studysite <- readOGR("data/BE2300005-1 perimeter_WGS84.shp") | |
bbox_ss <- extent(bbox(studysite)) | |
response <- planet_search_asset(bbox_ss, date_end, date_start, | |
item_name = "PSOrthoTile", | |
api_key = api_key) | |
# create dataframe of assets properties and id | |
items <- map_df(response$features, ~.x$properties) %>% | |
mutate(item_id = map_chr(response$features, ~.x$id)) | |
#-------------- | |
# example case: | |
#-------------- | |
item_ID <- items %>% top_n(1) %>% pull(item_id) | |
itemtype <- "PSOrthoTile" | |
asset_type <- "visual" | |
planet_activate_asset(itemtype, item_ID, api_key, asset_type) | |
planet_download_asset(itemtype, item_ID, api_key, asset_type) | |
#------------------------ | |
# apply on list of assets | |
#------------------------ | |
# Read csv with ItemID | |
planet_items <- items %>% | |
select(item_type, item_id) %>% | |
head(2) # for the example, I'm just using 2 of them | |
# activate all assets | |
map2(planet_items$item_type, planet_items$item_id, | |
planet_activate_asset, api_key, asset_type) | |
# download all assets | |
map2(planet_items$item_type, planet_items$item_id, | |
planet_download_asset, api_key, asset_type) | |
acquired | anomalous_pixels | black_fill | cloud_cover | columns | epsg_code | grid_cell | ground_control | gsd | item_type | origin_x | origin_y | pixel_resolution | provider | published | rows | satellite_id | strip_id | sun_azimuth | sun_elevation | updated | usable_data | view_angle | item_id | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2018-07-25T10:07:58.892915Z | 0.14 | 0.3 | 0.136 | 8000 | 32631 | 3162616 | TRUE | 4 | PSOrthoTile | 523500 | 5664500 | 3.125 | planetscope | 2018-10-24T17:56:53Z | 8000 | 1105 | 1587476 | 137 | 52.4 | 2018-10-25T21:24:39Z | 0.56 | 0.1 | 1587476_3162616_2018-07-25_1105 | |
2018-07-25T10:07:55.647572Z | 0.15 | 0.07 | 0.153 | 8000 | 32631 | 3162716 | TRUE | 4 | PSOrthoTile | 523500 | 5688500 | 3.125 | planetscope | 2018-10-24T17:56:52Z | 8000 | 1105 | 1587476 | 137.3 | 52.3 | 2018-10-25T21:24:28Z | 0.77 | 0.1 | 1587476_3162716_2018-07-25_1105 | |
2018-05-11T10:03:29.86267Z | 0.01 | 0.48 | 0.009 | 8000 | 32631 | 3162716 | TRUE | 4 | PSOrthoTile | 523500 | 5688500 | 3.125 | planetscope | 2018-10-24T17:16:33Z | 8000 | 1105 | 1418103 | 140.3 | 51.3 | 2018-10-25T21:51:23Z | 0.51 | 0 | 1418103_3162716_2018-05-11_1105 | |
2018-07-26T10:15:05.89996Z | 0.02 | 0.24 | 0.02 | 8000 | 32631 | 3162616 | TRUE | 3.9 | PSOrthoTile | 523500 | 5664500 | 3.125 | planetscope | 2018-07-26T15:00:09Z | 8000 | 100c | 1589140 | 139.6 | 53 | 2018-07-27T06:28:57Z | 0.74 | 0.1 | 1589140_3162616_2018-07-26_100c | |
2018-07-26T10:15:02.734309Z | 0.02 | 0.05 | 0.019 | 8000 | 32631 | 3162716 | TRUE | 3.9 | PSOrthoTile | 523500 | 5688500 | 3.125 | planetscope | 2018-07-26T14:59:57Z | 8000 | 100c | 1589140 | 139.9 | 52.9 | 2018-07-27T06:28:50Z | 0.93 | 0.1 | 1589140_3162716_2018-07-26_100c | |
2018-07-25T10:14:34.614106Z | 0.01 | 0.17 | 0.008 | 8000 | 32631 | 3162616 | TRUE | 3.9 | PSOrthoTile | 523500 | 5664500 | 3.125 | planetscope | 2018-07-25T15:04:13Z | 8000 | 1033 | 1587321 | 139.5 | 53.2 | 2018-07-26T06:53:32Z | 0.82 | 1.5 | 1587321_3162616_2018-07-25_1033 |
@stijnvanhoey, please, I get a new API key (Planet support confirm that's my API key is OK), update the code and the problem continues to happen and my output is:
item_ID <- "1563545_2229401_2018-07-13_0f49"
item_ID
#[1] "1563545_2229401_2018-07-13_0f49"
itemtype <- "PSOrthoTile"
asset_type <- "analytic"
planet_get_item <- function(itemtype, item_ID, api_key) {
url <- glue::glue("https://api.planet.com/data/v1/item-types/{itemtype}/items/{item_ID}/assets/")
response <- GET(url,
add_headers(Authorization = planet_translate_key(api_key)),
config("location"))
return(content(response))
}
#planet_get_item(itemtype, item_ID, api_key)
planet_activate_asset(itemtype, item_ID, api_key, asset_type)
Response [https://api.planet.com/data/v1/assets/eyJpIjogIjE1NjM1NDVfMjIyOTQwMV8yMDE4LTA3LTEzXzBmNDkiLCAiYyI6ICJQU09ydGhvVGlsZSIsICJ0IjogImFuYWx5dGljIiwgImN0IjogIml0ZW0tdHlwZSJ9/activate]
Date: 2021-10-22 15:01
Status: 204
Content-Type: <unknown>
<EMPTY BODY>
planet_download_asset(itemtype, item_ID, api_key, asset_type)
Not yet activated, waiting...
Not yet activated, waiting...
Not yet activated, waiting...
Not yet activated, waiting...
Not yet activated, waiting...
Not yet activated, waiting...
@Leprechault It takes indeed a while, but I'm still able to download the data using the code, e.g. for the example from the gist:
item_ID <- "1587476_3162616_2018-07-25_1105"
itemtype <- "PSOrthoTile"
asset_type <- "visual"
planet_activate_asset(itemtype, item_ID, api_key, asset_type)
planet_download_asset(itemtype, item_ID, api_key, asset_type)
works, if a subfolder visual
does exists in the folder to write the data in. The activation took around 4 minutes for this example. This makes me think the code/API is still working fine and I would check at Planet why the activation of the item "1563545_2229401_2018-07-13_0f49" is taking so long (I tested for 10minutes without succes; but I did not get a time out)? Otherwise, maybe give https://github.com/bevingtona/planetR a try and check if the activation works using that R wrapper?
@Leprechault it's been a while since I last used it, but it seems that the API requests to check if a data site is already activated timeout. You could try with extending the timeout in the
GET
request, see https://gist.github.com/stijnvanhoey/f7522feec20de928801f31373f571008#file-planet_labs_api-r-L147-L149