diff --git a/combine_features.py b/combine_features.py index b0fc4a8e..e358fc51 100755 --- a/combine_features.py +++ b/combine_features.py @@ -8,7 +8,7 @@ the file pointed to with the -o flag (features.geojson by default). Author: Xylar Asay-Davis -Last Modified: 09/10/2016 +Last Modified: 09/29/2016 """ import json @@ -104,14 +104,6 @@ print " points and transects) are being cobined." sys.exit(1) -out_file = open(out_file_name, 'w') -out_file.write('{"type": "FeatureCollection",\n') -out_file.write(' "groupName": "enterNameHere",\n') -out_file.write(' "features":\n') -out_file.write('\t[\n') -write_all_features(features, out_file, '\t\t') -out_file.write('\n') -out_file.write('\t]\n') -out_file.write('}\n') +write_all_features(features, out_file_name, indent=4) # vim: foldmethod=marker ai ts=4 sts=4 et sw=4 ft=python diff --git a/difference_features.py b/difference_features.py index 7907f007..0bd136c6 100755 --- a/difference_features.py +++ b/difference_features.py @@ -1,14 +1,14 @@ #!/usr/bin/env python """ This script takes a file containing one or more feature definitions, that is -pointed to by the -f flag and a second masking feature definition, pointed -to with the -m flag. The masking features are masked out of (i.e. removed -from) the original feature definitions. The resulting features are placed -in (or appended to) the output file pointed to with the -o flag -(features.geojson by default). +pointed to by the -f flag and a second set of one or more masking feature +definition, pointed to with the -m flag. The masking features are masked out +of (i.e. removed from) the original feature definitions. The resulting +features are placed in (or appended to) the output file pointed to with the +-o flag (features.geojson by default). Authors: Xylar Asay-Davis -Last Modified: 02/12/2016 +Last Modified: 09/29/2016 """ import json @@ -25,10 +25,11 @@ parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawTextHelpFormatter) parser.add_argument("-f", "--feature_file", dest="feature_file", - help="Single feature file to be clipped", metavar="FILE1", + help="Feature file to be clipped", metavar="FILE1", required=True) parser.add_argument("-m", "--mask_file", dest="mask_file", - help="Single feature whose overlap with the first feature should be removed", + help="Feature file with one or more features whose overlap " + "with features in feature_file should be removed", metavar="FILE2", required=True) parser.add_argument("-o", "--output", dest="output_file_name", help="Output file, e.g., features.geojson.", @@ -96,6 +97,8 @@ if featureShape.is_empty : add = False break + else: + print "Masked feature %s with mask %s"%(name,maskFeature['properties']['name']) if(add): if(masked): @@ -105,14 +108,6 @@ else: print "%s has been removed."%name -out_file = open(out_file_name, 'w') -out_file.write('{"type": "FeatureCollection",\n') -out_file.write(' "groupName": "enterNameHere",\n') -out_file.write(' "features":\n') -out_file.write('\t[\n') -write_all_features(features, out_file, '\t\t') -out_file.write('\n') -out_file.write('\t]\n') -out_file.write('}\n') +write_all_features(features, out_file_name, indent=4) # vim: foldmethod=marker ai ts=4 sts=4 et sw=4 ft=python diff --git a/fix_features_at_antimeridian.py b/fix_features_at_antimeridian.py index 77f63a23..8f9cff8f 100755 --- a/fix_features_at_antimeridian.py +++ b/fix_features_at_antimeridian.py @@ -16,7 +16,7 @@ The script makes use of the shapely library. Author: Xylar Asay-Davis -Last Modified: 1/31/2016 +Last Modified: 9/29/2016 """ @@ -103,6 +103,8 @@ def fromPolar(x,y): parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawTextHelpFormatter) parser.add_argument("-f", "--features_file", dest="features_file", help="File containing features to split at the antimeridian", metavar="FILE", required=True) +parser.add_argument("-o", "--output", dest="output_file_name", help="Output file, e.g., features.geojson.", metavar="PATH", default="features.geojson") + args = parser.parse_args() @@ -122,17 +124,6 @@ def fromPolar(x,y): if(result is not None): feature['geometry'] = result -out_file_name = "features.geojson" - -out_file = open(out_file_name, 'w') - -out_file.write('{"type": "FeatureCollection",\n') -out_file.write(' "groupName": "enterNameHere",\n') -out_file.write(' "features":\n') -out_file.write('\t[\n') -write_all_features(features_file, out_file, '\t\t') -out_file.write('\n') -out_file.write('\t]\n') -out_file.write('}\n') +write_all_features(features_file, args.output_file_name, indent=4) # vim: foldmethod=marker ai ts=4 sts=4 et sw=4 ft=python diff --git a/fix_features_at_prime_meridian.py b/fix_features_at_prime_meridian.py index e0daa41c..b49c84ac 100755 --- a/fix_features_at_prime_meridian.py +++ b/fix_features_at_prime_meridian.py @@ -13,7 +13,7 @@ The script makes use of the shapely library. Author: Xylar Asay-Davis -Last Modified: 2/27/2016 +Last Modified: 9/29/2016 """ @@ -65,6 +65,8 @@ def splitGeometryCrossingPrimeMeridian(geometry): parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawTextHelpFormatter) parser.add_argument("-f", "--features_file", dest="features_file", help="File containing features to split at the antimeridian", metavar="FILE", required=True) +parser.add_argument("-o", "--output", dest="output_file_name", help="Output file, e.g., features.geojson.", metavar="PATH", default="features.geojson") + args = parser.parse_args() @@ -84,17 +86,6 @@ def splitGeometryCrossingPrimeMeridian(geometry): if(result is not None): feature['geometry'] = result -out_file_name = "features.geojson" - -out_file = open(out_file_name, 'w') - -out_file.write('{"type": "FeatureCollection",\n') -out_file.write(' "groupName": "enterNameHere",\n') -out_file.write(' "features":\n') -out_file.write('\t[\n') -write_all_features(features_file, out_file, '\t\t') -out_file.write('\n') -out_file.write('\t]\n') -out_file.write('}\n') +write_all_features(features_file, args.output_file_name, indent=4) # vim: foldmethod=marker ai ts=4 sts=4 et sw=4 ft=python diff --git a/merge_features.py b/merge_features.py index 36b9602e..66367115 100755 --- a/merge_features.py +++ b/merge_features.py @@ -16,16 +16,16 @@ features.geojson if their tags property contains all of the tags listed on the input line. -Authors: Douglas Jacobsen -Last Modified: 02/11/2016 +Authors: Douglas Jacobsen, Xylar Asay-Davis +Last Modified: 9/29/2016 """ import sys, os, glob, shutil, numpy, fnmatch import json import argparse from collections import defaultdict -from utils.feature_write_utils import * -from utils.feature_test_utils import * +from utils.feature_write_utils import write_all_features +from utils.feature_test_utils import match_tag_list, feature_already_exists parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawTextHelpFormatter) parser.add_argument("-f", "--feature_file", dest="feature_file", help="Single feature file to append to features.geojson", metavar="FILE") @@ -67,8 +67,6 @@ except: new_file = True -out_file = open(file_to_append, 'w') - if args.feature_file: try: with open(args.feature_file) as f: @@ -103,13 +101,6 @@ print "Error parsing geojson file: %s"%(path) del paths -out_file.write('{"type": "FeatureCollection",\n') -out_file.write(' "groupName": "enterNameHere",\n') -out_file.write(' "features":\n') -out_file.write('\t[\n') -write_all_features(all_features, out_file, '\t\t') -out_file.write('\n') -out_file.write('\t]\n') -out_file.write('}\n') +write_all_features(all_features, file_to_append, indent=4) # vim: foldmethod=marker ai ts=4 sts=4 et sw=4 ft=python diff --git a/plot_features.py b/plot_features.py index d2a949b5..d736c850 100755 --- a/plot_features.py +++ b/plot_features.py @@ -15,7 +15,7 @@ 'southpole', 'atlantic', 'pacific', 'americas', 'asia' Authors: Xylar Asay-Davis, Doug Jacobsen, Phillip J. Wolfram -Last Modified: 09/14/2016 +Last Modified: 09/29/2016 """ import os.path diff --git a/simplify_features.py b/simplify_features.py index d8401a17..10c9373e 100755 --- a/simplify_features.py +++ b/simplify_features.py @@ -10,7 +10,7 @@ file pointed to with the -o flag (features.geojson by default). Author: Xylar Asay-Davis -Last Modified: 4/4/2016 +Last Modified: 9/29/2016 """ import json @@ -78,15 +78,6 @@ feature['geometry'] = shapely.geometry.mapping(simplifiedFeature) features['features'].append(feature) - -out_file = open(out_file_name, 'w') -out_file.write('{"type": "FeatureCollection",\n') -out_file.write(' "groupName": "enterNameHere",\n') -out_file.write(' "features":\n') -out_file.write('\t[\n') -write_all_features(features, out_file, '\t\t') -out_file.write('\n') -out_file.write('\t]\n') -out_file.write('}\n') +write_all_features(features, out_file_name, indent=4) # vim: foldmethod=marker ai ts=4 sts=4 et sw=4 ft=python diff --git a/split_features.py b/split_features.py index 4fe0c9c1..3096d5c1 100755 --- a/split_features.py +++ b/split_features.py @@ -6,15 +6,15 @@ pointed to by the -f flag. It then writes each feature defition out to it's own independent file in an autogenerated directory tree. -Authors: Douglas Jacobsen -Last Modified: 08/27/2015 +Authors: Douglas Jacobsen, Xylar Asay-Davis +Last Modified: 9/29/2016 """ import os import json import argparse -from utils.feature_write_utils import write_single_feature +from utils.feature_write_utils import write_all_features parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawTextHelpFormatter) parser.add_argument("-f", "--features_file", dest="features_file", help="File containing features to split up", metavar="FILE", required=True) @@ -39,15 +39,8 @@ if not os.path.exists('%s/%s/%s'%(component, object_type, dir_name)): os.makedirs('%s/%s/%s'%(component, object_type, dir_name)) - out_file = open('%s/%s/%s/%s.geojson'%(component, object_type, dir_name, object_type), 'w') + out_file_name = '%s/%s/%s/%s.geojson'%(component, object_type, dir_name, object_type) - out_file.write('{"type": "FeatureCollection",\n') - out_file.write(' "features":\n') - out_file.write('\t[\n') - write_single_feature(feature, out_file, '\t\t') - out_file.write('\n') - out_file.write('\t]\n') - out_file.write('}\n') - out_file.close() + write_all_features({'features':[feature]}, out_file_name, indent=4) # vim: foldmethod=marker ai ts=4 sts=4 et sw=4 ft=python diff --git a/tag_features.py b/tag_features.py index a6ca36dd..4054c5c5 100755 --- a/tag_features.py +++ b/tag_features.py @@ -1,13 +1,14 @@ #!/usr/bin/env python """ -This script takes a file containing a collection of one or more feature -definitions, that is pointed to by the -f flag and a tag name pointed to by -the -t flag. The tag is added to each feature (if that feature does not -already have that tag. Results are written back to the same feature file. +This script takes a file containing a collection of one or more feature +definitions, that is pointed to by the -f flag and a tag name pointed to by +the -t flag. The tag is added to each feature (if that feature does not +already have that tag. Results are written to the file pointed to with +the -o flag (features.geojson by default). Author: Xylar Asay-Davis -Last Modified: 2/11/2016 +Last Modified: 9/29/2016 """ import os.path @@ -17,60 +18,62 @@ from utils.feature_write_utils import write_all_features -parser = argparse.ArgumentParser(description=__doc__, +parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawTextHelpFormatter) -parser.add_argument("-f", "--feature_file", dest="feature_file", +parser.add_argument("-f", "--feature_file", dest="feature_file", help="Features collection file to be tagged", metavar="FILE", required=True) -parser.add_argument("-t", "--tag", dest="tag", help="Tag to add to all features", +parser.add_argument("-t", "--tag", dest="tag", help="Tag to add to all features", metavar="TAG", required=True) parser.add_argument("-r", "--remove", dest="remove", action='store_true', help="Use this flag to signal removing a tag instead of adding") +parser.add_argument("-o", "--output", dest="output_file_name", + help="Output file, e.g., features.geojson.", metavar="PATH", + default="features.geojson") args = parser.parse_args() -out_file_name = args.feature_file +out_file_name = args.output_file_name + all_features = defaultdict(list) if os.path.exists(out_file_name): - with open(out_file_name) as f: - appended_file = json.load(f) - for feature in appended_file['features']: - try: + try: + with open(out_file_name) as f: + appended_file = json.load(f) + for feature in appended_file['features']: + all_features['features'].append(feature) + del appended_file + except: + pass + +try: + filePointer = open(args.feature_file, 'r') +except IOError: + print "Error: file %s does not exist"%(args.feature_file) + raise + +appended_file = json.load(filePointer) +for feature in appended_file['features']: + try: feature_tags = feature['properties']['tags'] - except: + except KeyError: feature_tags = '' - feature_tag_list = feature_tags.split(';') - if args.remove: + feature_tag_list = feature_tags.split(';') + if args.remove: if args.tag in feature_tag_list: - feature_tag_list.remove(args.tag) - if(len(feature_tag_list) == 0): - feature['properties']['tags'] = '' - else: - feature_tags = feature_tag_list[0] - for tag in feature_tag_list[1:len(feature_tag_list)]: - feature_tags = '%s;%s'%(feature_tags,tag) - feature['properties']['tags'] = feature_tags - else: + feature_tag_list.remove(args.tag) + feature['properties']['tags'] = ';'.join(feature_tag_list) + else: if args.tag not in feature_tag_list: - if(feature_tags == ''): - feature['properties']['tags'] = args.tag - else: - feature['properties']['tags'] = '%s;%s'%(feature_tags,args.tag) - - all_features['features'].append(feature) - del appended_file + if(feature_tags == ''): + feature['properties']['tags'] = args.tag + else: + feature['properties']['tags'] = '%s;%s'%(feature_tags,args.tag) -out_file = open(out_file_name, 'w') + all_features['features'].append(feature) -out_file.write('{"type": "FeatureCollection",\n') -out_file.write(' "groupName": "enterNameHere",\n') -out_file.write(' "features":\n') -out_file.write('\t[\n') -write_all_features(all_features, out_file, '\t\t') -out_file.write('\n') -out_file.write('\t]\n') -out_file.write('}\n') +write_all_features(all_features, out_file_name, indent=4) # vim: foldmethod=marker ai ts=4 sts=4 et sw=4 ft=python diff --git a/utils/feature_test_utils.py b/utils/feature_test_utils.py index 4393346a..bca45784 100644 --- a/utils/feature_test_utils.py +++ b/utils/feature_test_utils.py @@ -1,41 +1,52 @@ #!/use/bin/env python -import json - -def match_tag_list(feature, master_tags):#{{{ - try: - feature_tags = feature['properties']['tags'] - except: - return True - - feature_tag_list = feature_tags.split(';') - - test = True - for tag in master_tags: - if tag in feature_tag_list: - test = test and True - else: - test = test and False - - return test -#}}} - -def feature_already_exists(existing_features, adding_feature):#{{{ - try: - feature_name = adding_feature['properties']['name'] - except: - print "Current feature doesn't have a name property. Exiting..." - quit(1) - - for feature in existing_features['features']: - try: - test_name = feature['properties']['name'] - except: - print "A feature in the existing features file does not have a name property. Exiting..." - quit(1) - - if test_name == feature_name: - print " A feature already exists with the name '%s', either use that one, or change the name before adding it."%(feature_name) - return True - - return False -#}}} + +""" +Utility funcitons for finding features wiht matching tags and checking if +features already exist + +Authors: Douglas Jacobsen, Xylar Asay-Davis +Last Modified: 09/29/2016 +""" + +def match_tag_list(feature, master_tags): # {{{ + try: + feature_tags = feature['properties']['tags'] + except: + return True + + feature_tag_list = feature_tags.split(';') + + test = True + for tag in master_tags: + if tag in feature_tag_list: + test = test and True + else: + test = test and False + + return test +# }}} + + +def feature_already_exists(existing_features, adding_feature): # {{{ + try: + feature_name = adding_feature['properties']['name'] + except: + print "Current feature doesn't have a name property. Exiting..." + quit(1) + + for feature in existing_features['features']: + try: + test_name = feature['properties']['name'] + except: + print "A feature in the existing features file does not have a " \ + "name property. Exiting..." + quit(1) + + if test_name == feature_name: + print " A feature already exists with the name '%s', either use " \ + "that one, or change the name before adding it." \ + % (feature_name) + return True + + return False +# }}} diff --git a/utils/feature_write_utils.py b/utils/feature_write_utils.py index 2789b123..44418d9f 100644 --- a/utils/feature_write_utils.py +++ b/utils/feature_write_utils.py @@ -1,183 +1,93 @@ #!/use/bin/env python + +""" +Utility funcitons for writing geojson files from a dictionary of features. + +Authors: Douglas Jacobsen, Xylar Asay-Davis +Last Modified: 09/29/2016 +""" + import json import sys -def write_all_features(features, out_file, base_indent):#{{{ - first_feature = True - for feature in features['features']: - if not first_feature: - out_file.write(',\n') - write_single_feature(feature, out_file, base_indent) - first_feature = False -#}}} - -def write_single_feature(feature, out_file, base_indent):#{{{ - # Write properties first - - out_file.write('%s{"type": "Feature",\n'%(base_indent)) - out_file.write('%s "properties": {\n'%(base_indent)) - - # Set property values that need to be set... - if not 'name' in feature['properties'].keys(): - print "There was an error getting the name property from a feature. Exiting...\n" - sys.exit(1) - - if not 'component' in feature['properties'].keys(): - print "Feature %s has an issue with the component property. Exiting...\n"%(feature['properties']['name']) - sys.exit(1) - - if not 'author' in feature['properties'].keys(): - feature['properties']['author'] = "" - - if not 'tags' in feature['properties'].keys(): - feature['properties']['tags'] = "" - - if not 'type' in feature['geometry'].keys(): - print "Feature %s has an issue with the geometry type. Exiting...\n"%(feature['properties']['name']) - sys.exit(1) - - feature_type = feature['geometry']['type'] - - # Determine object property value based on feature type. - if feature_type == "Polygon" or feature_type == "MultiPolygon": - object_type = "region" - elif feature_type == "LineString" or feature_type == "MultiLineString": - object_type = "transect" - elif feature_type == "Point": - object_type = "point" - - feature['properties']['object'] = object_type - - write_comma = False - - for key in sorted(feature['properties'].keys()): - if write_comma: - out_file.write(",\n") - - out_file.write('%s\t"%s": "%s"'%(base_indent, key, feature['properties'][key])) - - write_comma = True - - out_file.write("\n") - - # Write out properties - try: - feature_type = feature['geometry']['type'] - except: - print "Feature: %s has an issue with the type of geometry. Exiting...\n"%(feature['properties']['name']) - quit(1) - - - out_file.write('%s },\n'%(base_indent)) - - # Write out geometry - out_file.write('%s "geometry":\n'%(base_indent)) - out_file.write('%s\t{"type": "%s",\n'%(base_indent, feature_type)) - out_file.write('%s\t "coordinates":\n'%(base_indent)) - - if feature_type == "MultiPolygon": - # An array of polygons - # Each polygon is an array of shapes - # Each The first shape in a polygon is an array describing the vertices of the exterior of the polygon - # Each other shape in a polygon is an array describing the vertices of each hole in the interior of the polygon - coords_list = feature['geometry']['coordinates'] - - out_file.write('%s\t\t[\n'%(base_indent)) - out_file.write('%s\t\t\t[\n'%(base_indent)) - write_poly_seps = False - for poly in coords_list: - write_shape_seps = False - if write_poly_seps: - out_file.write('%s\t\t\t],\n'%(base_indent)) - out_file.write('%s\t\t\t[\n'%(base_indent)) - else: - write_poly_seps = True - - out_file.write('%s\t\t\t\t[\n'%(base_indent)) - for shape in poly: - if write_shape_seps: - out_file.write('%s\t\t\t\t],\n'%(base_indent)) - out_file.write('%s\t\t\t\t[\n'%(base_indent)) - else: - write_shape_seps = True - - write_coordinates(shape, out_file, '%s\t\t\t\t\t'%(base_indent)) - - out_file.write('%s\t\t\t\t]\n'%(base_indent)) - out_file.write('%s\t\t\t]\n'%(base_indent)) - out_file.write('%s\t\t]\n'%(base_indent)) - - elif feature_type == "Polygon": - # One large array - # Inside, any number of arrays - # First array is an array of points representing the exterior of the polygon - # Any after the first are arrays of points representing the holes within the polygon - - coords_list = feature['geometry']['coordinates'] - - out_file.write('%s\t\t[\n'%(base_indent)) - out_file.write('%s\t\t\t[\n'%(base_indent)) - write_poly_seps = False - for shape in coords_list: - if write_poly_seps: - out_file.write('%s\t\t\t],\n'%(base_indent)) - out_file.write('%s\t\t\t[\n'%(base_indent)) - else: - write_poly_seps = True - - write_coordinates(shape, out_file, '%s\t\t\t\t'%(base_indent)) - out_file.write('%s\t\t\t]\n'%(base_indent)) - out_file.write('%s\t\t]\n'%(base_indent)) - - elif feature_type == "MultiLineString": - # An array of lines - # Each line is an array of coordinates for each line segment - coords_list = feature['geometry']['coordinates'] - - out_file.write('%s\t\t[\n'%(base_indent)) - out_file.write('%s\t\t\t[\n'%(base_indent)) - write_line_seps = False - for line in coords_list: - if write_line_seps: - out_file.write('%s\t\t\t],\n'%(base_indent)) - out_file.write('%s\t\t\t[\n'%(base_indent)) - else: - write_line_seps = True - - write_coordinates(line, out_file, '%s\t\t\t\t'%(base_indent)) - out_file.write('%s\t\t\t]\n'%(base_indent)) - out_file.write('%s\t\t]\n'%(base_indent)) - - elif feature_type == "LineString": - # An single line - # Made up of an array of points - coords_list = feature['geometry']['coordinates'] - - out_file.write('%s\t\t[\n'%(base_indent)) - write_coordinates(coords_list, out_file, '%s\t\t\t'%(base_indent)) - out_file.write('%s\t\t]\n'%(base_indent)) - - elif feature_type == "Point": - coords_list = feature['geometry']['coordinates'] - out_file.write('%s\t[ %f, %f]\n'%(base_indent, coords_list[0], coords_list[1])) - else: - print "ERROR: Unsupported feature type: %s"%(feature_type) - sys.exit(1) - - out_file.write('%s\t}\n'%(base_indent)) - out_file.write('%s}'%(base_indent)) - -#}}} - -def write_coordinates(coords, out_file, base_indent):#{{{ - write_comma = False - for coord in coords: - if write_comma: - out_file.write(',\n') - else: - write_comma = True - - out_file.write('%s[ %f, %f]'%(base_indent, coord[0], coord[1])) - - out_file.write('\n') -#}}} +from collections import OrderedDict + + +def write_all_features(features, out_file_name, indent=4): # {{{ + json.encoder.FLOAT_REPR = lambda o: format(o, 'f') + + for index in range(len(features['features'])): + features['features'][index] = \ + check_feature(features['features'][index]) + + features['type'] = 'FeatureCollection' + + # Make the feature an ordered dictionary so type and groupName come before + # features (easier to read) + outFeatures = OrderedDict((('type', features['type']),)) + if 'groupName' in features.keys(): + outFeatures['groupName'] = features['groupName'] + + # Add the rest + for key in features: + if key not in outFeatures.keys(): + outFeatures[key] = features[key] + + out_file = open(out_file_name, 'w') + + json.dump(outFeatures, out_file, indent=indent) + + return outFeatures +# }}} + + +def check_feature(feature): # {{{ + + # Set property values that need to be set... + if 'name' not in feature['properties'].keys(): + print "There was an error getting the name property from a feature. " \ + "Exiting..." + sys.exit(1) + + if 'component' not in feature['properties'].keys(): + print "Feature %s has an issue with the component property. " \ + "Exiting..." % (feature['properties']['name']) + sys.exit(1) + + if 'author' not in feature['properties'].keys(): + feature['properties']['author'] = "" + + if 'tags' not in feature['properties'].keys(): + feature['properties']['tags'] = "" + + if 'type' not in feature['geometry'].keys(): + print "Feature %s has an issue with the geometry type. Exiting..." \ + % (feature['properties']['name']) + sys.exit(1) + + feature_type = feature['geometry']['type'] + + # Determine object property value based on feature type. + if feature_type == "Polygon" or feature_type == "MultiPolygon": + object_type = "region" + elif feature_type == "LineString" or feature_type == "MultiLineString": + object_type = "transect" + elif feature_type == "Point" or feature_type == "MultiPoint": + object_type = "point" + else: + raise ValueError("Unsupported feature type %s" % feature_type) + + feature['properties']['object'] = object_type + + # Make the feature an ordered dictionary so properties come before geometry + # (easier to read) + outFeature = OrderedDict((('type', 'Feature'), + ('properties', feature['properties']))) + # Add the rest + for key in feature: + if key not in outFeature.keys(): + outFeature[key] = feature[key] + + return outFeature + +# }}}