Search and Download¶
This example notebook walks through the steps for searching and downloading PlanetScope imagery using the planetsca library.
You will need a user account with Planet, and your own API key to use these functions.
[1]:
import planetsca as ps
/home/jovyan/envs/planetenv/lib/python3.9/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
[2]:
api_key = "YOUR_API_KEY_HERE" # provide you Planet API key here
Searching for Planet imagery¶
Set up a filter to search a specific time range and region, and to avoid cloudy images:
[3]:
# filter images acquired in a certain date range
date_range_filter = ps.search.make_date_range_filter(
"2024-01-15T00:00:00.000Z", "2024-01-31T00:00:00.000Z"
)
There are two options for specifying a region to search: creating a “geometry filter” from lat and lon bounding coordinates, or creating a “geometry filter” from a geojson file.
[4]:
# Example for defining an area of interest from bounds
minLon = -105.88
minLat = 40.51
maxLon = -105.87
maxLat = 40.52
# make a geometry filter with these bounding coordinates
geometry_filter = ps.search.make_geometry_filter_from_bounds(
[minLon, minLat, maxLon, maxLat]
)
# Alternatively, define area of interest from a geojson file
# geometry_filter = ps.search.make_geometry_filter_from_geojson('my_study_area.geojson')
Add a cloud cover percentage filter
[5]:
cloud_filter = ps.search.make_cloud_cover_filter(
0.05
) # filter any images which are more than 5% clouds
Finally, create a filter that combines our geometry, date, and cloud filters
[6]:
filter = ps.search.combine_filters([date_range_filter, geometry_filter, cloud_filter])
Submit our search to the Planet API. This returns a geopandas.GeoDataFrame with information about the images that match our filter criteria
[7]:
search_results_gdf = ps.search.search(api_key, filter)
Search returned 8 items.
[8]:
search_results_gdf
[8]:
geometry | acquired | anomalous_pixels | clear_confidence_percent | clear_percent | cloud_cover | cloud_percent | ground_control | gsd | heavy_haze_percent | ... | strip_id | sun_azimuth | sun_elevation | updated | view_angle | visible_confidence_percent | visible_percent | intersection_area | overlap_percentage | id | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | POLYGON ((-106.19821 40.69052, -106.24418 40.5... | 2024-01-30T17:48:24.24349Z | 0 | 66 | 14 | 0.00 | 0 | True | 3.5 | 0 | ... | 7075747 | 156.3 | 28.4 | 2024-02-01T03:58:16Z | 5.0 | 65 | 100 | 0.000051 | 50.644997 | 20240130_174824_24_2484 |
1 | POLYGON ((-105.94697 40.5751, -105.99321 40.41... | 2024-01-27T17:49:51.954811Z | 0 | 65 | 29 | 0.01 | 1 | True | 3.5 | 0 | ... | 7068597 | 157.0 | 27.9 | 2024-01-28T06:11:48Z | 2.0 | 61 | 99 | 0.000100 | 100.000000 | 20240127_174951_95_247d |
2 | POLYGON ((-105.88645 40.55067, -105.93283 40.3... | 2024-01-27T17:42:51.03811Z | 0 | 64 | 29 | 0.03 | 3 | True | 3.6 | 0 | ... | 7068561 | 155.6 | 27.5 | 2024-01-28T06:09:20Z | 5.0 | 60 | 97 | 0.000100 | 100.000000 | 20240127_174251_03_227a |
3 | POLYGON ((-105.85123 40.6801, -105.89698 40.51... | 2024-01-27T17:42:48.998661Z | 0 | 63 | 23 | 0.00 | 0 | True | 3.6 | 0 | ... | 7068561 | 155.7 | 27.4 | 2024-01-28T06:09:20Z | 5.0 | 59 | 100 | 0.000100 | 100.000000 | 20240127_174248_99_227a |
4 | POLYGON ((-106.1921 40.68607, -106.24563 40.50... | 2024-01-23T17:07:24.191323Z | 0 | 56 | 17 | 0.03 | 3 | True | 3.9 | 0 | ... | 7060077 | 146.6 | 22.8 | 2024-01-24T06:13:56Z | 4.0 | 58 | 97 | 0.000100 | 100.000000 | 20240123_170724_19_24bc |
5 | POLYGON ((-106.03646 40.70049, -106.09005 40.5... | 2024-01-16T17:07:00.243012Z | 0 | 40 | 1 | 0.03 | 3 | True | 3.9 | 0 | ... | 7045035 | 147.8 | 21.6 | 2024-01-17T09:58:34Z | 5.0 | 56 | 97 | 0.000100 | 100.000000 | 20240116_170700_24_24b0 |
6 | POLYGON ((-105.84943 40.62474, -105.89752 40.4... | 2024-01-16T17:49:47.733879Z | 0 | 47 | 12 | 0.04 | 4 | True | 3.5 | 0 | ... | 7045173 | 158.1 | 25.5 | 2024-01-17T05:31:17Z | 5.0 | 54 | 96 | 0.000100 | 100.000000 | 20240116_174947_73_2483 |
7 | POLYGON ((-105.8839 40.65978, -105.93455 40.47... | 2024-01-16T17:01:56.418635Z | 0 | 50 | 6 | 0.00 | 0 | True | 3.9 | 0 | ... | 7045016 | 147.5 | 21.7 | 2024-01-17T05:37:04Z | 3.5 | 53 | 100 | 0.000100 | 100.000000 | 20240116_170156_41_24c1 |
8 rows × 32 columns
Download Planet imagery¶
Now that we’ve found some images we’re interested in, we can send a request to order and download the images.
But first, perhaps we’d like to exclude images that overlap our region of interest by less than 50%. We can do that with the following:
[9]:
search_results_gdf.drop(
search_results_gdf[search_results_gdf.overlap_percentage < 50].index, inplace=True
)
[10]:
search_results_gdf
[10]:
geometry | acquired | anomalous_pixels | clear_confidence_percent | clear_percent | cloud_cover | cloud_percent | ground_control | gsd | heavy_haze_percent | ... | strip_id | sun_azimuth | sun_elevation | updated | view_angle | visible_confidence_percent | visible_percent | intersection_area | overlap_percentage | id | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | POLYGON ((-106.19821 40.69052, -106.24418 40.5... | 2024-01-30T17:48:24.24349Z | 0 | 66 | 14 | 0.00 | 0 | True | 3.5 | 0 | ... | 7075747 | 156.3 | 28.4 | 2024-02-01T03:58:16Z | 5.0 | 65 | 100 | 0.000051 | 50.644997 | 20240130_174824_24_2484 |
1 | POLYGON ((-105.94697 40.5751, -105.99321 40.41... | 2024-01-27T17:49:51.954811Z | 0 | 65 | 29 | 0.01 | 1 | True | 3.5 | 0 | ... | 7068597 | 157.0 | 27.9 | 2024-01-28T06:11:48Z | 2.0 | 61 | 99 | 0.000100 | 100.000000 | 20240127_174951_95_247d |
2 | POLYGON ((-105.88645 40.55067, -105.93283 40.3... | 2024-01-27T17:42:51.03811Z | 0 | 64 | 29 | 0.03 | 3 | True | 3.6 | 0 | ... | 7068561 | 155.6 | 27.5 | 2024-01-28T06:09:20Z | 5.0 | 60 | 97 | 0.000100 | 100.000000 | 20240127_174251_03_227a |
3 | POLYGON ((-105.85123 40.6801, -105.89698 40.51... | 2024-01-27T17:42:48.998661Z | 0 | 63 | 23 | 0.00 | 0 | True | 3.6 | 0 | ... | 7068561 | 155.7 | 27.4 | 2024-01-28T06:09:20Z | 5.0 | 59 | 100 | 0.000100 | 100.000000 | 20240127_174248_99_227a |
4 | POLYGON ((-106.1921 40.68607, -106.24563 40.50... | 2024-01-23T17:07:24.191323Z | 0 | 56 | 17 | 0.03 | 3 | True | 3.9 | 0 | ... | 7060077 | 146.6 | 22.8 | 2024-01-24T06:13:56Z | 4.0 | 58 | 97 | 0.000100 | 100.000000 | 20240123_170724_19_24bc |
5 | POLYGON ((-106.03646 40.70049, -106.09005 40.5... | 2024-01-16T17:07:00.243012Z | 0 | 40 | 1 | 0.03 | 3 | True | 3.9 | 0 | ... | 7045035 | 147.8 | 21.6 | 2024-01-17T09:58:34Z | 5.0 | 56 | 97 | 0.000100 | 100.000000 | 20240116_170700_24_24b0 |
6 | POLYGON ((-105.84943 40.62474, -105.89752 40.4... | 2024-01-16T17:49:47.733879Z | 0 | 47 | 12 | 0.04 | 4 | True | 3.5 | 0 | ... | 7045173 | 158.1 | 25.5 | 2024-01-17T05:31:17Z | 5.0 | 54 | 96 | 0.000100 | 100.000000 | 20240116_174947_73_2483 |
7 | POLYGON ((-105.8839 40.65978, -105.93455 40.47... | 2024-01-16T17:01:56.418635Z | 0 | 50 | 6 | 0.00 | 0 | True | 3.9 | 0 | ... | 7045016 | 147.5 | 21.7 | 2024-01-17T05:37:04Z | 3.5 | 53 | 100 | 0.000100 | 100.000000 | 20240116_170156_41_24c1 |
8 rows × 32 columns
We can also save the results of this search to a csv file for later reference.
[12]:
search_results_gdf.to_csv("./example_images/my_images.csv")
To submit an order to the Planet API for the images we want, we will need to grab the item IDs from one column in the search results GeoDataFrame.
[13]:
id_list = search_results_gdf.id.to_list() # get item IDs as a list
id_list
[13]:
['20240130_174824_24_2484',
'20240127_174951_95_247d',
'20240127_174251_03_227a',
'20240127_174248_99_227a',
'20240123_170724_19_24bc',
'20240116_170700_24_24b0',
'20240116_174947_73_2483',
'20240116_170156_41_24c1']
Now, submit the order:
[14]:
order_url = ps.download.order(api_key, id_list, filter)
Submitted a total of 8 image ids: accepted a total of 8 ids
Order URL: https://api.planet.com/compute/ops/orders/v2/6ac34a8c-a2a3-453b-88d4-d9679e0f4087
The order_url
returned by this function is where we’ll download our images from.
The download function below will try to download the images, but if they’re not yet ready, it will wait 60 seconds before tyring again. It can take about 3-5 minutes for an order of about 10 images to be prepared before being available for download.
[15]:
# specify the directory you'd like to save your downloaded images to
out_dirpath = "./example_images"
ps.download.download(api_key, order_url, out_dirpath="./example_images")
Attempting to download
data not ready yet, this was attempt number 1
will automatically try again in 60 seconds
data not ready yet, this was attempt number 2
will automatically try again in 60 seconds
data not ready yet, this was attempt number 3
will automatically try again in 60 seconds
data not ready yet, this was attempt number 4
will automatically try again in 60 seconds
data not ready yet, this was attempt number 5
will automatically try again in 60 seconds
data not ready yet, this was attempt number 6
will automatically try again in 60 seconds
data not ready yet, this was attempt number 7
will automatically try again in 60 seconds
data not ready yet, this was attempt number 8
will automatically try again in 60 seconds
12 items to download
downloading 6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_174947_73_2483_metadata.json to example_images/6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_174947_73_2483_metadata.json
downloading 6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_174947_73_2483_3B_udm2_clip.tif to example_images/6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_174947_73_2483_3B_udm2_clip.tif
downloading 6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_174947_73_2483_3B_AnalyticMS_metadata_clip.xml to example_images/6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_174947_73_2483_3B_AnalyticMS_metadata_clip.xml
downloading 6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_174947_73_2483_3B_AnalyticMS_SR_clip.tif to example_images/6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_174947_73_2483_3B_AnalyticMS_SR_clip.tif
downloading 6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_170156_41_24c1_metadata.json to example_images/6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_170156_41_24c1_metadata.json
downloading 6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_170156_41_24c1_3B_udm2_clip.tif to example_images/6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_170156_41_24c1_3B_udm2_clip.tif
downloading 6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_170156_41_24c1_3B_AnalyticMS_metadata_clip.xml to example_images/6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_170156_41_24c1_3B_AnalyticMS_metadata_clip.xml
downloading 6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_170156_41_24c1_3B_AnalyticMS_SR_clip.tif to example_images/6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240116_170156_41_24c1_3B_AnalyticMS_SR_clip.tif
downloading 6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240123_170724_19_24bc_metadata.json to example_images/6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240123_170724_19_24bc_metadata.json
downloading 6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240123_170724_19_24bc_3B_udm2_clip.tif to example_images/6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240123_170724_19_24bc_3B_udm2_clip.tif
downloading 6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240123_170724_19_24bc_3B_AnalyticMS_metadata_clip.xml to example_images/6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240123_170724_19_24bc_3B_AnalyticMS_metadata_clip.xml
downloading 6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240123_170724_19_24bc_3B_AnalyticMS_SR_clip.tif to example_images/6ac34a8c-a2a3-453b-88d4-d9679e0f4087/PSScene/20240123_170724_19_24bc_3B_AnalyticMS_SR_clip.tif
Completed downloads
[ ]: