Skip to content

Commit c28285b

Browse files
authored
Merge pull request #897 from planetlabs/rc3dev-fixes
merge rc3dev-fixes into main and continue dev in main so docs can be built
2 parents d95853c + 878a1a5 commit c28285b

26 files changed

+320
-197
lines changed

CHANGES.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2.0.0-rc.3 (TBD)
2+
3+
Changed:
4+
- Session class unit tests are marked to be run within an event loop and are
5+
no longer skipped (#881).
6+
17
2.0.0-rc.2 (2023-03-15)
28

39
Added:

docs/cli/cli-intro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ represent GeoJSON features, the JSON blob is a GeoJSON FeatureCollection.
173173
Otherwise, the JSON blob is a list of the individual results.
174174

175175
```console
176-
$ planet data search PSScene | planet collect -
176+
planet data search PSScene | planet collect -
177177
```
178178

179179
This gives you a fully compliant GeoJSON FeatureCollection, which is

docs/cli/cli-orders.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ You can also filter orders by their `state`, which can be useful to just see ord
3636
progress:
3737

3838
```console
39-
planet orders --state running
39+
planet orders list --state running
4040
```
4141

4242
The other options are queued, failed, success, partial and cancelled.
@@ -100,7 +100,7 @@ To create an order you need a name, a [bundle](https://developers.planet.com/api
100100
First lets get the ID of an item you have download access to, using the Data API:
101101

102102
```
103-
planet data filter | planet data search PSScene --limit 1 - | jq -r .id
103+
planet data filter | planet data search PSScene --limit 1 --filter - | jq -r .id
104104
```
105105

106106
If you don't have access to PlanetScope data then replace PSScene with SkySatCollect.
@@ -515,7 +515,7 @@ One cool little trick is that you can even stream in the JSON directly with `cur
515515

516516
```console
517517
curl -s https://raw.githubusercontent.com/planetlabs/planet-client-python/main/docs/cli/request-json/tools-clip-composite.json \
518-
| planet orders request --item-type PSScene --bundle analytic_sr_udm2 --name 'Streaming Clip & Composite' \
518+
| planet orders request --item-type PSScene --bundle analytic_sr_udm2 --name 'Streaming Clip & Composite' --no-stac \
519519
20220605_124027_64_242b,20220605_124025_34_242b --tools - | planet orders create -
520520
```
521521

@@ -550,7 +550,7 @@ STAC metadata by default, as the STAC files are small and often more useful than
550550
You can easily turn off STAC output request with the `--no-stac` command:
551551

552552
```
553-
planet orders request PSScene visual --name 'No STAC' --no-stac --id 20220605_124027_64_242b
553+
planet orders request --item-type PSScene --bundle visual --name 'No STAC' --no-stac 20220605_124027_64_242b
554554
```
555555

556556
Currently this needs to be done for any 'composite' operation, as STAC output from composites is not yet
@@ -672,7 +672,7 @@ image that was published:
672672

673673
```console
674674
planet orders request --item-type SkySatCollect --bundle analytic --name 'SkySat Latest' \
675-
`planet data filter | planet data search SkySatCollect --sort 'acquired desc' --limit 1 - | jq -r .id` \
675+
`planet data filter | planet data search SkySatCollect --sort 'acquired desc' --limit 1 --filter - | jq -r .id` \
676676
| planet orders create -
677677
```
678678

@@ -681,7 +681,7 @@ Or get the 5 latest cloud free images in an area and create an order that clips
681681

682682
```console
683683
ids=`planet data filter --geom geometry.geojson --range clear_percent gt 90 | planet data \
684-
search PSScene --limit 5 - | jq -r .id | tr '\n' , | sed 's/.$//'`
684+
search PSScene --limit 5 --filter - | jq -r .id | tr '\n' , | sed 's/.$//'`
685685
planet orders request --item-type PSScene --bundle analytic_sr_udm2 --name 'Clipped Scenes' \
686686
$ids --clip geometry.geojson | planet orders create -
687687
```

docs/cli/cli-tips-tricks.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,11 @@ planet orders list | jq -rs '.[3] | "\(.id) \(.created_on) \(.name) \(.state)"'
301301

302302
* Use jq to show just orders that have a given item type, like just skysat.
303303

304-
planet orders list | jq -rs '.[] | "\(.id) \(.created_on) \(.state) \(.products[0].item_type)"' will show the item type
304+
```console
305+
planet orders list | jq -rs '.[] | "\(.id) \(.created_on) \(.state) \(.products[0].item_type)"'
306+
```
305307

306-
https://gist.github.com/ipbastola/2c955d8bf2e96f9b1077b15f995bdae3 has ideas for contains, but haven't got it right yet
308+
will show the item type https://gist.github.com/ipbastola/2c955d8bf2e96f9b1077b15f995bdae3 has ideas for contains, but haven't got it right yet
307309

308310
* use jq to get the id of the an order by it's name
309311

noxfile.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ def test(session):
4242
session.install(".[test]")
4343

4444
options = session.posargs
45-
session.run('pytest', '--ignore', 'examples/', '-v', *options)
45+
# -W=error raises pytest warnings to errors so they are caught by CI
46+
# to exclude some warnings, see
47+
# https://docs.python.org/3/library/warnings.html#temporarily-suppressing-warnings
48+
session.run('pytest', '--ignore', 'examples/', '-v', '-W=error', *options)
4649

4750

4851
@nox.session

planet/cli/data.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,8 @@ def filter(ctx,
283283
callback=check_item_types)
284284
@click.option('--filter',
285285
type=types.JSON(),
286-
help='Apply specified filter to search.')
286+
help="""Apply specified filter to search. Can be a json string,
287+
filename, or '-' for stdin.""")
287288
@limit
288289
@click.option('--name', type=str, help='Name of the saved search.')
289290
@click.option('--sort',
@@ -321,32 +322,35 @@ async def search(ctx, item_types, filter, limit, name, sort, pretty):
321322
@click.pass_context
322323
@translate_exceptions
323324
@coro
324-
@click.argument('name')
325325
@click.argument("item_types",
326326
type=types.CommaSeparatedString(),
327327
callback=check_item_types)
328-
@click.argument("filter", type=types.JSON())
328+
@click.option(
329+
'--filter',
330+
type=types.JSON(),
331+
required=True,
332+
help="""Filter to apply to search. Can be a json string, filename,
333+
or '-' for stdin.""")
334+
@click.option('--name',
335+
type=str,
336+
required=True,
337+
help='Name of the saved search.')
329338
@click.option('--daily-email',
330339
is_flag=True,
331340
help='Send a daily email when new results are added.')
332341
@pretty
333-
async def search_create(ctx, name, item_types, filter, daily_email, pretty):
342+
async def search_create(ctx, item_types, filter, name, daily_email, pretty):
334343
"""Create a new saved structured item search.
335344
336345
This function outputs a full JSON description of the created search,
337346
optionally pretty-printed.
338347
339-
NAME is the name to give the search.
340-
341348
ITEM_TYPES is a comma-separated list of item-types to search.
342-
343-
FILTER must be JSON and can be specified a json string, filename, or '-'
344-
for stdin.
345349
"""
346350
async with data_client(ctx) as cl:
347-
items = await cl.create_search(name=name,
348-
item_types=item_types,
351+
items = await cl.create_search(item_types=item_types,
349352
search_filter=filter,
353+
name=name,
350354
enable_email=daily_email)
351355
echo_json(items, pretty)
352356

planet/clients/data.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,9 @@ async def search(self,
167167
yield i
168168

169169
async def create_search(self,
170-
name: str,
171170
item_types: List[str],
172171
search_filter: dict,
172+
name: str,
173173
enable_email: bool = False) -> dict:
174174
"""Create a new saved structured item search.
175175
@@ -190,9 +190,9 @@ async def create_search(self,
190190
191191
192192
Parameters:
193-
name: The name of the saved search.
194193
item_types: The item types to include in the search.
195194
search_filter: Structured search criteria.
195+
name: The name of the saved search.
196196
enable_email: Send a daily email when new results are added.
197197
198198
Returns:

planet/clients/orders.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,10 @@ async def create_order(self, request: dict) -> dict:
123123
>>> from planet.order_request import build_request, product
124124
>>>
125125
>>> async def main():
126-
... image_ids = ['3949357_1454705_2020-12-01_241c']
126+
... image_ids = ["20200925_161029_69_2223"]
127127
... request = build_request(
128128
... 'test_order',
129-
... [product(image_ids, 'analytic', 'psorthotile')]
129+
... [product(image_ids, 'analytic_udm2', 'psscene')]
130130
... )
131131
... async with Session() as sess:
132132
... cl = OrdersClient(sess)

planet/order_request.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,3 +455,61 @@ def harmonize_tool(target_sensor: str) -> dict:
455455
raise ClientError(e)
456456

457457
return _tool('harmonize', {'target_sensor': target_sensor})
458+
459+
460+
def band_math_tool(b1: str,
461+
b2: Optional[str] = None,
462+
b3: Optional[str] = None,
463+
b4: Optional[str] = None,
464+
b5: Optional[str] = None,
465+
b6: Optional[str] = None,
466+
b7: Optional[str] = None,
467+
b8: Optional[str] = None,
468+
b9: Optional[str] = None,
469+
b10: Optional[str] = None,
470+
b11: Optional[str] = None,
471+
b12: Optional[str] = None,
472+
b13: Optional[str] = None,
473+
b14: Optional[str] = None,
474+
b15: Optional[str] = None,
475+
pixel_type: str = specs.BAND_MATH_PIXEL_TYPE_DEFAULT):
476+
'''Specify an Orders API band math tool.
477+
478+
The parameters of the bandmath tool define how each output band in the
479+
derivative product should be produced, referencing the product inputs’
480+
original bands. Band math expressions may not reference neighboring pixels,
481+
as non-local operations are not supported. The tool can calculate up to 15
482+
bands for an item. Input band parameters may not be skipped. For example,
483+
if the b4 parameter is provided, then b1, b2, and b3 parameters are also
484+
required.
485+
486+
For each band expression, the bandmath tool supports normal arithmetic
487+
operations and simple math operators offered in the Python numpy package.
488+
(For a list of supported mathematical functions, see
489+
[Bandmath supported numpy math routines](https://developers.planet.com/apis/orders/bandmath-numpy-routines/)).
490+
491+
One bandmath imagery output file is produced for each product bundle, with
492+
output bands derived from the band math expressions. nodata pixels are
493+
processed with the band math equation. These files have “_bandmath”
494+
appended to their file names.
495+
496+
The tool passes through UDM, RPC, and XML files, and does not update values
497+
in these files.
498+
499+
Parameters:
500+
b1-b15: An expression defining how the output band should be computed.
501+
pixel_type: A value indicating what the output pixel type should be.
502+
503+
Raises:
504+
planet.exceptions.ClientError: If pixel_type is not valid.
505+
''' # noqa
506+
try:
507+
pixel_type = specs.get_match(pixel_type,
508+
specs.BAND_MATH_PIXEL_TYPE,
509+
'pixel_type')
510+
except specs.SpecificationException as e:
511+
raise ClientError(e)
512+
513+
# e.g. {"b1": "b1", "b2":"arctan(b1)"} if b1 and b2 are specified
514+
parameters = dict((k, v) for k, v in locals().items() if v)
515+
return _tool('bandmath', parameters)

planet/specs.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
PRODUCT_BUNDLE_SPEC_NAME = 'orders_product_bundle_2023-02-24.json'
2222
SUPPORTED_TOOLS = [
23-
'band_math',
23+
'bandmath',
2424
'clip',
2525
'composite',
2626
'coregister',
@@ -34,6 +34,8 @@
3434
SUPPORTED_ARCHIVE_TYPES = ['zip']
3535
SUPPORTED_FILE_FORMATS = ['COG', 'PL_NITF']
3636
HARMONIZE_TOOL_TARGET_SENSORS = ('Sentinel-2', 'PS2')
37+
BAND_MATH_PIXEL_TYPE = ('Auto', '8U', '16U', '16S', '32R')
38+
BAND_MATH_PIXEL_TYPE_DEFAULT = 'Auto'
3739

3840
LOGGER = logging.getLogger(__name__)
3941

0 commit comments

Comments
 (0)