Skip to content

Commit b723c97

Browse files
Merge pull request planetlabs#220 from planetlabs/gee-integration-210
Google Earth Engine integration notebook
2 parents 95e1493 + 3b3d0d3 commit b723c97

File tree

1 file changed

+324
-0
lines changed

1 file changed

+324
-0
lines changed
Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Order and Delivery to Google Earth Engine\n",
8+
"\n",
9+
"In this notebook we're going to cover how to order data using the [Orders API](https://developers.planet.com/apis/orders/) and deliver it to [Google Earth Engine (GEE)](https://earthengine.google.com/) using [Planet’s GEE Delivery Integration](https://developers.planet.com/docs/integrations/gee/).\n",
10+
"\n",
11+
"This example demonstrates how to:\n",
12+
"1. Define the data to be ordered\n",
13+
"2. Build a cloud delivery configuration object (`delivery_config`), which tells the Orders API where to deliver the data\n",
14+
"3. Build an order request to be sent off to the Orders API, `iowa_order`\n",
15+
"4. Create the order and have it deliver to your GEE project\n",
16+
"\n",
17+
"**Prerequisites:** \n",
18+
"- [Planet's Python SDK 2.0](https://github.com/planetlabs/planet-client-python) installed and initialized in your environment. Please follow instructions in [our docs](https://planet-sdk-for-python-v2.readthedocs.io/en/latest/get-started/quick-start-guide/) to authenticate your account with Planet servers. (**This notebook is not compatible with earlier versions of Planet's Python SDK**)\n",
19+
"- An AOI - `iowa_aoi`\n",
20+
"- Item ID(s) - `iowa_images`\n",
21+
"- A GEE project with EE API enabled - `planet-devrel-dev`\n",
22+
"- A pre-existing GEE [ImageCollection](https://developers.google.com/earth-engine/guides/ic_creating) - `gee-integration-testing`\n",
23+
"- An account with a download quota. Not sure if you have download quota? Please [get in touch](https://www.planet.com/contact-sales/)."
24+
]
25+
},
26+
{
27+
"cell_type": "code",
28+
"execution_count": 1,
29+
"metadata": {},
30+
"outputs": [],
31+
"source": [
32+
"import planet"
33+
]
34+
},
35+
{
36+
"cell_type": "markdown",
37+
"metadata": {},
38+
"source": [
39+
"## Define data to be ordered"
40+
]
41+
},
42+
{
43+
"cell_type": "code",
44+
"execution_count": 2,
45+
"metadata": {},
46+
"outputs": [],
47+
"source": [
48+
"# The area of interest (AOI) defined as a polygon\n",
49+
"iowa_aoi = {\n",
50+
" \"type\":\n",
51+
" \"Polygon\",\n",
52+
" \"coordinates\": [[[-91.198465, 42.893071], [-91.121931, 42.893071],\n",
53+
" [-91.121931, 42.946205], [-91.198465, 42.946205],\n",
54+
" [-91.198465, 42.893071]]]\n",
55+
"}\n",
56+
"\n",
57+
"# The item IDs we wish to order\n",
58+
"iowa_images = ['20200925_161029_69_2223', '20200925_161027_48_2223']"
59+
]
60+
},
61+
{
62+
"cell_type": "markdown",
63+
"metadata": {},
64+
"source": [
65+
"## Define cloud delivery location\n",
66+
"This is the *key concept* of this notebook. Here, we are defining a cloud delivery configuration object, `cloud_config`, where we are defining the destination to be Google Earth Engine, in the project named `planet-devrel-dev`, in the ImageCollection named `gee-integration-testing`."
67+
]
68+
},
69+
{
70+
"cell_type": "code",
71+
"execution_count": 3,
72+
"metadata": {},
73+
"outputs": [],
74+
"source": [
75+
"# Google Earth Engine configuration\n",
76+
"cloud_config = planet.order_request.google_earth_engine(\n",
77+
" project='planet-devrel-dev', collection='gee-integration-testing')\n",
78+
"# Order delivery configuration\n",
79+
"delivery_config = planet.order_request.delivery(cloud_config=cloud_config)"
80+
]
81+
},
82+
{
83+
"cell_type": "markdown",
84+
"metadata": {},
85+
"source": [
86+
"## Build a simple order request\n",
87+
"Here we are building an order request, where we specify the products we wish to order. Spesifically, here we are requesting the IDs defined in `iowa_images`, as `analytic_udm2` assets, from the Planet Scope Scene product, `PSScene`."
88+
]
89+
},
90+
{
91+
"cell_type": "code",
92+
"execution_count": 4,
93+
"metadata": {},
94+
"outputs": [
95+
{
96+
"name": "stdout",
97+
"output_type": "stream",
98+
"text": [
99+
"{'name': 'iowa_order', 'products': [{'item_ids': ['20200925_161029_69_2223', '20200925_161027_48_2223'], 'item_type': 'PSScene', 'product_bundle': 'analytic_sr_udm2'}], 'delivery': {'google_earth_engine': {'project': 'planet-devrel-dev', 'collection': 'gee-integration-testing'}}}\n"
100+
]
101+
}
102+
],
103+
"source": [
104+
"# Product description for the order request\n",
105+
"data_products = [\n",
106+
" planet.order_request.product(item_ids=iowa_images,\n",
107+
" product_bundle='analytic_sr_udm2',\n",
108+
" item_type='PSScene')\n",
109+
"]\n",
110+
"\n",
111+
"# Build the order request\n",
112+
"iowa_order = planet.order_request.build_request(name='iowa_order',\n",
113+
" products=data_products,\n",
114+
" delivery=delivery_config)\n",
115+
"\n",
116+
"print(iowa_order)"
117+
]
118+
},
119+
{
120+
"cell_type": "markdown",
121+
"metadata": {},
122+
"source": [
123+
"## Create and deliver the order\n",
124+
"Define a function that will create an order and update you with its progress. In this case, since we specified the delivery destination to be Google Earth Engine with `delivery_config`, it will also wait for it to be delivered to your project."
125+
]
126+
},
127+
{
128+
"cell_type": "code",
129+
"execution_count": 5,
130+
"metadata": {},
131+
"outputs": [],
132+
"source": [
133+
"async def create_and_deliver_order(order_request, client):\n",
134+
" '''Create and deliver an order.\n",
135+
"\n",
136+
" Parameters:\n",
137+
" order_request: An order request\n",
138+
" client: An Order client object\n",
139+
" '''\n",
140+
" with planet.reporting.StateBar(state='creating') as reporter:\n",
141+
" # Place an order to the Orders API\n",
142+
" order = await client.create_order(order_request)\n",
143+
" reporter.update(state='created', order_id=order['id'])\n",
144+
" # Wait while the order is being completed\n",
145+
" await client.wait(order['id'],\n",
146+
" callback=reporter.update_state,\n",
147+
" max_attempts=0)\n",
148+
"\n",
149+
" # Grab the details of the orders\n",
150+
" order_details = await client.get_order(order_id=order['id'])\n",
151+
"\n",
152+
" return order_details"
153+
]
154+
},
155+
{
156+
"cell_type": "markdown",
157+
"metadata": {},
158+
"source": [
159+
"Create and deliver the order, `iowa_order`, to the GEE project, `planet-devrel-dev`, in the ImageCollection, `gee-integration-testing`."
160+
]
161+
},
162+
{
163+
"cell_type": "code",
164+
"execution_count": 6,
165+
"metadata": {},
166+
"outputs": [
167+
{
168+
"name": "stderr",
169+
"output_type": "stream",
170+
"text": [
171+
"54:18 - order befd89fa-d314-4194-9001-1ac656fc8d27 - state: success\n"
172+
]
173+
}
174+
],
175+
"source": [
176+
"async with planet.Session() as ps:\n",
177+
" # The Orders API client\n",
178+
" client = planet.OrdersClient(ps)\n",
179+
" # Create the order and deliver it to GEE\n",
180+
" order_details = await create_and_deliver_order(iowa_order, client)"
181+
]
182+
},
183+
{
184+
"cell_type": "markdown",
185+
"metadata": {},
186+
"source": [
187+
"Display the results for the first item data in the order."
188+
]
189+
},
190+
{
191+
"cell_type": "code",
192+
"execution_count": 7,
193+
"metadata": {},
194+
"outputs": [
195+
{
196+
"name": "stdout",
197+
"output_type": "stream",
198+
"text": [
199+
"{'delivery': 'success', 'expires_at': '2022-12-01T00:37:11.420Z', 'location': 'https://api.planet.com/compute/ops/download/?token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Njk4NTUwMzEsInN1YiI6IllzV0ZqTDE4c04zeXYyZE1HQmNjeEVjeDFCQ0ZHeVgrUmlZWG9UYkU1Q3lFL2lMblE2VHhVMzBMc3JuczR6aEI5TUZvTmVTc0pHUFEzQ3lkc1hRMDVRPT0iLCJ0b2tlbl90eXBlIjoiZG93bmxvYWQtYXNzZXQtc3RhY2siLCJhb2kiOiIiLCJhc3NldHMiOlt7Iml0ZW1fdHlwZSI6IiIsImFzc2V0X3R5cGUiOiIiLCJpdGVtX2lkIjoiIn1dLCJ1cmwiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vY29tcHV0ZS1vcmRlcnMtbGl2ZS8yMDIwMDkyNV8xNjEwMjlfNjlfMjIyM18zQl9BbmFseXRpY01TX1NSLnRpZj9YLUdvb2ctQWxnb3JpdGhtPUdPT0c0LVJTQS1TSEEyNTZcdTAwMjZYLUdvb2ctQ3JlZGVudGlhbD1jb21wdXRlLWdjcy1zdmNhY2MlNDBwbGFuZXQtY29tcHV0ZS1wcm9kLmlhbS5nc2VydmljZWFjY291bnQuY29tJTJGMjAyMjExMzAlMkZhdXRvJTJGc3RvcmFnZSUyRmdvb2c0X3JlcXVlc3RcdTAwMjZYLUdvb2ctRGF0ZT0yMDIyMTEzMFQwMDM3MTFaXHUwMDI2WC1Hb29nLUV4cGlyZXM9ODYzOTlcdTAwMjZYLUdvb2ctU2lnbmF0dXJlPWE2OWQxNjE4ZGMwZDk0ODY3Y2I2N2EzY2U3MGUyNTU0M2VhODMyMmU2ZTFmZjFjMjE1NWVlZGU4OGQyYTgyMWVhMWU2MGEzNzRlYWQ5MWVhYjQwMzQ4NmQ4NzNjNzJhZjEzYWEwOTI4ZTVmMmFkNjhlYzU2M2UyZGRiZWQ3ZWZkZWFjOGUyNGJiZDM5MzRmOWFkMTNlMmM5ZjRiMmU0NmUxNjkyYzYzMWY4ZWM4Mjc1ZWRmYzg3ZjE0ZDkxMmNmYjUxMDE2N2IwM2FhMTY5MDRjY2YwNTY1ZjU4MDMzYTg3N2Y1Mzg3ZjI1YjU5ZGFjMTg4MDM1MWI3NGFlMmQyYTgxMWVhNjQ2ZDcwNGIyNTZkZmY5MGIxNWVmYTc2MTBlZWZlMjExMDI4ZTQ0ZDc1MjYxOGY4YzM1MzZkYWFkNmQ4MjJkNDVkZjNiMDNkZGUxOWQ2MDQwNjEzNzA0ZDQ3MWNkOGM5ZGQ1MTFlZWRjYTNjYzJjNWQyZDU4YWQ4YzcwZjhjNGZjOWFjYzBhNmY0NjkwY2I4ZTY0MTY0YTc3Yzc1NjZkMWY1NmI0NWEwOWU5YjY2N2QwYTJmYTM0NmFmYTYxMDQxN2NjODg5MWVlODkzNDhlMDlhNWFiNGQ3MmM0YTA2ZTZiNTk0NTMzMWVlYWQwYjJhNmUxMTFjYjJjMzYwXHUwMDI2WC1Hb29nLVNpZ25lZEhlYWRlcnM9aG9zdCIsInNvdXJjZSI6Ik9yZGVycyBTZXJ2aWNlIn0.FnaAXSRd_oeayLitsmws_dF6Uw-c_17fSSzrQfmAG1SzE7O_T4a1QKh8kAR8ijew0H5URUQm75qRLY6Swt4crQ', 'name': '20200925_161029_69_2223_3B_AnalyticMS_SR.tif'}\n"
200+
]
201+
}
202+
],
203+
"source": [
204+
"print(order_details['_links']['results'][0])"
205+
]
206+
},
207+
{
208+
"cell_type": "markdown",
209+
"metadata": {},
210+
"source": [
211+
"## Build an order request with clipping and harmonization applied\n",
212+
"Here we are building an order request similar to the one above, but with [clipping](https://developers.planet.com/apis/orders/tools/#clip) and [harmonization](https://developers.planet.com/apis/orders/tools/#harmonization) applied. Namely, we are asking the Orders API to clip our images to the AOI, as defined by `iowa_aoi`, and radiometrically harmonizing the imagery with Sentinel-2's sensor. It's important to note that although the Orders API supports more tools, clipping and harmonization are the only two that are currently supported with GEE integration."
213+
]
214+
},
215+
{
216+
"cell_type": "code",
217+
"execution_count": 8,
218+
"metadata": {},
219+
"outputs": [
220+
{
221+
"name": "stdout",
222+
"output_type": "stream",
223+
"text": [
224+
"{'name': 'iowa_order', 'products': [{'item_ids': ['20200925_161029_69_2223', '20200925_161027_48_2223'], 'item_type': 'PSScene', 'product_bundle': 'analytic_sr_udm2'}], 'delivery': {'google_earth_engine': {'project': 'planet-devrel-dev', 'collection': 'gee-integration-testing'}}, 'tools': [{'clip': {'aoi': {'type': 'Polygon', 'coordinates': [[[-91.198465, 42.893071], [-91.121931, 42.893071], [-91.121931, 42.946205], [-91.198465, 42.946205], [-91.198465, 42.893071]]]}}}, {'harmonize': {'target_sensor': 'Sentinel-2'}}]}\n"
225+
]
226+
}
227+
],
228+
"source": [
229+
"# Clip images to the AOI's perimeter and harmonize the data with Dove Classic\n",
230+
"tools = [\n",
231+
" planet.order_request.clip_tool(iowa_aoi),\n",
232+
" planet.order_request.harmonize_tool('Sentinel-2')\n",
233+
"]\n",
234+
"\n",
235+
"# Build the order request\n",
236+
"iowa_order = planet.order_request.build_request(name='iowa_order',\n",
237+
" products=data_products,\n",
238+
" delivery=delivery_config,\n",
239+
" tools=tools)\n",
240+
"\n",
241+
"print(iowa_order)"
242+
]
243+
},
244+
{
245+
"cell_type": "markdown",
246+
"metadata": {},
247+
"source": [
248+
"Create and deliver the clipped and harmonized data to `planet-devrel-dev` in `gee-integration-testing`."
249+
]
250+
},
251+
{
252+
"cell_type": "code",
253+
"execution_count": 9,
254+
"metadata": {},
255+
"outputs": [
256+
{
257+
"name": "stderr",
258+
"output_type": "stream",
259+
"text": [
260+
"08:16 - order 37d82131-6a36-4b5c-a651-df30ca8ef945 - state: success\n"
261+
]
262+
}
263+
],
264+
"source": [
265+
"async with planet.Session() as ps:\n",
266+
" # The Orders API client\n",
267+
" client = planet.OrdersClient(ps)\n",
268+
" # Create the order and deliver it to GEE\n",
269+
" order_details = await create_and_deliver_order(iowa_order, client)"
270+
]
271+
},
272+
{
273+
"cell_type": "markdown",
274+
"metadata": {},
275+
"source": [
276+
"Display the results for the first item data in the order."
277+
]
278+
},
279+
{
280+
"cell_type": "code",
281+
"execution_count": 10,
282+
"metadata": {},
283+
"outputs": [
284+
{
285+
"name": "stdout",
286+
"output_type": "stream",
287+
"text": [
288+
"{'delivery': 'success', 'expires_at': '2022-12-01T01:05:06.668Z', 'location': 'https://api.planet.com/compute/ops/download/?token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Njk4NTY3MDYsInN1YiI6IjdyZW9xVXRQaUQ5WVhaZkpwRU1wUkZQZVVBeFVzcDU2c3NaSnBTN0dMV3RZcWtZSFZJYWhwZXRISER6MHgxZTBTSWVYQk9CWjYrUXRDeDZFYnREVFlRPT0iLCJ0b2tlbl90eXBlIjoiZG93bmxvYWQtYXNzZXQtc3RhY2siLCJhb2kiOiIiLCJhc3NldHMiOlt7Iml0ZW1fdHlwZSI6IiIsImFzc2V0X3R5cGUiOiIiLCJpdGVtX2lkIjoiIn1dLCJ1cmwiOiJodHRwczovL3N0b3JhZ2UuZ29vZ2xlYXBpcy5jb20vY29tcHV0ZS1vcmRlcnMtbGl2ZS8yMDIwMDkyNV8xNjEwMjlfNjlfMjIyM18zQl91ZG0yX2NsaXAudGlmP1gtR29vZy1BbGdvcml0aG09R09PRzQtUlNBLVNIQTI1Nlx1MDAyNlgtR29vZy1DcmVkZW50aWFsPWNvbXB1dGUtZ2NzLXN2Y2FjYyU0MHBsYW5ldC1jb21wdXRlLXByb2QuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20lMkYyMDIyMTEzMCUyRmF1dG8lMkZzdG9yYWdlJTJGZ29vZzRfcmVxdWVzdFx1MDAyNlgtR29vZy1EYXRlPTIwMjIxMTMwVDAxMDUwNlpcdTAwMjZYLUdvb2ctRXhwaXJlcz04NjM5OVx1MDAyNlgtR29vZy1TaWduYXR1cmU9YTExNGE3Mjk3ZTNhZmEwYzRmNmU2ZDQxYjRkNzgxMWQ1YTkwNTcxNjI0MmMxMDUzZWI2OGYxZjE3NjhiY2E3NjNlNzg5ZmViZjAwMzYxYzI1NjgxN2FjMDU2MWY5NTQxMWU0OTI1MmEyMzBkZDQyNDUxNjcyYThlOWRhZDFmNDQwODE1NDVjZDlkYzYxNzI5MTFjZTAyYjkyMmE1OGM3OTJlYWI0NzdlMjY5MjU3ZTM1MWM3ZWVlM2Q0YWI5MjdkZjFjNjg0YWVmM2Q0OTc0NGEzODg1MWRhOTcxMTc2MTZlYjM3ZWM1NGZjMWE4MGIwZTU5MGJkNGUzZWFiMzEyYTY5MmIwZTg2ZmY0OWY0MzYxMjJmODBiZDFlYjIwYTgxZDdhYzMzYTY5YmY3OGExYmIwOWIzZGQ1YTE3MGYyYjE1YzJiZjM0MDk0NjJlY2IwYjIyNThhMjZkY2FkODlkMGExNDkyY2I5MGI1ZjViMmYwN2YyM2Q4MTY0YTljMDRhN2Q4ZWY0M2EzNTJjYTRlN2YwZDQ3MWYzNTZhNjQyMTU2Yzg1NTY3NDY0MDQ3MDUwZDc0NDgyMmU1MjgxZjkzZTM5ZWQ3NmU5YzdlYWZiZmVlY2QyMDgyNTE0MmQ0YmQ2OGRjMmZhNjc1NzNlZmU2ODc0ODk4M2I1YzZjM2MwNTNcdTAwMjZYLUdvb2ctU2lnbmVkSGVhZGVycz1ob3N0Iiwic291cmNlIjoiT3JkZXJzIFNlcnZpY2UifQ.cohH8ih049_CQF3NIEy-yAqAt6Vc_taEnXK5gn4Hwe6W3D3RqJAgoxyC7ZG3UJW0zmCdnq0653JKeAyScK94JQ', 'name': '20200925_161029_69_2223_3B_udm2_clip.tif'}\n"
289+
]
290+
}
291+
],
292+
"source": [
293+
"print(order_details['_links']['results'][0])"
294+
]
295+
}
296+
],
297+
"metadata": {
298+
"kernelspec": {
299+
"display_name": "Python 3.9.6 64-bit ('3.9.6')",
300+
"language": "python",
301+
"name": "python3"
302+
},
303+
"language_info": {
304+
"codemirror_mode": {
305+
"name": "ipython",
306+
"version": 3
307+
},
308+
"file_extension": ".py",
309+
"mimetype": "text/x-python",
310+
"name": "python",
311+
"nbconvert_exporter": "python",
312+
"pygments_lexer": "ipython3",
313+
"version": "3.9.6"
314+
},
315+
"orig_nbformat": 4,
316+
"vscode": {
317+
"interpreter": {
318+
"hash": "1bedda3fce59fa236ffac8164c02851c562f094c6d8f95a48784416ec3bbb813"
319+
}
320+
}
321+
},
322+
"nbformat": 4,
323+
"nbformat_minor": 2
324+
}

0 commit comments

Comments
 (0)