Skip to content

Commit

Permalink
Merge pull request #14 from mapbox/geoms-as-features
Browse files Browse the repository at this point in the history
Geometry sequence as features
  • Loading branch information
sgillies committed Nov 7, 2016
2 parents d18d24a + 58ca701 commit 892bd5b
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 4 deletions.
40 changes: 37 additions & 3 deletions cligj/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,21 @@ def iter_features(geojsonfile, func=None):
for line in geojsonfile:
if line.startswith(u'\x1e'):
if text_buffer:
newfeat = func(json.loads(text_buffer))
obj = json.loads(text_buffer)
if 'coordinates' in obj:
obj = to_feature(obj)
newfeat = func(obj)
if newfeat:
yield newfeat
text_buffer = line.strip(u'\x1e')
else:
text_buffer += line
# complete our parsing with a for-else clause.
else:
newfeat = func(json.loads(text_buffer))
obj = json.loads(text_buffer)
if 'coordinates' in obj:
obj = to_feature(obj)
newfeat = func(obj)
if newfeat:
yield newfeat

Expand All @@ -97,9 +103,17 @@ def iter_features(geojsonfile, func=None):
newfeat = func(feat)
if newfeat:
yield newfeat
elif 'coordinates' in obj:
newfeat = func(to_feature(obj))
if newfeat:
yield newfeat
for line in geojsonfile:
newfeat = func(to_feature(json.loads(line)))
if newfeat:
yield newfeat

# Indented or pretty-printed GeoJSON features or feature
# collections will fail out of the try clause above since
# collections will fail out of the try clause above since
# they'll have no complete JSON object on their first line.
# To handle these, we slurp in the entire file and parse its
# text.
Expand All @@ -115,6 +129,26 @@ def iter_features(geojsonfile, func=None):
newfeat = func(feat)
if newfeat:
yield newfeat
elif 'coordinates' in obj:
newfeat = func(to_feature(obj))
if newfeat:
yield newfeat


def to_feature(obj):
"""Takes a feature or a geometry
returns feature verbatim or
wraps geom in a feature with empty properties
"""
if obj['type'] == 'Feature':
return obj
elif 'coordinates' in obj:
return {
'type': 'Feature',
'properties': {},
'geometry': obj}
else:
raise ValueError("Object is not a feature or geometry")


def iter_query(query):
Expand Down
4 changes: 4 additions & 0 deletions tests/point_pretty_geom.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"coordinates": [-122.7282, 45.5801],
"type": "Point"
}
23 changes: 22 additions & 1 deletion tests/test_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest

from cligj.features import \
coords_from_query, iter_query, \
coords_from_query, iter_query, to_feature, \
normalize_feature_inputs, normalize_feature_objects


Expand Down Expand Up @@ -118,6 +118,20 @@ def test_coordpairs_space(expected_features):
assert _geoms(features) == _geoms(expected_features)


def test_geometrysequence(expected_features):
features = normalize_feature_inputs(None, 'features', ["tests/twopoints_geom_seq.txt"])
assert _geoms(features) == _geoms(expected_features)


def test_geometrysequencers(expected_features):
features = normalize_feature_inputs(None, 'features', ["tests/twopoints_geom_seqrs.txt"])
assert _geoms(features) == _geoms(expected_features)


def test_geometrypretty(expected_features):
features = normalize_feature_inputs(None, 'features', ["tests/point_pretty_geom.txt"])
assert _geoms(features)[0] == _geoms(expected_features)[0]

class MockGeo(object):
def __init__(self, feature):
self.__geo_interface__ = feature
Expand All @@ -134,3 +148,10 @@ def test_normalize_feature_objects_bad(expected_features):
objs.append(MockGeo(dict()))
with pytest.raises(ValueError):
list(normalize_feature_objects(objs))

def test_to_feature(expected_features):
geom = expected_features[0]['geometry']
feat = {'type': 'Feature', 'properties': {}, 'geometry': geom}
assert to_feature(feat) == to_feature(geom)
with pytest.raises(ValueError):
assert to_feature({'type': 'foo'})
2 changes: 2 additions & 0 deletions tests/twopoints_geom_seq.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{"coordinates": [-122.7282, 45.5801], "type": "Point"}
{"coordinates": [-121.3153, 44.0582], "type": "Point"}
8 changes: 8 additions & 0 deletions tests/twopoints_geom_seqrs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"coordinates": [-122.7282, 45.5801],
"type": "Point"
}
{
"coordinates": [-121.3153, 44.0582],
"type": "Point"
}

0 comments on commit 892bd5b

Please sign in to comment.