Exemplo n.º 1
0
def split_features():
    '''
    Features in the collection are split into individual files in the
    geometric_data cache
    '''
    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("-f",
                        "--feature_file",
                        dest="feature_file",
                        help="File containing features to split up",
                        metavar="FILE",
                        required=True)
    parser.add_argument("-o",
                        "--output_dir",
                        dest="output_dir_name",
                        help="Output directory, default is determined by the "
                        "component property",
                        metavar="PATH",
                        default="./geometric_data")
    parser.add_argument('-v',
                        '--version',
                        action='version',
                        version='geometric_features {}'.format(
                            geometric_features.__version__),
                        help="Show version number and exit")
    args = parser.parse_args()

    fc = read_feature_collection(args.feature_file)
    gf = GeometricFeatures()
    gf.split(fc, args.output_dir_name)
    iceMask = numpy.logical_or(iceMask, bedMask)
    groundedMask = numpy.logical_or(groundedMask, bedMask)

    masks = dict()
    masks['AntarcticIceCoverage'] = iceMask
    masks['AntarcticGroundedIceCoverage'] = groundedMask
    fc = FeatureCollection()
    for name in masks:

        properties = dict()
        properties['name'] = name
        properties['component'] = 'bedmachine'
        properties['author'] = \
            'Morlighem et al. (2019) doi:10.1038/s41561-019-0510-8'
        properties['object'] = 'region'
        properties['tags'] = ''
        feature = dict()
        feature['properties'] = properties
        feature['geometry'] = extract_geometry(masks[name])
        fc.add_feature(feature)

    fc.to_geojson(out_file_name)

gf = GeometricFeatures(cacheLocation='./geometric_data')
gf.split(fc)
write_feature_names_and_tags(gf.cacheLocation)

os.rename('features_and_tags.json',
          'geometric_features/features_and_tags.json')
Exemplo n.º 3
0
def main():
    author = 'Milena Veneziani'

    # make a geometric features object that knows about the geometric data
    # cache up a couple of directories
    gf = GeometricFeatures(cacheLocation='../../geometric_data')

    fc = FeatureCollection()

    # ********* OSNAP array West *********

    # Read in OSNAP West lon,lat
    OSNAPwestLonLat = csv.reader(open('./OSNAParrayWest20210322.csv', 'r'))
    # Skip 4 header lines
    next(OSNAPwestLonLat, None)
    next(OSNAPwestLonLat, None)
    next(OSNAPwestLonLat, None)
    next(OSNAPwestLonLat, None)
    coords = []
    for line in OSNAPwestLonLat:
        coords.append([float(line[0]), float(line[1])])

    feature = {}
    feature['type'] = 'Feature'
    feature['properties'] = {}
    feature['properties']['name'] = 'OSNAP section West'
    feature['properties']['tags'] = 'arctic_sections'
    feature['properties']['object'] = 'transect'
    feature['properties']['component'] = 'ocean'
    feature['properties']['author'] = author
    feature['geometry'] = {}
    feature['geometry']['type'] = 'LineString'
    feature['geometry']['coordinates'] = coords
    fcOW = FeatureCollection([feature])
    fcOW.plot(projection='northpole')
    fc.merge(fcOW)

    # ********* OSNAP array East *********

    # Read in OSNAP East lon,lat
    OSNAPeastLonLat = csv.reader(open('./OSNAParrayEast20210322.csv', 'r'))
    # Skip 4 header lines
    next(OSNAPeastLonLat, None)
    next(OSNAPeastLonLat, None)
    next(OSNAPeastLonLat, None)
    next(OSNAPeastLonLat, None)
    coords = []
    for line in OSNAPeastLonLat:
        coords.append([float(line[0]), float(line[1])])

    feature = {}
    feature['type'] = 'Feature'
    feature['properties'] = {}
    feature['properties']['name'] = 'OSNAP section East'
    feature['properties']['tags'] = 'arctic_sections'
    feature['properties']['object'] = 'transect'
    feature['properties']['component'] = 'ocean'
    feature['properties']['author'] = author
    feature['geometry'] = {}
    feature['geometry']['type'] = 'LineString'
    feature['geometry']['coordinates'] = coords
    fcOE = FeatureCollection([feature])
    fcOE.plot(projection='northpole')
    fc.merge(fcOE)

    # "split" these features into individual files in the geometric data cache
    gf.split(fc)

    # update the database of feature names and tags
    write_feature_names_and_tags(gf.cacheLocation)
    # move the resulting file into place
    shutil.copyfile('features_and_tags.json',
                    '../../geometric_features/features_and_tags.json')

    plt.show()
Exemplo n.º 4
0
def main():
    author = 'Xylar Asay-Davis, Alice Barthel, Nicolas Jourdain'
    tags = 'Antarctic;ISMIP6'

    # make a geometric features object that knows about the geometric data
    # cache up a couple of directories
    gf = GeometricFeatures('../../geometric_data')

    bedmap2_bin_to_netcdf('bedmap2.nc')

    fcContour1500 = get_longest_contour(contourValue=-1500., author=author)

    fc = FeatureCollection()

    lons = [-65., -25., -25., -65.]
    lats = [-80., -80., -77., -71.]
    fc.merge(
        shelf_polygon(lons,
                      lats,
                      name='ISMIP6 Weddell Sea',
                      author=author,
                      tags=tags,
                      fcContour=fcContour1500))

    lons = [-128., -128., -90., -90.]
    lats = [-76., -69., -69., -76.]
    fc.merge(
        shelf_polygon(lons,
                      lats,
                      name='ISMIP6 Amundsen Sea',
                      author=author,
                      tags=tags,
                      fcContour=fcContour1500))

    lons = [45., 45., 90., 90.]
    lats = [-70., -60., -60., -70.]
    fc.merge(
        shelf_polygon(lons,
                      lats,
                      name='ISMIP6 Amery Sector',
                      author=author,
                      tags=tags,
                      fcContour=fcContour1500))

    lons = [-22.5, -22.5, 22.5, 22.5]
    lats = [-75., -65., -65., -75.]
    fc.merge(
        shelf_polygon(lons,
                      lats,
                      name='ISMIP6 Dronning Maud Land',
                      author=author,
                      tags=tags,
                      fcContour=fcContour1500))

    lons = [110., 110., 130., 130.]
    lats = [-70., -60., -60., -70.]
    fc.merge(
        shelf_polygon(lons,
                      lats,
                      name='ISMIP6 Totten Region',
                      author=author,
                      tags=tags,
                      fcContour=fcContour1500))

    lons = [165., 165., 180., 180.]
    lats = [-80., -71., -73., -80.]
    fc_ross = shelf_polygon(lons,
                            lats,
                            name='ISMIP6 Western Ross Sea',
                            author=author,
                            tags=tags,
                            fcContour=fcContour1500)

    lons = [-180., -180., -150., -150.]
    lats = [-80., -73., -77., -80.]
    fc_ross.merge(
        shelf_polygon(lons,
                      lats,
                      name='ISMIP6 Eastern Ross Sea',
                      author=author,
                      tags=tags,
                      fcContour=fcContour1500))

    old_props = fc_ross.features[0]['properties']
    fc_ross = fc_ross.combine('ISMIP6 Ross Sea')
    props = fc_ross.features[0]['properties']
    for prop in ['tags', 'zmin', 'zmax']:
        props[prop] = old_props[prop]

    fc.merge(fc_ross)

    fc.plot(projection='southpole')
    fc.to_geojson('ismip6_antarctic_ocean_regions.geojson')

    # "split" these features into individual files in the geometric data cache
    gf.split(fc)

    # update the database of feature names and tags
    write_feature_names_and_tags(gf.cacheLocation)
    # move the resulting file into place
    shutil.copyfile('features_and_tags.json',
                    '../../geometric_features/features_and_tags.json')

    plt.show()
Exemplo n.º 5
0
def main():
    author = 'Xylar Asay-Davis'
    timTags = 'Antarctic;Timmermann'
    orsiTags = 'Antarctic;Orsi'

    # make a geometric fieatures object that knows about the geometric data
    # cache up a couple of directories
    gf = GeometricFeatures('../../geometric_data')

    bedmap2_bin_to_netcdf('bedmap2.nc')

    fcContour700 = get_longest_contour(contourValue=-700., author=author)
    fcContour800 = get_longest_contour(contourValue=-800., author=author)

    fc = FeatureCollection()

    fcWeddell = split_rectangle(lon0=-63.,
                                lon1=0.,
                                lat0=-80.,
                                lat1=-65.,
                                name='Weddell Sea',
                                author=author,
                                tags=timTags,
                                fcContour=fcContour800)

    # get rid of the Weddell Sea because we're not that happy with this
    # definition, but keep the deep/shelf ones
    fcWeddell.features = fcWeddell.features[1:]
    fc.merge(fcWeddell)

    fcEW = split_rectangle(lon0=-20.,
                           lon1=25.,
                           lat0=-80.,
                           lat1=-55.,
                           name='Eastern Weddell Sea',
                           author=author,
                           tags=orsiTags,
                           fcContour=fcContour800)

    fc.merge(fcEW)

    fcWW = split_rectangle(lon0=-63.,
                           lon1=-20.,
                           lat0=-80.,
                           lat1=-60.,
                           name='Western Weddell Sea',
                           author=author,
                           tags=orsiTags,
                           fcContour=fcContour800)

    fc.merge(fcWW)

    # The Weddell feature is the sum of the Eastern and Western features before
    # splitting into shelf/deep

    fcWeddell = FeatureCollection()
    fcWeddell.features.append(fcEW.features[0])
    fcWeddell.features.append(fcWW.features[0])

    # now combine these into a single feature
    fcWeddell = fcWeddell.combine('Weddell Sea')
    props = fcWeddell.features[0]['properties']
    props['tags'] = orsiTags
    props['zmin'] = -1000.
    props['zmax'] = -400.

    fc.merge(fcWeddell)

    # add the Weddell Sea back as the sum of Eastern and Western
    fc.merge(
        make_rectangle(lon0=-63.,
                       lon1=45.,
                       lat0=-80.,
                       lat1=-58.,
                       name='Weddell Sea',
                       author=author,
                       tags=orsiTags))

    fc.merge(
        split_rectangle(lon0=-100.,
                        lon1=-63.,
                        lat0=-80.,
                        lat1=-67.,
                        name='Bellingshausen Sea',
                        author=author,
                        tags=timTags,
                        fcContour=fcContour700))

    fc.merge(
        split_rectangle(lon0=-140.,
                        lon1=-100.,
                        lat0=-80.,
                        lat1=-67.,
                        name='Amundsen Sea',
                        author=author,
                        tags=timTags,
                        fcContour=fcContour800))

    fc.merge(
        split_rectangle(lon0=-180.,
                        lon1=-140.,
                        lat0=-80.,
                        lat1=-67.,
                        name='Eastern Ross Sea',
                        author=author,
                        tags=timTags,
                        fcContour=fcContour700))

    fc.merge(
        split_rectangle(lon0=160.,
                        lon1=180.,
                        lat0=-80.,
                        lat1=-67.,
                        name='Western Ross Sea',
                        author=author,
                        tags=timTags,
                        fcContour=fcContour700))

    fc.merge(
        split_rectangle(lon0=25.,
                        lon1=160.,
                        lat0=-80.,
                        lat1=-62.,
                        name='East Antarctic Seas',
                        author=author,
                        tags=orsiTags,
                        fcContour=fcContour800))

    fc.merge(
        make_rectangle(lon0=-180.,
                       lon1=180.,
                       lat0=-80.,
                       lat1=-60.,
                       name='Southern Ocean 60S',
                       author=author,
                       tags=timTags))

    fcSO = gf.read('ocean', 'region', ['Southern Ocean'])
    props = fcSO.features[0]['properties']
    props['zmin'] = -1000.
    props['zmax'] = -400.

    fc.merge(fcSO)

    fc.plot(projection='southpole')
    fc.to_geojson('antarctic_ocean_regions.geojson')

    # "split" these features into individual files in the geometric data cache
    gf.split(fc)

    # update the database of feature names and tags
    write_feature_names_and_tags(gf.cacheLocation)
    # move the resulting file into place
    shutil.copyfile('features_and_tags.json',
                    '../../geometric_features/features_and_tags.json')

    plt.show()
Exemplo n.º 6
0
def main():
    author = 'Milena Veneziani'

    # make a geometric features object that knows about the geometric data
    # cache up a couple of directories
    gf = GeometricFeatures(cacheLocation='../../geometric_data')

    fc = FeatureCollection()

    # ********* New Hudson Bay (modified feature) *********

    # Extract Foxe Basin from Northwestern Passages, and merge it
    # to old Hudson Bay feature. Also combine Hudson Strait with
    # Hudson Bay. Note that the created feature needs to be further
    # edited by hand to eliminate a seem, due to Foxe Basin not
    # completely aligning with one side of the old Hudson Bay feature
    # (and this feature is not fixed by the last step in this script
    # either).
    fcCAA = gf.read('ocean', 'region', ['Northwestern Passages'])
    fcbox1 = make_rectangle(lon0=-84.3, lon1=-71.7, lat0=67.1, lat1=70.75,
                            name='Foxe Basin Box 1', author=author,
                            tags='Hudson_Bay;Arctic;Atlantic_Basin')
    fcbox2 = make_rectangle(lon0=-86., lon1=-71.7, lat0=63.5, lat1=67.1,
                            name='Foxe Basin Box 2', author=author,
                            tags='Hudson_Bay;Arctic;Atlantic_Basin')
    fcFoxe_tmp = fcbox1.difference(fcCAA)
    fcFoxe_tmp = fcbox1.difference(fcFoxe_tmp)
    fcFoxe = fcbox2.difference(fcCAA)
    fcFoxe = fcbox2.difference(fcFoxe)
    fcFoxe.merge(fcFoxe_tmp)
    fcFoxe = fcFoxe.combine('Foxe Basin')
    fcHudson = gf.read('ocean', 'region', ['Hudson Bay'])
    fcHudson.merge(gf.read('ocean', 'region', ['Hudson Strait']))
    fcHudson.merge(fcFoxe)
    fcHudson = fcHudson.combine('Hudson Bay')
    props = fcHudson.features[0]['properties']
    props['tags'] = 'Hudson Bay;Arctic;Atlantic_Basin'
    props['author'] = author
    fc = fcHudson

    # ********* New Canadian Archipelago (modified feature) *********

    # Remove Foxe Basin from Northwestern Passages and make new
    # Canadian Archipelago feature
    fcCAA = fcCAA.difference(fcFoxe)
    props = fcCAA.features[0]['properties']
    props['name'] = 'Canadian Archipelago'
    props['tags'] = 'Canadian_Archipelago;Arctic;Atlantic_Basin'
    props['author'] = author
    fc.merge(fcCAA)

    # ********* New Barents Sea (modified feature) *********
    # NOTE: this is dependent on existence of *old* features;
    #       in particular, the Barentsz_Sea feature will
    #       be removed after this script is applied

    # Combine Barentsz_Sea and White_Sea into new Barents Sea feature
    fcBS = gf.read('ocean', 'region', ['Barentsz Sea'])
    fcBS.merge(gf.read('ocean', 'region', ['White Sea']))
    fcBS = fcBS.combine('Barents Sea')
    props = fcBS.features[0]['properties']
    props['tags'] = 'Barents_Sea;Arctic;Arctic_NSIDC;Arctic_Basin'
    props['author'] = author
    fc.merge(fcBS)

    # ********* Kara Sea (unchanged feature) *********

    fcKara = gf.read('ocean', 'region', ['Kara Sea'])
    props = fcKara.features[0]['properties']
    props['tags'] = 'Kara_Sea;Arctic;Arctic_NSIDC;Arctic_Basin'
    fc.merge(fcKara)

    # ********* New Arctic Ocean (modified feature) *********
    # NOTE: this is dependent on existence of *old* features;
    #       in particular, the Arctic_Ocean, Chukchi_Sea,
    #       East_Siberian_Sea, and Laptev_Sea features will
    #       be superseded after this script is applied

    # Define triangle between Greenland Sea and Arctic_Ocean
    # (north of Fram Strait) that is not part of any of the
    # currently defined Arctic features
    fc_tmp = gf.read('ocean', 'region', ['Arctic Ocean'])
    fc_tmp.merge(gf.read('ocean', 'region', ['Lincoln Sea']))
    fc_tmp.merge(fcBS)
    fcArctic = make_rectangle(lon0=-36., lon1=20., lat0=86., lat1=79.,
        name='North of Fram Strait', author=author, tags='Arctic_Basin')
    fcArctic = fcArctic.difference(fc_tmp)

    # Define full Arctic *but* Barents and Kara Seas
    fcArctic.merge(gf.read('ocean', 'region', ['Arctic Ocean']))
    fcArctic.merge(gf.read('ocean', 'region', ['Laptev Sea']))
    fcArctic.merge(gf.read('ocean', 'region', ['East Siberian Sea']))
    fcArctic.merge(gf.read('ocean', 'region', ['Chukchi Sea']))
    fcArctic.merge(gf.read('ocean', 'region', ['Beaufort Sea']))
    fcArctic.merge(gf.read('ocean', 'region', ['Lincoln Sea']))
    fcArctic = fcArctic.combine('Arctic Ocean')
    props = fcArctic.features[0]['properties']
    props['tags'] = 'Arctic_Ocean;Arctic;Arctic_Basin'
    props['author'] = author
    fc.merge(fcArctic)

    # ********* Beaufort Gyre (entirely new feature) *********

    fcContour300 = get_longest_contour(contourValue=-300., author=author)
    fcBG_firstTry = make_rectangle(lon0=-170., lon1=-130., lat0=70.5, lat1=80.5,
                                   name='Beaufort Gyre', author=author,
                                   tags='Beaufort_Gyre;Arctic_Proshutinsky')
    fcBG = fcBG_firstTry.difference(fcContour300)
    fcBG = fcBG_firstTry.difference(fcBG)
    fc.merge(fcBG)

    # ********* New NSIDC Chukchi Sea (new feature) *********

    # Define Chukchi Sea as MASIE region #2 minus intersection with
    # Beaufort Gyre, and with Bering Strait transect as southern boundary
    fcChukchi = FeatureCollection()
    fcChukchi.add_feature(
        {"type": "Feature",
         "properties": {"name": 'Chukchi Sea NSIDC',
                        "author": author,
                        "object": 'region',
                        "component": 'ocean',
                        "tags": 'Chukchi_Sea_NSIDC;Arctic_NSIDC'},
         "geometry": {
             "type": "Polygon",
             "coordinates": [[[-167.15, 65.74],
                              [-168.01, 65.84],
                              [-168.62, 65.91],
                              [-169.43, 66.01],
                              [-170.24, 66.1],
                              [-180., 66.6],
                              [-180., 80.0],
                              [-156.48, 80.0],
                              [-156.65, 65.37],
                              [-167.15, 65.74]]]}})
    fcChukchi = fcChukchi.difference(fcBG)
    fc.merge(fcChukchi)

    # ********* Beaufort Gyre shelf (entirely new feature) *********

    # Define Beaufort Gyre shelf region, minus intersection with Chukchi Sea
    fcBGshelf_firstTry = make_rectangle(lon0=-170., lon1=-130.,
                                        lat0=68.0, lat1=80.5,
                                        name='Beaufort Gyre Shelf Box',
                                        author=author,
                                        tags='Beaufort_Gyre_Shelf;Arctic_Proshutinsky')
    fcBGshelf = fcBGshelf_firstTry.difference(fcContour300)
    fcBGshelf_secondTry = fcBGshelf_firstTry.difference(fcBG)
    fcBGshelf_secondTry = fcBGshelf_secondTry.difference(fcBGshelf)
    fcBGshelf.merge(fcBGshelf_secondTry)
    fcBGshelf = fcBGshelf.combine('Beaufort Gyre Shelf')
    fcBGshelf = fcBGshelf.difference(fcChukchi)
    props = fcBGshelf.features[0]['properties']
    props['name'] = 'Beaufort Gyre Shelf'
    props['author'] = author
    props['tags'] = 'Beaufort_Gyre_Shelf;Arctic_Proshutinsky'
    fc.merge(fcBGshelf)

    # ********* New NSIDC East Siberian Sea (new feature) *********

    # Define East Siberian Sea as MASIE region #3
    fcESS = FeatureCollection()
    fcESS = make_rectangle(lon0=180., lon1=145., lat0=67., lat1=80.,
                           name='East Siberian Sea NSIDC', author=author,
                           tags='East_Siberian_Sea_NSIDC;Arctic_NSIDC')
    fc.merge(fcESS)

    # ********* New NSIDC Laptev Sea (new feature) *********

    # Define Laptev Sea as MASIE region #4, minus intersection with
    # Kara Sea
    fcLap = FeatureCollection()
    fcLap.add_feature(
        {"type": "Feature",
         "properties": {"name": 'Laptev Sea NSIDC',
                        "author": author,
                        "object": 'region',
                        "component": 'ocean',
                        "tags": 'Laptev_Sea_NSIDC;Arctic_NSIDC'},
         "geometry": {
             "type": "Polygon",
             "coordinates": [[[145.,  68.],
                              [145.,  80.],
                              [95.4, 81.29],
                              [99.89, 78.27],
                              [102.,  72.],
                              [145.,  68.]]]}})
    fcLap = fcLap.difference(fcKara)
    fc.merge(fcLap)

    # ********* Central Arctic (entirely new feature) *********

    # Define Central Arctic region as New Arctic Ocean minus BG, BGshelf,
    # New Chukchi, New ESS, and New Laptev
    fcCentralArctic = fcArctic.difference(fcBG)
    fcCentralArctic = fcCentralArctic.difference(fcBGshelf)
    fcCentralArctic = fcCentralArctic.difference(fcChukchi)
    fcCentralArctic = fcCentralArctic.difference(fcESS)
    fcCentralArctic = fcCentralArctic.difference(fcLap)
    props = fcCentralArctic.features[0]['properties']
    props['name'] = 'Central Arctic'
    props['tags'] = 'Central_Arctic;Arctic;Arctic_Basin'
    props['author'] = author
    fc.merge(fcCentralArctic)

    # "split" these features into individual files in the geometric data cache
    gf.split(fc)

    # update the database of feature names and tags
    write_feature_names_and_tags(gf.cacheLocation)
    # move the resulting file into place
    shutil.copyfile('features_and_tags.json',
                    '../../geometric_features/features_and_tags.json')

    # Fix features if necessary
    fcArcticTags = gf.read(componentName='ocean', objectType='region',
                           tags=['Arctic'])
    for feature in fcArcticTags.features:
        featureName = feature['properties']['name']
        shape = shapely.geometry.shape(feature['geometry'])
        print('{} is_valid: {}'.format(featureName, shape.is_valid))
        if not shape.is_valid:
            fixed = shape.buffer(0)
            print('  Fixed? {}'.format(fixed.is_valid))
            feature['geometry'] = shapely.geometry.mapping(fixed)
    fcArcticNSIDCTags = gf.read(componentName='ocean', objectType='region',
                                tags=['Arctic_NSIDC'])
    for feature in fcArcticNSIDCTags.features:
        featureName = feature['properties']['name']
        shape = shapely.geometry.shape(feature['geometry'])
        print('{} is_valid: {}'.format(featureName, shape.is_valid))
        if not shape.is_valid:
            fixed = shape.buffer(0)
            print('  Fixed? {}'.format(fixed.is_valid))
            feature['geometry'] = shapely.geometry.mapping(fixed)

    fcArctic = fcArcticTags
    fcArctic.merge(fcArcticNSIDCTags)
    fcArctic.to_geojson('arctic_ocean_regions.geojson')
    fcArctic.plot(projection='northpole')

    # "split" these features into individual files in the geometric data cache
    gf.split(fcArctic)

    # update the database of feature names and tags
    write_feature_names_and_tags(gf.cacheLocation)
    # move the resulting file into place
    shutil.copyfile('features_and_tags.json',
                    '../../geometric_features/features_and_tags.json')

    plt.show()
def main():
    author = 'Milena Veneziani'

    # make a geometric features object that knows about the geometric data
    # cache up a couple of directories
    gf = GeometricFeatures(cacheLocation='../../geometric_data',
                           remoteBranchOrTag='master')

    fc = FeatureCollection()

    # *********** First, fix Atlantic_Basin regions in such a way that ********
    # **********  they do not overlap each other (so that, we can combine
    # *********   them together to form a Atlantic Basin region)

    # ********* New Baltic Sea (modified feature) *********

    # Combine old Baltic Sea feature with other small features
    fcBalticSea = gf.read('ocean', 'region', ['Baltic Sea'])
    fcFinland = gf.read('ocean', 'region', ['Gulf of Finland'])
    fcBothnia = gf.read('ocean', 'region', ['Gulf of Bothnia'])
    fcRiga = gf.read('ocean', 'region', ['Gulf of Riga'])
    fcKattegat = gf.read('ocean', 'region', ['Kattegat'])
    fcSkaggerak = gf.read('ocean', 'region', ['Skaggerak'])
    fcBalticSea.merge(fcFinland)
    fcBalticSea.merge(fcBothnia)
    fcBalticSea.merge(fcRiga)
    fcBalticSea.merge(fcKattegat)
    fcBalticSea.merge(fcSkaggerak)
    fcBalticSea = fcBalticSea.combine('Baltic Sea')
    props = fcBalticSea.features[0]['properties']
    props['tags'] = 'Baltic_Sea;Arctic;Atlantic_Basin'
    props['author'] = author
    fc = fcBalticSea

    # ********* New North Atlantic Ocean (modified feature) *********

    # Fix North Atlantic so that it does not overlap with new Labdrador
    # Sea, Irminger Sea, North Sea, Greenland Sea, and Norwegian Sea
    fcNorthAtlantic = gf.read('ocean', 'region', ['North Atlantic Ocean'])
    fcLabSea = gf.read('ocean', 'region', ['Labrador Sea'])
    fcIrmSea = gf.read('ocean', 'region', ['Irminger Sea'])
    fcGS = gf.read('ocean', 'region', ['Greenland Sea'])
    fcNS = gf.read('ocean', 'region', ['Norwegian Sea'])
    fcNorthSea = gf.read('ocean', 'region', ['North Sea'])
    fc_todiscard = fcLabSea
    fc_todiscard.merge(fcIrmSea)
    fc_todiscard.merge(fcGS)
    fc_todiscard.merge(fcNS)
    fc_todiscard.merge(fcNorthSea)
    fc_todiscard = fc_todiscard.combine('Combined region to discard')
    fcNorthAtlantic.merge(fc_todiscard)
    fcNorthAtlantic = fcNorthAtlantic.combine('North Atlantic Ocean')
    fcNorthAtlantic = fcNorthAtlantic.difference(fc_todiscard)
    props = fcNorthAtlantic.features[0]['properties']
    props['tags'] = 'North_Atlantic_Ocean;Atlantic_Basin'
    props['author'] = author
    fc.merge(fcNorthAtlantic)

    # *********** Second, complete definition of oceanography-relevant *********
    # **********  Arctic regions, started in part I, and identified with
    # *********   tag='Arctic'

    # ********* New Canadian Archipelago (modified feature) *********

    # Modify old CAA by 1) including the shelf in the Arctic Ocean, and
    # 2) including Nares Strait. Old CAA feature will be superseded by this.
    fcContour500 = get_longest_contour(contourValue=-500., author=author)
    fcContour1000 = get_longest_contour(contourValue=-1000., author=author)
    fcCAA1 = make_rectangle(lon0=-130.,
                            lon1=-90.,
                            lat0=67.0,
                            lat1=86.0,
                            name='West Canadian Archipelago',
                            author=author,
                            tags='Canadian_Archipelago;Arctic;Atlantic_Basin')
    fcCAA1 = fcCAA1.difference(fcContour500)
    fcCAA2 = make_rectangle(lon0=-90.,
                            lon1=-70.,
                            lat0=67.0,
                            lat1=86.0,
                            name='Mid Canadian Archipelago',
                            author=author,
                            tags='Canadian_Archipelago;Arctic;Atlantic_Basin')
    fcCAA2 = fcCAA2.difference(fcContour1000)
    fcCAA3 = make_rectangle(lon0=-70.,
                            lon1=-50.5,
                            lat0=76.0,
                            lat1=86.0,
                            name='East Canadian Archipelago',
                            author=author,
                            tags='Canadian_Archipelago;Arctic;Atlantic_Basin')
    fcCAA3 = fcCAA3.difference(fcContour500)
    fcCAA = fcCAA1
    fcCAA.merge(fcCAA2)
    fcCAA.merge(fcCAA3)
    fcCAA = fcCAA.combine('Canadian Archipelago')
    fcHudson = gf.read('ocean', 'region', ['Hudson Bay'])
    fcCAA = fcCAA.difference(fcHudson)
    fcBaffin = gf.read('ocean', 'region', ['Baffin Bay'])
    fcCAA = fcCAA.difference(fcBaffin)
    props = fcCAA.features[0]['properties']
    props['tags'] = 'Canadian_Archipelago;Arctic;Atlantic_Basin'
    props['author'] = author
    fc.merge(fcCAA)

    # ********* Canada Basin (new feature) *********

    # This is a slightly modified version of the Beaufort Gyre feature
    # defined in part I. Differences include 1) a region that expands to
    # the west to touch the northern boundary of the new CAA feature, and
    # 2) a region that includes the Canada Basin shelf (whereas, for the
    # Beuafort Gyre, we have separated the 'Gyre' from the 'Gyre Shelf').
    fcContour300 = get_longest_contour(contourValue=-300., author=author)
    fcCB1 = make_rectangle(lon0=-170.,
                           lon1=-156.65,
                           lat0=67.0,
                           lat1=80.0,
                           name='West Canada Basin',
                           author=author,
                           tags='Canada_Basin;Arctic;Arctic_Basin')
    fcCB = fcCB1.difference(fcContour300)
    fcCB = fcCB1.difference(fcCB)
    fcCB2 = make_rectangle(lon0=-156.65,
                           lon1=-100.0,
                           lat0=67.0,
                           lat1=80.0,
                           name='East Canada Basin',
                           author=author,
                           tags='Canada_Basin;Arctic;Arctic_Basin')
    fcCB2 = fcCB2.difference(fcCAA)
    fcCB.merge(fcCB2)
    fcCB = fcCB.combine('Canada Basin')
    props = fcCB.features[0]['properties']
    props['tags'] = 'Canada_Basin;Arctic;Arctic_Basin'
    props['author'] = author
    fc.merge(fcCB)

    # ********* Chukchi Sea (new feature) *********

    # This supersedes the old Chukchi Sea feature
    fcChukchi = make_rectangle(lon0=-180.,
                               lon1=-156.65,
                               lat0=65.0,
                               lat1=80.0,
                               name='Chukchi Sea',
                               author=author,
                               tags='Chukchi_Sea;Arctic;Arctic_Basin')
    fcChukchi = fcChukchi.difference(fcContour300)
    fcChukchi_NSIDC = gf.read('ocean', 'region', ['Chukchi Sea NSIDC'])
    fcChukchi_todiscard = fcChukchi.difference(fcChukchi_NSIDC)
    fcChukchi = fcChukchi.difference(fcChukchi_todiscard)
    props = fcChukchi.features[0]['properties']
    props['tags'] = 'Chukchi_Sea;Arctic;Arctic_Basin'
    props['author'] = author
    fc.merge(fcChukchi)

    # ********* East Siberian Sea (new feature) *********

    # This supersedes the old East Siberian Sea feature
    fcESS = make_rectangle(lon0=142.,
                           lon1=180.0,
                           lat0=68.5,
                           lat1=80.0,
                           name='East Siberian Sea',
                           author=author,
                           tags='East_Siberian_Sea;Arctic;Arctic_Basin')
    fcESS = fcESS.difference(fcContour300)
    props = fcESS.features[0]['properties']
    props['tags'] = 'East_Siberian_Sea;Arctic;Arctic_Basin'
    props['author'] = author
    fc.merge(fcESS)

    # ********* Laptev Sea (new feature) *********

    # This supersedes the old Laptev Sea feature
    fcLap = make_rectangle(lon0=90.,
                           lon1=142.0,
                           lat0=70.0,
                           lat1=81.25,
                           name='Laptev Sea',
                           author=author,
                           tags='Laptev_Sea;Arctic;Arctic_Basin')
    fcLap = fcLap.difference(fcContour300)
    fcKara = gf.read('ocean', 'region', ['Kara Sea'])
    fcLap = fcLap.difference(fcKara)
    props = fcLap.features[0]['properties']
    props['tags'] = 'Laptev_Sea;Arctic;Arctic_Basin'
    props['author'] = author
    fc.merge(fcLap)

    # ********* Central Arctic (new feature) *********

    # Define Central Arctic region as Arctic Ocean minus Canadian
    # Archipelago, Canada Basin, Chukchi Sea, ESS, and Laptev Sea
    fcArctic = gf.read('ocean', 'region', ['Arctic Ocean'])
    fcCentralArctic = fcArctic.difference(fcCAA)
    fcCentralArctic = fcCentralArctic.difference(fcCB)
    fcCentralArctic = fcCentralArctic.difference(fcChukchi)
    fcCentralArctic = fcCentralArctic.difference(fcESS)
    fcCentralArctic = fcCentralArctic.difference(fcLap)
    props = fcCentralArctic.features[0]['properties']
    props['name'] = 'Central Arctic'
    props['tags'] = 'Central_Arctic;Arctic;Arctic_Basin'
    props['author'] = author
    fc.merge(fcCentralArctic)

    # *********** Third, complete definition of seaice-relevant ***********
    # ***** Arctic regions, started in part I, according to NSIDC
    # ***** (regions map: https://nsidc.org/data/masie/browse_regions)
    # ****  and identified with tag='Arctic_NSIDC'

    # ********* New Chukchi Sea NSIDC (modified feature) *********

    # This supersedes the Chukchi Sea NSIDC feature defined in part I
    fcChukchi_NSIDC = FeatureCollection()
    fcChukchi_NSIDC.add_feature({
        "type": "Feature",
        "properties": {
            "name": 'Chukchi Sea NSIDC',
            "author": author,
            "object": 'region',
            "component": 'ocean',
            "tags": 'Chukchi_Sea_NSIDC;Arctic_NSIDC'
        },
        "geometry": {
            "type":
            "Polygon",
            "coordinates": [[[-156.65, 65.37], [-180.0, 66.0], [-180.0, 80.0],
                             [-156.48, 80.0], [-156.65, 65.37]]]
        }
    })
    fc.merge(fcChukchi_NSIDC)

    # ********* Beaufort Sea NSIDC (new feature) *********

    fcBS_NSIDC = FeatureCollection()
    fcBS_NSIDC.add_feature({
        "type": "Feature",
        "properties": {
            "name": 'Beaufort Sea NSIDC',
            "author": author,
            "object": 'region',
            "component": 'ocean',
            "tags": 'Beaufort_Sea_NSIDC;Arctic_NSIDC'
        },
        "geometry": {
            "type":
            "Polygon",
            "coordinates":
            [[[-156.65, 65.37], [-156.48, 80.0], [-112.34, 77.69],
              [-124.58, 75.67], [-124.0, 65.0], [-156.65, 65.37]]]
        }
    })
    fc.merge(fcBS_NSIDC)

    # ********* Canadian Archipelago NSIDC (new feature) *********

    fcCAA_NSIDC = FeatureCollection()
    fcCAA_NSIDC.add_feature({
        "type": "Feature",
        "properties": {
            "name": 'Canadian Archipelago NSIDC',
            "author": author,
            "object": 'region',
            "component": 'ocean',
            "tags": 'Canadian_Archipelago_NSIDC;Arctic_NSIDC'
        },
        "geometry": {
            "type":
            "Polygon",
            "coordinates":
            [[[-103.41, 60.69], [-124.0, 65.0], [-124.58, 75.67],
              [-112.34, 77.69], [-69.33, 82.67], [-81.21, 71.79],
              [-83.94, 70.43], [-84.45, 67.27], [-93.04, 65.70],
              [-103.41, 60.69]]]
        }
    })
    fc.merge(fcCAA_NSIDC)

    # ********* Hudson Bay NSIDC (new feature) *********

    fcHudson_NSIDC = FeatureCollection()
    fcHudson_NSIDC.add_feature({
        "type": "Feature",
        "properties": {
            "name": 'Hudson Bay NSIDC',
            "author": author,
            "object": 'region',
            "component": 'ocean',
            "tags": 'Hudson_Bay_NSIDC;Arctic_NSIDC'
        },
        "geometry": {
            "type":
            "Polygon",
            "coordinates": [[[-81.24, 49.19], [-103.41, 60.69],
                             [-93.04, 65.70], [-84.45, 67.27], [-83.94, 70.43],
                             [-81.21, 71.79], [-70.70, 66.95], [-70.12, 65.99],
                             [-63.70, 57.35], [-81.24, 49.19]]]
        }
    })
    fc.merge(fcHudson_NSIDC)

    # ********* Baffin Bay NSIDC (new feature) *********

    fcBaffin_NSIDC = FeatureCollection()
    fcBaffin_NSIDC.add_feature({
        "type": "Feature",
        "properties": {
            "name": 'Baffin Bay NSIDC',
            "author": author,
            "object": 'region',
            "component": 'ocean',
            "tags": 'Baffin_Bay_NSIDC;Arctic_NSIDC'
        },
        "geometry": {
            "type":
            "Polygon",
            "coordinates": [[[-53.20, 42.0], [-68.07, 38.38], [-76.82, 48.01],
                             [-60.85, 54.33], [-63.70, 57.35], [-70.12, 65.99],
                             [-70.70, 66.95], [-81.21, 71.79], [-69.33, 82.67],
                             [-45.0, 60.0], [-45.0, 42.0], [-53.20, 42.0]]]
        }
    })
    fc.merge(fcBaffin_NSIDC)

    # ********* Central Arctic NSIDC (new feature) *********

    fcCentralArctic_NSIDC = FeatureCollection()
    fcCentralArctic_NSIDC.add_feature({
        "type": "Feature",
        "properties": {
            "name": 'Central Arctic NSIDC',
            "author": author,
            "object": 'region',
            "component": 'ocean',
            "tags": 'Central_Arctic_NSIDC;Arctic_NSIDC'
        },
        "geometry": {
            "type":
            "Polygon",
            "coordinates": [[[180.0, 80.0], [180.0, 90.0], [-69.33, 90.0],
                             [-180.0, 90.0], [-180.0, 80.0], [-156.48, 80.0],
                             [-112.34, 77.69], [-69.33, 82.67],
                             [-51.66, 74.25], [-12.72, 81.41], [18.99, 79.18],
                             [58.68, 81.08], [94.95, 81.08], [145.0, 80.0],
                             [180.0, 80.0]]]
        }
    })
    fc.merge(fcCentralArctic_NSIDC)

    # "split" these features into individual files in the geometric data cache
    gf.split(fc)

    # update the database of feature names and tags
    write_feature_names_and_tags(gf.cacheLocation)
    # move the resulting file into place
    shutil.copyfile('features_and_tags.json',
                    '../../geometric_features/features_and_tags.json')

    # Fix features if necessary
    fcArcticTags = gf.read(componentName='ocean',
                           objectType='region',
                           tags=['Arctic'])
    for feature in fcArcticTags.features:
        featureName = feature['properties']['name']
        shape = shapely.geometry.shape(feature['geometry'])
        print('{} is_valid: {}'.format(featureName, shape.is_valid))
        if not shape.is_valid:
            fixed = shape.buffer(0)
            print('  Fixed? {}'.format(fixed.is_valid))
            feature['geometry'] = shapely.geometry.mapping(fixed)
    fcArcticTags.plot(projection='northpole')
    fcArcticTags.to_geojson('arctic_ocean_regions.geojson')

    fcArcticNSIDCTags = gf.read(componentName='ocean',
                                objectType='region',
                                tags=['Arctic_NSIDC'])
    for feature in fcArcticNSIDCTags.features:
        featureName = feature['properties']['name']
        shape = shapely.geometry.shape(feature['geometry'])
        print('{} is_valid: {}'.format(featureName, shape.is_valid))
        if not shape.is_valid:
            fixed = shape.buffer(0)
            print('  Fixed? {}'.format(fixed.is_valid))
            feature['geometry'] = shapely.geometry.mapping(fixed)
    fcArcticNSIDCTags.plot(projection='northpole')
    fcArcticNSIDCTags.to_geojson('arcticNSIDC_ocean_regions.geojson')

    fcArctic = fcArcticTags
    fcArctic.merge(fcArcticNSIDCTags)

    # "split" these features into individual files in the geometric data cache
    gf.split(fcArctic)

    # update the database of feature names and tags
    write_feature_names_and_tags(gf.cacheLocation)
    # move the resulting file into place
    shutil.copyfile('features_and_tags.json',
                    '../../geometric_features/features_and_tags.json')

    plt.show()