Last active
October 25, 2021 14:39
-
-
Save stijnvanhoey/f7522feec20de928801f31373f571008 to your computer and use it in GitHub Desktop.
Activate and download assets from Planet Labs API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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")) | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
@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?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@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: