Repository: planetlabs/planet-client-python
Pull request #66 (2015-08-20 01:42:34)

Aoi work


Patch:
diff --git a/planet/api/models.py b/planet/api/models.py
index 7a08449..871dd52 100644
--- a/planet/api/models.py
+++ b/planet/api/models.py
@@ -172,6 +172,7 @@ class _Features(_Paged):
 
     def _json_stream(self, limit):
         stream = super(_Features, self)._json_stream(limit)
+        stream['count'] = self.get()['count']
         stream['type'] = 'FeatureCollection'
         return stream
 
diff --git a/planet/api/utils.py b/planet/api/utils.py
index 94f6b43..7383c58 100644
--- a/planet/api/utils.py
+++ b/planet/api/utils.py
@@ -155,3 +155,35 @@ class GeneratorAdapter(list):
 
     def __len__(self):
         return 1
+
+
+def probably_wkt(text):
+    '''Quick check to determine if the provided text looks like WKT'''
+    valid = False
+    valid_types = set([
+        'POINT', 'LINESTRING', 'POLYGON', 'MULTIPOINT',
+        'MULTILINESTRING', 'MULTIPOLYGON', 'GEOMETRYCOLLECTION',
+    ])
+    matched = re.match('(\w+)\s*\([^)]+\)', text.strip())
+    if matched:
+        valid = matched.group(1).upper() in valid_types
+    return valid
+
+
+def probably_geojson(input):
+    '''A quick check to see if this input looks like GeoJSON. If not a dict
+    JSON-like object, attempt to parse input as JSON. If the resulting object
+    has a type property that looks like GeoJSON, return that object or None'''
+    valid = False
+    if not isinstance(input, dict):
+        try:
+            input = json.loads(input)
+        except ValueError:
+            return None
+    typename = input.get('type', None)
+    supported_types = set([
+        'Point', 'LineString', 'Polygon', 'MultiPoint', 'MultiLineString',
+        'MultiPolygon', 'GeometryCollection', 'Feature', 'FeatureCollection'
+    ])
+    valid = typename in supported_types
+    return input if valid else None
diff --git a/planet/scripts/__init__.py b/planet/scripts/__init__.py
index d391c87..3907cf1 100644
--- a/planet/scripts/__init__.py
+++ b/planet/scripts/__init__.py
@@ -172,6 +172,24 @@ def read(value, split=False):
     return retval
 
 
+def read_aoi(value):
+    '''See if the provided AOI looks like a WKT or GeoJSON and if so, return
+    as text or a parsed dict. If the value resolves to nothing, return None.
+    Otherwise raise ClickException if the provided value is not either.
+    '''
+    aoi = None
+    raw = read(value)
+    if raw:
+        if api.utils.probably_wkt(raw):
+            aoi = raw
+        else:
+            aoi = api.utils.probably_geojson(raw)
+        if aoi is None:
+            raise click.ClickException('The provided AOI does not look like '
+                                       'WKT or GeoJSON')
+    return aoi
+
+
 def _split(value):
     '''return input split on any whitespace'''
     return re.split('\s+', value)
@@ -235,7 +253,7 @@ def init(email, password):
 def get_scenes_list(scene_type, pretty, aoi, limit, where, workspace):
     '''Get a list of scenes'''
 
-    aoi = read(aoi)
+    aoi = read_aoi(aoi)
     conditions = {}
 
     if workspace:
@@ -444,12 +462,8 @@ def set_workspace(id, aoi, name, create, workspace):
     if create:
         id = None
 
-    aoi = read(aoi)
+    aoi = read_aoi(aoi)
     if aoi:
-        try:
-            aoi = json.loads(aoi)
-        except ValueError:
-            raise click.ClickException('workspace aoi must be JSON')
         geom = api.utils.geometry_from_json(aoi)
         if geom is None:
             raise click.ClickException('unable to find geometry in aoi')


Test patch:
diff --git a/tests/fixtures/valid-wkt.txt b/tests/fixtures/valid-wkt.txt
new file mode 100644
index 0000000..6556c27
--- /dev/null
+++ b/tests/fixtures/valid-wkt.txt
@@ -0,0 +1,10 @@
+POINT (30 10)
+LINESTRING (30 10, 10 30, 40 40)
+POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))
+POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))
+MULTIPOINT ((10 40), (40 30), (20 20), (30 10))
+MULTIPOINT (10 40, 40 30, 20 20, 30 10)
+MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))
+MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))
+MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), (30 20, 20 15, 20 25, 30 20)))
+GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))
\ No newline at end of file
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 71fddca..9e6a8a3 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -252,7 +252,7 @@ def test_workspace_update_stdin():
 
 
 def test_workspace_create_aoi_stdin():
-    geometry = {'type': 'Geometry'}
+    geometry = {'type': 'Point'}
     expected = {
         'name': 'foobar',
         'filters': {
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 260b7e7..29facfa 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -43,3 +43,29 @@ def test_build_conditions():
     assert c['sat.alt.gte'] == 200
     assert c['sat.alt.lte'] == 650
     assert c['age.lte'] == 63072000
+
+
+def test_probably_wkt():
+    # not wkt
+    assert not utils.probably_wkt('')
+    assert not utils.probably_wkt('{ geojson }')
+    # it is wkt but we don't support it
+    assert not utils.probably_wkt('POLYHEDRALSURFACE ()')
+    assert not utils.probably_wkt('TRIANGLE((0 0 0,0 1 0,1 1 0,0 0 0))')
+
+    # all valid wkt
+    wkt = read_fixture('valid-wkt.txt').split('\n')
+    assert len(wkt) > 0
+    for valid in wkt:
+        assert utils.probably_wkt(valid)
+
+
+def test_probably_geojson():
+    # nope
+    assert utils.probably_geojson('') is None
+    assert utils.probably_geojson('{}') is None
+    assert utils.probably_geojson({}) is None
+    assert utils.probably_geojson({'type': 'random'}) is None
+    # yep
+    assert utils.probably_geojson({'type': 'Point'}) == {'type': 'Point'}
+    assert utils.probably_geojson('{"type": "Point"}') == {'type': 'Point'}