Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 143 additions & 14 deletions docs/source/cli/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ meant to be easily interoperable with other tools, e.g. `jq
<https://stedolan.github.io/jq/>`_. For example, we could output just the name
and date range of each mosaic with::

planet mosaics list | jq -r '.mosaics[] | [.name, .first_acquired, .last_acquired] | @tsv'
planet mosaics list | jq -r '.mosaics[] | [.name, .first_acquired, .last_acquired] | @tsv'

Get basic information for a specific mosaic::

Expand All @@ -73,7 +73,7 @@ list all quads. Keep in mind that there may be millions for a global mosaic.)::
planet mosaics search global_monthly_2018_09_mosaic --limit=10

Find all quads inside a particular area of interest::

planet mosaics search global_monthly_2018_09_mosaic --bbox=-95.5,29.6,-95.3,29.8

Note that the format of ``--bbox`` is "xmin,ymin,xmax,ymax", so longitude comes
Expand Down Expand Up @@ -193,7 +193,7 @@ Orders Examples
-----------------

List all recent orders for the authenticated user::

planet orders list

Get the status of a single order by Order ID::
Expand All @@ -203,17 +203,17 @@ Get the status of a single order by Order ID::
Note that you may want to parse the JSON that's output into a more human
readable format. The cli does not directly provide options for this, but is
meant to be easily interoperable with other tools, e.g. `jq
<https://stedolan.github.io/jq/>`_.
<https://stedolan.github.io/jq/>`_.

To cancel a running order by given order ID::

planet orders cancel <order ID>

To download an order to your local machine::
To download an order to your local machine::

planet orders download <order ID>
planet orders download <order ID>

Optionally, a `--dest <path to destination>` flag may be specified too.
Optionally, a `--dest <path to destination>` flag may be specified too.

Creating an Order
..................
Expand All @@ -227,19 +227,148 @@ The minimal command to create a simple order looks something like::
If no toolchain or delivery details are specified, a basic order with download
delivery will be placed for the requested bundle including the item id(s) specified.

Additionally, optional toolchain & delivery details can be provided on the
command line, e.g.:::
In the place of `--id`, you can insert a Data search string. This will populate
the list of IDs from a search. For example::

planet orders create --name "my order" \
--ids_from_search $'--item-type PSScene3Band --date acquired gt 2017-02-14 --date acquired lt 2017-03-14 --limit 6 --geom \'{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-116.40701293945311,
43.061363052307875
],
[
-116.4451217651367,
43.05032512283074
],
[
-116.4320755004883,
43.017450433440814
],
[
-116.37508392333984,
43.01092359150748
],
[
-116.3393783569336,
43.03677585761058
],
[
-116.35894775390624,
43.06186472916744
],
[
-116.40701293945311,
43.061363052307875
]
]
]
}
}
]
}\'' \
--bundle visual \
--item-type psscene3band \
--zip bundle --email \
--clip '{
"type": "Polygon",
"coordinates": [
[
[
-116.40701293945311,
43.061363052307875
],
[
-116.4451217651367,
43.05032512283074
],
[
-116.4320755004883,
43.017450433440814
],
[
-116.37508392333984,
43.01092359150748
],
[
-116.3393783569336,
43.03677585761058
],
[
-116.35894775390624,
43.06186472916744
],
[
-116.40701293945311,
43.061363052307875
]
]
]
}'

Note that `--ids_from_search` is passed as a string value.

Additionally, optional toolchain & delivery details can be provided on the command line, e.g.::

planet orders create --name "my order" \
--id 20151119_025740_0c74,20151119_025741_0c74 \
--bundle visual --item-type psscene3band --zip order --email

This places the same order as above, and will also provide a .zip archive
download link for the full order, as well as email notification.
download link for the full order, as well as email notification. If you change
`--zip order` to `--zip bundle`, the individual bundles will be zipped rather
than the full order.

You can also clip the items in an order by providing a GeoJSON AOI Geometry
with the `--clip` parameter::

planet orders create --name "my order" ... \
--clip '{
"type": "Polygon",
"coordinates": [
[
[
-163.828125,
-44.59046718130883
],
[
181.7578125,
-44.59046718130883
],
[
181.7578125,
78.42019327591201
],
[
-163.828125,
78.42019327591201
],
[
-163.828125,
-44.59046718130883
]
]
]
}'

Alternatively, you can specify a file that contains your GeoJSON AOI using the
`@` notation, e.g. `--clip @path/to/aoi.json`.

It should be noted that if the clip AOI you specify does not intersect with the
items in `--id` or `--ids_from_search` you may end up with a zero result order.
If some of the items intersect, you will receive those items.

The Orders API allows you to specify a toolchain of operations to be performed
on your order prior to download. To read more about tools & toolchains, visit
`the docs <https://developers.planet.com/docs/orders/tools-toolchains/>`_ .
`the docs <https://developers.planet.com/docs/orders/tools-toolchains/>`_ .

To add tool operations to your order, use the `--tools` option to specify a
json-formatted file containing an array (list) of the desired tools an their
Expand Down Expand Up @@ -271,16 +400,16 @@ order, you would create a `.json` file similar to the following::
"name_template": "C1232_30_30_{tilex:04d}_{tiley:04d}"
}
}
]
]


Similarly, you can also specify cloud delivery options on an order create
command with the `--cloudconfig <path to json file>` option. In this case, the
json file should contain the required credentials for your desired cloud
storage destination, for example::

{
"amazon_s3":{
{
"amazon_s3":{
"bucket":"foo-bucket",
"aws_region":"us-east-2",
"aws_access_key_id":"",
Expand Down
25 changes: 25 additions & 0 deletions planet/scripts/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,28 @@ def convert(self, val, param, ctx):
for date in dates:
if date != '..' and strp_lenient(date) is None:
raise click.BadParameter('Invalid date: {}'.format(date))


class ClipAOI(click.ParamType):
name = 'clip'

def convert(self, val, param, ctx):
val = read(val)
if not val:
return []
try:
json.loads(val)
except ValueError:
raise click.BadParameter('invalid GeoJSON')
return val


class RequiredUnless(click.Option):
def __init__(self, *args, **kwargs):
self.this_opt_exists = kwargs.pop('this_opt_exists')
super(RequiredUnless, self).__init__(*args, **kwargs)

def handle_parse_result(self, ctx, opts, args):
if self.name not in opts and self.this_opt_exists not in opts:
raise click.UsageError('{} is required.'.format(self.name))
return super(RequiredUnless, self).handle_parse_result(ctx, opts, args)
36 changes: 25 additions & 11 deletions planet/scripts/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ def create_order_request(**kwargs):
email = kwargs.get('email')
archive = kwargs.get('zip')
config = kwargs.get('cloudconfig')
clip = kwargs.get('clip')
tools = kwargs.get('tools')

request = {'name': kwargs.get('name'),
Expand All @@ -108,30 +109,35 @@ def create_order_request(**kwargs):
'product_bundle': bundle}
],
'tools': [
],
'delivery': {
},
'notifications': {
],
'delivery': {
},
'notifications': {
'email': email
},
}
},
}

if archive is not None:
request["delivery"]["archive_filename"] = "{{name}}_{{order_id}}.zip"
request["delivery"]["archive_type"] = "zip"

# TODO verify this is correct req format for order vs bundle zip
if archive == "bundle":
# If single_archive is not set, each bundle will be zipped, as opposed
# to the entire order.
if archive == "order":
request["delivery"]["single_archive"] = True

if config:
with open(config, 'r') as f:
conf = json.load(f)
request["delivery"].update(conf)

# TODO determine reasonable interfaces for SOME tools via CLI;
# e.g., clip via provided geojson AOI
# for now we can punt by pointing users to doc examples for copy-pasting
# NOTE clip is the only tool that currently can be specified via CLI param.
# A full tool chain can be specified via JSON file, so that will overwrite
# clip if both are present. TODO add other common tools as params.
if clip and not tools:
toolchain = [{'clip': {'aoi': json.loads(clip)}}]
request['tools'].extend(toolchain)

if tools:
with open(tools, 'r') as f:
toolchain = json.load(f)
Expand Down Expand Up @@ -346,3 +352,11 @@ def downloader_output(dl, disable_ansi=False):
if termui.WIN and not disable_ansi:
logging.getLogger('').setLevel(logging.INFO)
return Output(thread, dl)


def ids_from_search_response(resp):
ret = []
r = json.loads(resp)
for feature in r['features']:
ret.append(feature['id'])
return ','.join(ret)
Loading