Esempio n. 1
0
def build_ocean_basins(gf, plot):
    '''
    Builds features defining the major ocean basins

    Parameters
    ----------
    gf : ``GeometricFeatures``
        An object that knows how to download and read geometric featuers

    plot : bool
        Whether to plot each basin

    Returns
    -------
    fc : ``FeatureCollection``
        The new feature collection
    '''
    # Authors
    # -------
    # Xylar Asay-Davis

    fc = FeatureCollection()
    fc.set_group_name(groupName='OceanBasinRegionsGroup')

    # build ocean basins from regions with the appropriate tags
    for oceanName in [
            'Atlantic', 'Pacific', 'Indian', 'Arctic', 'Southern_Ocean',
            'Mediterranean'
    ]:

        basinName = '{}_Basin'.format(oceanName)
        print(oceanName)

        print(' * merging features')
        fcBasin = gf.read(componentName='ocean',
                          objectType='region',
                          tags=[basinName])

        print(' * combining features')
        fcBasin = fcBasin.combine(featureName=basinName)

        fc.merge(fcBasin)

        if plot:
            fcBasin.plot(projection='cyl')
            plt.title(oceanName)

    # add the global ocean, global ocean between 65S and 65S, and
    # equatorial region
    fc.merge(
        gf.read(componentName='ocean',
                objectType='region',
                featureNames=[
                    'Global Ocean', 'Global Ocean 65N to 65S',
                    'Global Ocean 15S to 15N'
                ]))

    return fc
def make_ice_shelf_masks(gf):  # {{{
    iceShelfNames = [
        'Abbot', 'Amery', 'Atka', 'Aviator', 'Bach', 'Baudouin',
        'Borchgrevink', 'Brahms', 'Brunt_Stancomb', 'Campbell', 'Cheetham',
        'Conger_Glenzer', 'Cook', 'Cosgrove', 'Crosson', 'Dennistoun',
        'Dibble', 'Dotson', 'Drygalski', 'Edward_VIII', 'Ekstrom', 'Ferrigno',
        'Filchner', 'Fimbul', 'Fitzgerald', 'Frost', 'GeikieInlet',
        'George_VI', 'Getz', 'Gillet', 'Hamilton', 'Hannan', 'HarbordGlacier',
        'Helen', 'Holmes', 'HolmesWest', 'Hull', 'Jelbart', 'Land', 'Larsen_B',
        'Larsen_C', 'Larsen_D', 'Larsen_E', 'Larsen_F', 'Larsen_G', 'Lazarev',
        'Lillie', 'Mariner', 'Matusevitch', 'Mendelssohn', 'Mertz',
        'Moscow_University', 'Moubray', 'Mulebreen', 'Myers', 'Nansen',
        'Nickerson', 'Ninnis', 'Nivl', 'Noll', 'Nordenskjold', 'Pine_Island',
        'PourquoiPas', 'Prince_Harald', 'Publications', 'Quar', 'Rayner_Thyer',
        'Rennick', 'Richter', 'Riiser-Larsen', 'Ronne', 'Ross_East',
        'Ross_West', 'Shackleton', 'Shirase', 'Slava', 'SmithInlet', 'Stange',
        'Sulzberger', 'Suvorov', 'Swinburne', 'Thwaites', 'Tinker', 'Totten',
        'Tracy_Tremenchus', 'Tucker', 'Underwood', 'Utsikkar', 'Venable',
        'Verdi', 'Vigrid', 'Vincennes', 'Voyeykov', 'West', 'Wilkins',
        'Wilma_Robert_Downer', 'Withrow', 'Wordie', 'Wylde', 'Zubchatyy'
    ]

    combinedIceShelves = {
        'Filchner-Ronne': ['Filchner', 'Ronne'],
        'Ross': ['Ross_East', 'Ross_West'],
        'Antarctica': [
            'AntarcticPenninsulaIMBIE', 'WestAntarcticaIMBIE',
            'EastAntarcticaIMBIE'
        ],
        'Peninsula': ['AntarcticPenninsulaIMBIE'],
        'West Antarctica': ['WestAntarcticaIMBIE'],
        'East Antarctica': ['EastAntarcticaIMBIE']
    }

    nIMBIEBasins = 27
    for basinNumber in range(1, nIMBIEBasins + 1):
        basinName = 'Antarctica_IMBIE{}'.format(basinNumber)
        combinedIceShelves['IMBIE{}'.format(basinNumber)] = [basinName]

    # create a FeatureCollection containing all ice shelves and combined ice-shelf
    # regions
    fc = FeatureCollection()

    # build analysis regions from combining ice shelves from regions with the
    # appropriate tags
    for shelfName in combinedIceShelves:
        subNames = combinedIceShelves[shelfName]
        print(shelfName)

        print(' * merging features')
        fcShelf = gf.read(componentName='iceshelves',
                          objectType='region',
                          tags=subNames,
                          allTags=False)

        print(' * combining features')
        fcShelf = fcShelf.combine(featureName=shelfName)

        # merge the feature for the basin into the collection of all basins
        fc.merge(fcShelf)

    # build ice shelves from regions with the appropriate tags
    for shelfName in iceShelfNames:
        print(shelfName)

        print(' * merging features')
        fcShelf = gf.read(componentName='iceshelves',
                          objectType='region',
                          tags=[shelfName])

        print(' * combining features')
        fcShelf = fcShelf.combine(featureName=shelfName)

        # merge the feature for the basin into the collection of all basins
        fc.merge(fcShelf)

    return fc  # }}}
Esempio n. 3
0
fcSeed = gf.read(componentName='ocean',
                 objectType='point',
                 tags=['seed_point'])

if land_blockages:
    if options.with_critical_passages:
        # merge transects for critical land blockages into
        # critical_land_blockages.geojson
        fcCritBlockages = gf.read(componentName='ocean',
                                  objectType='transect',
                                  tags=['Critical_Land_Blockage'])
    else:
        fcCritBlockages = FeatureCollection()

    if options.custom_land_blockages is not None:
        fcCritBlockages.merge(
            read_feature_collection(options.custom_land_blockages))

    # create masks from the transects
    dsCritBlockMask = conversion.mask(dsBaseMesh, fcMask=fcCritBlockages)

    dsLandMask = add_critical_land_blockages(dsLandMask, dsCritBlockMask)

fcCritPassages = FeatureCollection()
dsPreserve = []

if critical_passages:
    if options.with_critical_passages:
        # merge transects for critical passages into critical_passages.geojson
        fcCritPassages.merge(
            gf.read(componentName='ocean',
                    objectType='transect',
Esempio n. 4
0
def build_MOC_basins(gf):
    '''
    Builds features defining the ocean basins used in computing the meridional
    overturning circulation (MOC)

    Parameters
    ----------
    gf : ``GeometricFeatures``
        An object that knows how to download and read geometric featuers

    Returns
    -------
    fc : ``FeatureCollection``
        The new feature collection
    '''
    # Authors
    # -------
    # Xylar Asay-Davis

    MOCSubBasins = {
        'Atlantic': ['Atlantic', 'Mediterranean'],
        'IndoPacific': ['Pacific', 'Indian'],
        'Pacific': ['Pacific'],
        'Indian': ['Indian']
    }

    MOCSouthernBoundary = {
        'Atlantic': '34S',
        'IndoPacific': '34S',
        'Pacific': '6S',
        'Indian': '6S'
    }

    fc = FeatureCollection()
    fc.set_group_name(groupName='MOCBasinRegionsGroup')

    # build MOC basins from regions with the appropriate tags
    for basinName in MOCSubBasins:

        print('{} MOC'.format(basinName))

        print(' * merging features')
        tags = ['{}_Basin'.format(basin) for basin in MOCSubBasins[basinName]]

        fcBasin = gf.read(componentName='ocean',
                          objectType='region',
                          tags=tags,
                          allTags=False)

        print(' * combining features')
        fcBasin = fcBasin.combine(featureName='{}_MOC'.format(basinName))

        print(' * masking out features south of MOC region')
        maskName = 'MOC mask {}'.format(MOCSouthernBoundary[basinName])
        fcMask = gf.read(componentName='ocean',
                         objectType='region',
                         featureNames=[maskName])
        # mask out the region covered by the mask
        fcBasin = fcBasin.difference(fcMask)

        # remove various small polygons that are not part of the main MOC
        # basin shapes.  Most are tiny but one below Australia is about 20
        # deg^2, so make the threshold 100 deg^2 to be on the safe side.
        fcBasin = remove_small_polygons(fcBasin, minArea=100.)

        # add this basin to the full feature collection
        fc.merge(fcBasin)

    return fc
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()
Esempio n. 6
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()
# create a GeometricFeatures object that points to a local cache of geometric
# data and knows which branch of geometric_feature to use to download
# missing data
gf = GeometricFeatures('./geometric_data')

# create a FeatureCollection containing all iceshelf regions wtih one of the
# 27 IMBIE basin tags tags
fc = FeatureCollection()
for basin in range(1, 28):
    print('Adding feature from IMBIE basin {:d}'.format(basin))
    basinName = 'Antarctica_IMBIE{:d}'.format(basin)
    tags = [basinName]
    # load the iceshelf regions for one IMBIE basin
    fcBasin = gf.read(componentName='iceshelves',
                      objectType='region',
                      tags=tags)

    # combine all regions in the basin into a single feature
    fcBasin = fcBasin.combine(featureName=basinName)

    # merge the feature for the basin into the collection of all basins
    fc.merge(fcBasin)

# save the feature collection to a geojson file
fc.to_geojson('Extended_Antarctic_Basins.geojson')

if plot:
    fc.plot(projection='southpole')
    plt.show()
Esempio n. 8
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()
Esempio n. 9
0
# appropriate tags
for shelfName in combinedIceShelves:
    subNames = combinedIceShelves[shelfName]
    print(shelfName)

    print(' * merging features')
    fcShelf = gf.read(componentName='iceshelves',
                      objectType='region',
                      tags=subNames,
                      allTags=False)

    print(' * combining features')
    fcShelf = fcShelf.combine(featureName=shelfName)

    # merge the feature for the basin into the collection of all basins
    fc.merge(fcShelf)

# build ice shelves from regions with the appropriate tags
for shelfName in iceShelfNames:
    print(shelfName)

    print(' * merging features')
    fcShelf = gf.read(componentName='iceshelves',
                      objectType='region',
                      tags=[shelfName])

    print(' * combining features')
    fcShelf = fcShelf.combine(featureName=shelfName)

    # merge the feature for the basin into the collection of all basins
    fc.merge(fcShelf)
Esempio n. 10
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()
Esempio n. 12
0
def _cull_mesh_with_logging(logger, with_cavities, with_critical_passages,
                            custom_critical_passages, custom_land_blockages,
                            preserve_floodplain, use_progress_bar,
                            process_count):
    """ Cull the mesh once the logger is defined for sure """

    critical_passages = with_critical_passages or \
        (custom_critical_passages is not None)

    land_blockages = with_critical_passages or \
        (custom_land_blockages is not None)

    gf = GeometricFeatures()

    # start with the land coverage from Natural Earth
    fcLandCoverage = gf.read(componentName='natural_earth',
                             objectType='region',
                             featureNames=['Land Coverage'])

    # remove the region south of 60S so we can replace it based on ice-sheet
    # topography
    fcSouthMask = gf.read(componentName='ocean', objectType='region',
                          featureNames=['Global Ocean 90S to 60S'])

    fcLandCoverage = fcLandCoverage.difference(fcSouthMask)

    # Add "land" coverage from either the full ice sheet or just the grounded
    # part
    if with_cavities:
        fcAntarcticLand = gf.read(
            componentName='bedmachine', objectType='region',
            featureNames=['AntarcticGroundedIceCoverage'])
    else:
        fcAntarcticLand = gf.read(
            componentName='bedmachine', objectType='region',
            featureNames=['AntarcticIceCoverage'])

    fcLandCoverage.merge(fcAntarcticLand)

    # save the feature collection to a geojson file
    fcLandCoverage.to_geojson('land_coverage.geojson')

    # these defaults may have been updated from config options -- pass them
    # along to the subprocess
    netcdf_format = mpas_tools.io.default_format
    netcdf_engine = mpas_tools.io.default_engine

    # Create the land mask based on the land coverage, i.e. coastline data
    args = ['compute_mpas_region_masks',
            '-m', 'base_mesh.nc',
            '-g', 'land_coverage.geojson',
            '-o', 'land_mask.nc',
            '-t', 'cell',
            '--process_count', '{}'.format(process_count),
            '--format', netcdf_format,
            '--engine', netcdf_engine]
    check_call(args, logger=logger)

    dsBaseMesh = xarray.open_dataset('base_mesh.nc')
    dsLandMask = xarray.open_dataset('land_mask.nc')
    dsLandMask = add_land_locked_cells_to_mask(dsLandMask, dsBaseMesh,
                                               latitude_threshold=43.0,
                                               nSweeps=20)

    # create seed points for a flood fill of the ocean
    # use all points in the ocean directory, on the assumption that they are,
    # in fact, in the ocean
    fcSeed = gf.read(componentName='ocean', objectType='point',
                     tags=['seed_point'])

    if land_blockages:
        if with_critical_passages:
            # merge transects for critical land blockages into
            # critical_land_blockages.geojson
            fcCritBlockages = gf.read(
                componentName='ocean', objectType='transect',
                tags=['Critical_Land_Blockage'])
        else:
            fcCritBlockages = FeatureCollection()

        if custom_land_blockages is not None:
            fcCritBlockages.merge(read_feature_collection(
                custom_land_blockages))

        # create masks from the transects
        fcCritBlockages.to_geojson('critical_blockages.geojson')
        args = ['compute_mpas_transect_masks',
                '-m', 'base_mesh.nc',
                '-g', 'critical_blockages.geojson',
                '-o', 'critical_blockages.nc',
                '-t', 'cell',
                '-s', '10e3',
                '--process_count', '{}'.format(process_count),
                '--format', netcdf_format,
                '--engine', netcdf_engine]
        check_call(args, logger=logger)
        dsCritBlockMask = xarray.open_dataset('critical_blockages.nc')

        dsLandMask = add_critical_land_blockages(dsLandMask, dsCritBlockMask)

    fcCritPassages = FeatureCollection()
    dsPreserve = []

    if critical_passages:
        if with_critical_passages:
            # merge transects for critical passages into fcCritPassages
            fcCritPassages.merge(gf.read(componentName='ocean',
                                         objectType='transect',
                                         tags=['Critical_Passage']))

        if custom_critical_passages is not None:
            fcCritPassages.merge(read_feature_collection(
                custom_critical_passages))

        # create masks from the transects
        fcCritPassages.to_geojson('critical_passages.geojson')
        args = ['compute_mpas_transect_masks',
                '-m', 'base_mesh.nc',
                '-g', 'critical_passages.geojson',
                '-o', 'critical_passages.nc',
                '-t', 'cell', 'edge',
                '-s', '10e3',
                '--process_count', '{}'.format(process_count),
                '--format', netcdf_format,
                '--engine', netcdf_engine]
        check_call(args, logger=logger)
        dsCritPassMask = xarray.open_dataset('critical_passages.nc')

        # Alter critical passages to be at least two cells wide, to avoid sea
        # ice blockage
        dsCritPassMask = widen_transect_edge_masks(dsCritPassMask, dsBaseMesh,
                                                   latitude_threshold=43.0)

        dsPreserve.append(dsCritPassMask)

    if preserve_floodplain:
        dsPreserve.append(dsBaseMesh)

    # cull the mesh based on the land mask
    dsCulledMesh = cull(dsBaseMesh, dsMask=dsLandMask,
                        dsPreserve=dsPreserve, logger=logger)

    # create a mask for the flood fill seed points
    dsSeedMask = compute_mpas_flood_fill_mask(dsMesh=dsCulledMesh,
                                              fcSeed=fcSeed,
                                              logger=logger)

    # cull the mesh a second time using a flood fill from the seed points
    dsCulledMesh = cull(dsCulledMesh, dsInverse=dsSeedMask,
                        graphInfoFileName='culled_graph.info', logger=logger)
    write_netcdf(dsCulledMesh, 'culled_mesh.nc')

    if critical_passages:
        # make a new version of the critical passages mask on the culled mesh
        fcCritPassages.to_geojson('critical_passages.geojson')
        args = ['compute_mpas_transect_masks',
                '-m', 'culled_mesh.nc',
                '-g', 'critical_passages.geojson',
                '-o', 'critical_passages_mask_final.nc',
                '-t', 'cell',
                '-s', '10e3',
                '--process_count', '{}'.format(process_count),
                '--format', netcdf_format,
                '--engine', netcdf_engine]
        check_call(args, logger=logger)

    if with_cavities:
        fcAntarcticIce = gf.read(
            componentName='bedmachine', objectType='region',
            featureNames=['AntarcticIceCoverage'])

        fcAntarcticIce.to_geojson('ice_coverage.geojson')
        args = ['compute_mpas_region_masks',
                '-m', 'culled_mesh.nc',
                '-g', 'ice_coverage.geojson',
                '-o', 'ice_coverage.nc',
                '-t', 'cell',
                '--process_count', '{}'.format(process_count),
                '--format', netcdf_format,
                '--engine', netcdf_engine]
        check_call(args, logger=logger)
        dsMask = xarray.open_dataset('ice_coverage.nc')

        landIceMask = dsMask.regionCellMasks.isel(nRegions=0)
        dsLandIceMask = xarray.Dataset()
        dsLandIceMask['landIceMask'] = landIceMask

        write_netcdf(dsLandIceMask, 'land_ice_mask.nc')

        dsLandIceCulledMesh = cull(dsCulledMesh, dsMask=dsMask, logger=logger)
        write_netcdf(dsLandIceCulledMesh, 'no_ISC_culled_mesh.nc')

    extract_vtk(ignore_time=True, dimension_list=['maxEdges='],
                variable_list=['allOnCells'],
                filename_pattern='culled_mesh.nc',
                out_dir='culled_mesh_vtk',
                use_progress_bar=use_progress_bar)

    if with_cavities:
        extract_vtk(ignore_time=True, dimension_list=['maxEdges='],
                    variable_list=['allOnCells'],
                    filename_pattern='no_ISC_culled_mesh.nc',
                    out_dir='no_ISC_culled_mesh_vtk',
                    use_progress_bar=use_progress_bar)