From 150ba10694ceab9c5f16c993327169729f156d3f Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Wed, 21 Sep 2016 17:39:19 +0200 Subject: [PATCH 1/4] Update feature_write_utils to use json.dump This makes it easier to support new geometries (such as MultiPoint) that weren't supported by the previous writer. It also means that no file formatting must be handled by calling scripts, since json.dump writes the full structure in one step. For convenience, write_all_features now takes a file name instead of a file pointer. Some gymnastics were required to make sure that properties come before geometry (which makes the files easier to manipulate. Also, The formatting, while similar, is not identical to the previous. write_single_feature has been removed since it can be handled by write_all_features in the only script that uses it. All scripts have been updated to work with the new syntax. --- combine_features.py | 10 +- difference_features.py | 12 +- fix_features_at_antimeridian.py | 15 +- fix_features_at_prime_meridian.py | 15 +- merge_features.py | 15 +- simplify_features.py | 11 +- split_features.py | 13 +- tag_features.py | 11 +- utils/feature_test_utils.py | 84 +++++----- utils/feature_write_utils.py | 260 ++++++++++-------------------- 10 files changed, 143 insertions(+), 303 deletions(-) diff --git a/combine_features.py b/combine_features.py index b0fc4a8e..b2f7f74e 100755 --- a/combine_features.py +++ b/combine_features.py @@ -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..c0d01ae6 100755 --- a/difference_features.py +++ b/difference_features.py @@ -96,6 +96,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 +107,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..38d52382 100755 --- a/fix_features_at_antimeridian.py +++ b/fix_features_at_antimeridian.py @@ -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..0def3892 100755 --- a/fix_features_at_prime_meridian.py +++ b/fix_features_at_prime_meridian.py @@ -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..0fe8ddad 100755 --- a/merge_features.py +++ b/merge_features.py @@ -24,8 +24,8 @@ 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/simplify_features.py b/simplify_features.py index d8401a17..55a3aac1 100755 --- a/simplify_features.py +++ b/simplify_features.py @@ -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..a35549e2 100755 --- a/split_features.py +++ b/split_features.py @@ -14,7 +14,7 @@ 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..671c2a1d 100755 --- a/tag_features.py +++ b/tag_features.py @@ -62,15 +62,6 @@ all_features['features'].append(feature) del appended_file -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(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..e84455c0 100644 --- a/utils/feature_test_utils.py +++ b/utils/feature_test_utils.py @@ -1,41 +1,45 @@ #!/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 -#}}} + + +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..dd0b7eb4 100644 --- a/utils/feature_write_utils.py +++ b/utils/feature_write_utils.py @@ -2,182 +2,84 @@ 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 + +# }}} From 8e9e8db0cdf431fccc7216c3c71201b1b37a09f0 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Thu, 29 Sep 2016 11:09:00 +0200 Subject: [PATCH 2/4] tag_features.py now writes to new file Previously, tag_features.py changed tags in place. Now, it writes out a new file, consistent with all other manipulation scripts. --- tag_features.py | 74 ++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/tag_features.py b/tag_features.py index 671c2a1d..184df6fa 100755 --- a/tag_features.py +++ b/tag_features.py @@ -1,10 +1,11 @@ #!/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 @@ -17,50 +18,61 @@ 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) + + all_features['features'].append(feature) write_all_features(all_features, out_file_name, indent=4) From 139444647c933f2cdda99713143c822a28782704 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Thu, 29 Sep 2016 16:42:34 +0200 Subject: [PATCH 3/4] Update/add authors and last-modified --- combine_features.py | 2 +- difference_features.py | 2 +- fix_features_at_antimeridian.py | 2 +- fix_features_at_prime_meridian.py | 2 +- merge_features.py | 4 ++-- plot_features.py | 2 +- simplify_features.py | 2 +- split_features.py | 4 ++-- tag_features.py | 2 +- utils/feature_test_utils.py | 7 +++++++ utils/feature_write_utils.py | 8 ++++++++ 11 files changed, 26 insertions(+), 11 deletions(-) diff --git a/combine_features.py b/combine_features.py index b2f7f74e..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 diff --git a/difference_features.py b/difference_features.py index c0d01ae6..0a590aa5 100755 --- a/difference_features.py +++ b/difference_features.py @@ -8,7 +8,7 @@ (features.geojson by default). Authors: Xylar Asay-Davis -Last Modified: 02/12/2016 +Last Modified: 09/29/2016 """ import json diff --git a/fix_features_at_antimeridian.py b/fix_features_at_antimeridian.py index 38d52382..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 """ diff --git a/fix_features_at_prime_meridian.py b/fix_features_at_prime_meridian.py index 0def3892..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 """ diff --git a/merge_features.py b/merge_features.py index 0fe8ddad..66367115 100755 --- a/merge_features.py +++ b/merge_features.py @@ -16,8 +16,8 @@ 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 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 55a3aac1..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 diff --git a/split_features.py b/split_features.py index a35549e2..3096d5c1 100755 --- a/split_features.py +++ b/split_features.py @@ -6,8 +6,8 @@ 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 """ diff --git a/tag_features.py b/tag_features.py index 184df6fa..4054c5c5 100755 --- a/tag_features.py +++ b/tag_features.py @@ -8,7 +8,7 @@ the -o flag (features.geojson by default). Author: Xylar Asay-Davis -Last Modified: 2/11/2016 +Last Modified: 9/29/2016 """ import os.path diff --git a/utils/feature_test_utils.py b/utils/feature_test_utils.py index e84455c0..bca45784 100644 --- a/utils/feature_test_utils.py +++ b/utils/feature_test_utils.py @@ -1,5 +1,12 @@ #!/use/bin/env python +""" +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: diff --git a/utils/feature_write_utils.py b/utils/feature_write_utils.py index dd0b7eb4..44418d9f 100644 --- a/utils/feature_write_utils.py +++ b/utils/feature_write_utils.py @@ -1,4 +1,12 @@ #!/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 From ee7a01ee2648a7b3faa13003d19b75d6158a374b Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Thu, 29 Sep 2016 17:09:45 +0200 Subject: [PATCH 4/4] Update docstring, help in difference_features.py Docstring and help now state correctly that the features that the script supports multiple features to clip and multiple features as masks. --- difference_features.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/difference_features.py b/difference_features.py index 0a590aa5..0bd136c6 100755 --- a/difference_features.py +++ b/difference_features.py @@ -1,11 +1,11 @@ #!/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: 09/29/2016 @@ -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.",