xopr.geometry

Geospatial operations for radar datasets

This module provides utilities for working with geospatial data in the context of polar radar analysis. It includes functions for:

  • Loading and filtering Antarctic regional boundaries from the MEaSUREs dataset
  • Projecting radar dataset coordinates between different coordinate reference systems
  • Reprojecting GeoJSON geometries for spatial analysis

The module handles common polar coordinate system transformations, particularly between WGS84 (EPSG:4326) and Antarctic Polar Stereographic (EPSG:3031), and provides tools for merging and simplifying regional boundaries.

Functions

get_antarctic_regions : Load and filter Antarctic regional boundaries get_greenland_regions : Load and filter Greenland regional boundaries project_dataset : Project dataset coordinates to a target CRS project_geojson : Reproject geometries between coordinate systems

See Also

MEaSUREs, Antarctic, Boundaries: https://nsidc.org/data/nsidc-0709/versions/2
EPSG: 3031 (Antarctic Polar Stereographic): https://epsg.io/3031

  1"""
  2Geospatial operations for radar datasets
  3
  4This module provides utilities for working with geospatial data in the context
  5of polar radar analysis. It includes functions for:
  6
  7- Loading and filtering Antarctic regional boundaries from the MEaSUREs dataset
  8- Projecting radar dataset coordinates between different coordinate reference systems
  9- Reprojecting GeoJSON geometries for spatial analysis
 10
 11The module handles common polar coordinate system transformations, particularly
 12between WGS84 (EPSG:4326) and Antarctic Polar Stereographic (EPSG:3031), and
 13provides tools for merging and simplifying regional boundaries.
 14
 15Functions
 16---------
 17get_antarctic_regions : Load and filter Antarctic regional boundaries
 18get_greenland_regions : Load and filter Greenland regional boundaries
 19project_dataset : Project dataset coordinates to a target CRS
 20project_geojson : Reproject geometries between coordinate systems
 21
 22See Also
 23--------
 24MEaSUREs Antarctic Boundaries: https://nsidc.org/data/nsidc-0709/versions/2
 25EPSG:3031 (Antarctic Polar Stereographic): https://epsg.io/3031
 26"""
 27
 28import geopandas as gpd
 29import shapely
 30import shapely.ops
 31from pyproj import Transformer
 32
 33
 34def get_antarctic_regions(
 35    name=None,
 36    region=None,
 37    subregion=None,
 38    type=None,
 39    merge_regions=True,
 40    merge_in_projection="EPSG:3031",
 41    simplify_tolerance=None,
 42    regions=None, # Deprecated alias for "region"
 43    subregions=None # Deprecated alias for "subregion"
 44):
 45    """
 46    Load and filter Antarctic regional boundaries from the MEaSUREs dataset.
 47
 48    The data product is derived from:
 49
 50    > Maps of Antarctic ice shelves, the Antarctic coastline and Antarctic basins. The maps are assembled from 2008-2009 ice-front data from ALOS PALSAR and ENVISAT ASAR data acquired during International Polar Year, 2007-2009 (IPY), the InSAR-based grounding line data (MEaSUREs Antarctic Grounding Line from Differential Satellite Radar Interferometry), augmented with other grounding line sources, the Antarctic ice velocity map (MEaSUREs InSAR-Based Antarctica Ice Velocity Map), and the Bedmap-2 DEM.
 51    >
 52    > This data set is part of the NASA Making Earth System Data Records for Use in Research Environments (MEaSUREs) program.
 53    >
 54    > Mouginot, J., B. Scheuchl, and E. Rignot. 2017. MEaSUREs Antarctic Boundaries for IPY 2007-2009 from Satellite Radar, Version 2. [Indicate subset used]. Boulder, Colorado USA. NASA National Snow and Ice Data Center Distributed Active Archive Center. doi: http://dx.doi.org/10.5067/AXE4121732AD. [Date Accessed].
 55    >
 56    > https://nsidc.org/data/nsidc-0709/versions/2
 57
 58    See these two notebooks for examples of how to use this function:
 59    - https://docs.englacial.org/xopr/search-and-scaling/
 60    - https://docs.englacial.org/xopr/crossovers/
 61
 62    Parameters
 63    ----------
 64    name : str or list, optional
 65        NAME field value(s) to filter by
 66    region : str or list, optional
 67        REGION field value(s) to filter by
 68    subregion : str or list, optional
 69        SUBREGION field value(s) to filter by
 70    type : str or list, optional
 71        TYPE field value(s) to filter by
 72    merge_regions : bool, default True
 73        If True, return a single merged geometry; if False, return list of geometries
 74    measures_boundaries_url : str, default "https://storage.googleapis.com/opr_stac/reference_geometry/measures_boundaries_4326.geojson"
 75        URL to the GeoJSON file containing Antarctic region boundaries
 76
 77    Returns
 78    -------
 79    list or dict
 80        If merge_regions=False: List of GeoJSON geometry dicts
 81        If merge_regions=True: Single GeoJSON geometry dict of merged regions
 82
 83    Examples
 84    --------
 85    # Get George VI ice shelf
 86    >>> george_vi = get_antarctic_regions(name="George_VI", type="FL")
 87
 88    # Get all ice shelves, merged into one geometry
 89    >>> all_shelves = get_antarctic_regions(type="FL", merge_regions=True)
 90
 91    # Get multiple regions by name
 92    >>> regions = get_antarctic_regions(name=["George_VI", "LarsenC"])
 93    """
 94
 95    if regions is not None:
 96        print("Warning: 'regions' parameter is deprecated; use 'region' instead.")
 97        if region is not None:
 98            raise ValueError("Cannot use both 'regions' and 'region' parameters.")
 99        region = regions
100    if subregions is not None:
101        print("Warning: 'subregions' parameter is deprecated; use 'subregion' instead.")
102        if subregion is not None:
103            raise ValueError("Cannot use both 'subregions' and 'subregion' parameters.")
104        subregion = subregions
105
106    return _get_regions(
107        name=name,
108        region=region,
109        subregion=subregion,
110        type=type,
111        merge_regions=merge_regions,
112        regions_geojson_url="https://storage.googleapis.com/opr_stac/reference_geometry/measures_boundaries_4326.geojson",
113        merge_in_projection=merge_in_projection,
114        simplify_tolerance=simplify_tolerance
115    )
116
117def get_greenland_regions(
118    name=None,
119    region=None,
120    subregion=None,
121    type=None,
122    merge_regions=True,
123    merge_in_projection="EPSG:3413",
124    simplify_tolerance=None,
125):
126    """
127    Load and filter Greenland regional boundaries as defined by the GrIMP project
128
129    The data product is derived from:
130
131    > We divide Greenland, including its peripheral glaciers and ice caps, into 260 basins grouped in seven regions:  southwest (SW), central west (CW), (iii) northwest (NW), north (NO), northeast (NE), central east (CE), and southeast (SE). These regions are selected based on ice flow regimes, climate, and the need to partition the ice sheet into zones comparable in size (200,000 km2 to 400,000 km2) and ice production (50 Gt/y to 100 Gt/y, or billion tons per year). Out of the 260 surveyed glaciers, 217 are marine-terminating, i.e., calving into icebergs and melting in contact with ocean waters, and 43 are land-terminating.The actual number of land-terminating glaciers is far larger than 43, but we lump them into larger units for simplification.
132    >
133    > Each glacier catchment is defined using a combination of ice flow direction and surface slope. In areas of fast flow (> 100 m), we use a composite velocity mosaic (Mouginot et al. 2017). In slowmoving areas, we use surface slope using the GIMP DEM (https://nsidc.org/data/nsidc- 0715/versions/1) (Howat et al. 2014) smoothed over 10 ice thicknesses to remove shortwavelength undulations.
134    >
135    > References:
136    >
137    > Mouginot J, Rignot E, Scheuchl B, Millan R (2017) Comprehensive annual ice sheet velocity mapping using landsat-8, sentinel-1, and radarsat-2 data. Remote Sensing 9(4).
138    >
139    > Howat IM, Negrete A, Smith BE (2014) The greenland ice mapping project (GIMP) land classification and surface elevation data sets. The Cryosphere 8(4):1509–1518.
140    >
141    > https://datadryad.org/dataset/doi:10.7280/D1WT11
142
143    Parameters
144    ----------
145    name : str or list, optional
146        NAME field value(s) to filter by
147    region : str or list, optional
148        REGION field value(s) to filter by
149    subregion : str or list, optional
150        SUBREGION field value(s) to filter by
151    type : str or list, optional
152        TYPE field value(s) to filter by
153    merge_regions : bool, default True
154        If True, return a single merged geometry; if False, return list of geometries
155    measures_boundaries_url : str, default "https://storage.googleapis.com/opr_stac/reference_geometry/measures_boundaries_4326.geojson"
156        URL to the GeoJSON file containing Antarctic region boundaries
157
158    Returns
159    -------
160    list or dict
161        If merge_regions=False: List of GeoJSON geometry dicts
162        If merge_regions=True: Single GeoJSON geometry dict of merged regions
163    """
164
165    greenland_boundaries_url = "https://storage.googleapis.com/opr_stac/reference_geometry/greenland_boundaries_4326.geojson"
166
167    return _get_regions(
168        name=name,
169        region=region,
170        subregion=subregion,
171        type=type,
172        merge_regions=merge_regions,
173        regions_geojson_url=greenland_boundaries_url,
174        merge_in_projection=merge_in_projection,
175        simplify_tolerance=simplify_tolerance
176    )
177
178
179def _get_regions(
180    name=None,
181    region=None,
182    subregion=None,
183    type=None,
184    merge_regions=True,
185    regions_geojson_url = None,
186    merge_in_projection=None,
187    simplify_tolerance=None
188):
189    if regions_geojson_url is None:
190        raise ValueError("regions_geojson_url must be provided")
191
192    if merge_in_projection is None:
193        raise ValueError("merge_in_projection must be provided")
194
195    # Load the boundaries GeoJSON from the reference URL
196    filtered = gpd.read_file(regions_geojson_url)
197
198    standard_columns = {
199        'NAME': ['NAME', 'NAMES'],
200        'REGION': ['REGION', 'Regions'],
201        'SUBREGION': ['SUBREGION', 'Subregions'],
202        'TYPE': ['TYPE', 'TYPES', 'GL_TYPE']
203    }
204
205    # Standardize column names
206    for standard_name, possible_names in standard_columns.items():
207        for col in possible_names:
208            if col in filtered.columns:
209                filtered = filtered.rename(columns={col: standard_name})
210                break
211
212    # Apply filters based on provided parameters
213    if name is not None:
214        if isinstance(name, str):
215            name = [name]
216        filtered = filtered[filtered['NAME'].isin(name)]
217
218    if region is not None:
219        if isinstance(region, str):
220            region = [region]
221        filtered = filtered[filtered['REGION'].isin(region)]
222
223    if subregion is not None:
224        if isinstance(subregion, str):
225            subregion = [subregion]
226        filtered = filtered[filtered['SUBREGION'].isin(subregion)]
227
228    if type is not None:
229        if isinstance(type, str):
230            type = [type]
231        filtered = filtered[filtered['TYPE'].isin(type)]
232
233    if len(filtered) == 0:
234        return [] if not merge_regions else None
235
236    if merge_regions:
237
238        if merge_in_projection:
239            filtered = filtered.to_crs(merge_in_projection)
240
241        # Check for invalid regions and attempt to fix them
242        invalid_geometries = filtered[~filtered.is_valid]
243        if len(invalid_geometries) > 0:
244            filtered = filtered.make_valid()
245            print(f"Warning: {len(invalid_geometries)} invalid geometries were fixed before merging.")
246            if merge_in_projection != "EPSG:3031":
247                print("Consider using merge_in_projection='EPSG:3031' to reproject before merging.")
248            print(f"Invalid geometry regions were: {', '.join(invalid_geometries['NAME'])}")
249
250        merged = shapely.ops.unary_union(filtered.geometry)  # geopandas < 1.0 compat
251
252        if simplify_tolerance is None and (merge_in_projection is not None): # Set a reasonable default based on the size
253            area_km2 = merged.area / 1e6
254            if area_km2 < 10000:
255                simplify_tolerance = 0
256            elif area_km2 < 100000:
257                print(f"Area is {area_km2:.1f} km^2, automatically applying 100m simplification tolerance")
258                print(f"To disable simplification, set simplify_tolerance=0")
259                simplify_tolerance = 100
260            else:
261                print(f"Area is {area_km2:.1f} km^2, automatically applying 1km simplification tolerance")
262                print(f"To disable simplification, set simplify_tolerance=0")
263                simplify_tolerance = 1000
264
265        if simplify_tolerance and (simplify_tolerance > 0):
266            merged = shapely.buffer(merged, simplify_tolerance).simplify(tolerance=simplify_tolerance)
267
268        if merge_in_projection:
269            merged = project_geojson(merged, source_crs=merge_in_projection, target_crs="EPSG:4326")
270
271        return merged
272    else:
273        return filtered
274
275def project_dataset(ds, target_crs):
276    """
277    Project dataset coordinates from WGS84 to a target coordinate reference system.
278
279    Takes longitude and latitude coordinates from a dataset and projects them to
280    the specified target CRS, adding 'x' and 'y' coordinate arrays to the dataset.
281
282    Parameters
283    ----------
284    ds : xarray.Dataset
285        Input dataset containing 'Longitude' and 'Latitude' coordinates
286    target_crs : cartopy.crs.CRS or str
287        Target coordinate reference system. Can be a cartopy CRS object or
288        a string representation (e.g., "EPSG:3031")
289
290    Returns
291    -------
292    xarray.Dataset
293        Dataset with added 'x' and 'y' coordinate arrays in the target CRS
294
295    Examples
296    --------
297    >>> import cartopy.crs as ccrs
298    >>> projected_ds = project_dataset(ds, ccrs.SouthPolarStereo(true_scale_latitude=-71))
299    >>> projected_ds = project_dataset(ds, "EPSG:3031")
300    """
301    if hasattr(target_crs, 'to_epsg') and target_crs.to_epsg():
302        target_crs_str = f"EPSG:{target_crs.to_epsg()}"
303    elif isinstance(target_crs, str):
304        target_crs_str = target_crs
305    else:
306        target_crs_str = target_crs.to_proj4_string()
307
308    transformer = Transformer.from_crs("EPSG:4326", target_crs_str, always_xy=True)
309    projected_coords = transformer.transform(ds['Longitude'].values, ds['Latitude'].values)
310
311    ds = ds.assign_coords({
312        'x': (('slow_time'), projected_coords[0]),
313        'y': (('slow_time'), projected_coords[1])
314    })
315    return ds
316
317def project_geojson(geometry, source_crs="EPSG:4326", target_crs=None):
318    """
319    Project a geometry from one coordinate reference system to another.
320
321    Uses pyproj.Transformer to reproject geometries between different
322    coordinate reference systems. Commonly used for projecting geometries
323    from WGS84 (lat/lon) to polar stereographic projections.
324
325    Parameters
326    ----------
327    geometry : shapely.geometry.base.BaseGeometry
328        Input geometry to be projected
329    source_crs : str, default "EPSG:4326"
330        Source coordinate reference system (default is WGS84)
331    target_crs : str, default None
332        Target coordinate reference system. If None, automatically selects
333        Antarctic Polar Stereographic (EPSG:3031) for southern hemisphere
334        and Arctic Polar Stereographic (EPSG:3413) for northern hemisphere based on
335        the geometry's centroid latitude.
336
337    Returns
338    -------
339    shapely.geometry.base.BaseGeometry
340        Projected geometry in the target coordinate reference system
341
342    Examples
343    --------
344    >>> from shapely.geometry import Point
345    >>> point = Point(-70, -75)  # lon, lat in WGS84
346    >>> projected = project_geojson(point, "EPSG:4326", "EPSG:3031")
347    """
348
349    if target_crs is None:
350        if geometry.centroid.y < 0:
351            target_crs = "EPSG:3031"  # Antarctic Polar Stereographic
352        else:
353            target_crs = "EPSG:3413"  # Arctic Polar Stereographic
354
355    transformer = Transformer.from_crs(source_crs, target_crs, always_xy=True)
356    projected_geometry = shapely.ops.transform(transformer.transform, geometry)
357    return projected_geometry
def get_antarctic_regions( name=None, region=None, subregion=None, type=None, merge_regions=True, merge_in_projection='EPSG:3031', simplify_tolerance=None, regions=None, subregions=None):
 35def get_antarctic_regions(
 36    name=None,
 37    region=None,
 38    subregion=None,
 39    type=None,
 40    merge_regions=True,
 41    merge_in_projection="EPSG:3031",
 42    simplify_tolerance=None,
 43    regions=None, # Deprecated alias for "region"
 44    subregions=None # Deprecated alias for "subregion"
 45):
 46    """
 47    Load and filter Antarctic regional boundaries from the MEaSUREs dataset.
 48
 49    The data product is derived from:
 50
 51    > Maps of Antarctic ice shelves, the Antarctic coastline and Antarctic basins. The maps are assembled from 2008-2009 ice-front data from ALOS PALSAR and ENVISAT ASAR data acquired during International Polar Year, 2007-2009 (IPY), the InSAR-based grounding line data (MEaSUREs Antarctic Grounding Line from Differential Satellite Radar Interferometry), augmented with other grounding line sources, the Antarctic ice velocity map (MEaSUREs InSAR-Based Antarctica Ice Velocity Map), and the Bedmap-2 DEM.
 52    >
 53    > This data set is part of the NASA Making Earth System Data Records for Use in Research Environments (MEaSUREs) program.
 54    >
 55    > Mouginot, J., B. Scheuchl, and E. Rignot. 2017. MEaSUREs Antarctic Boundaries for IPY 2007-2009 from Satellite Radar, Version 2. [Indicate subset used]. Boulder, Colorado USA. NASA National Snow and Ice Data Center Distributed Active Archive Center. doi: http://dx.doi.org/10.5067/AXE4121732AD. [Date Accessed].
 56    >
 57    > https://nsidc.org/data/nsidc-0709/versions/2
 58
 59    See these two notebooks for examples of how to use this function:
 60    - https://docs.englacial.org/xopr/search-and-scaling/
 61    - https://docs.englacial.org/xopr/crossovers/
 62
 63    Parameters
 64    ----------
 65    name : str or list, optional
 66        NAME field value(s) to filter by
 67    region : str or list, optional
 68        REGION field value(s) to filter by
 69    subregion : str or list, optional
 70        SUBREGION field value(s) to filter by
 71    type : str or list, optional
 72        TYPE field value(s) to filter by
 73    merge_regions : bool, default True
 74        If True, return a single merged geometry; if False, return list of geometries
 75    measures_boundaries_url : str, default "https://storage.googleapis.com/opr_stac/reference_geometry/measures_boundaries_4326.geojson"
 76        URL to the GeoJSON file containing Antarctic region boundaries
 77
 78    Returns
 79    -------
 80    list or dict
 81        If merge_regions=False: List of GeoJSON geometry dicts
 82        If merge_regions=True: Single GeoJSON geometry dict of merged regions
 83
 84    Examples
 85    --------
 86    # Get George VI ice shelf
 87    >>> george_vi = get_antarctic_regions(name="George_VI", type="FL")
 88
 89    # Get all ice shelves, merged into one geometry
 90    >>> all_shelves = get_antarctic_regions(type="FL", merge_regions=True)
 91
 92    # Get multiple regions by name
 93    >>> regions = get_antarctic_regions(name=["George_VI", "LarsenC"])
 94    """
 95
 96    if regions is not None:
 97        print("Warning: 'regions' parameter is deprecated; use 'region' instead.")
 98        if region is not None:
 99            raise ValueError("Cannot use both 'regions' and 'region' parameters.")
100        region = regions
101    if subregions is not None:
102        print("Warning: 'subregions' parameter is deprecated; use 'subregion' instead.")
103        if subregion is not None:
104            raise ValueError("Cannot use both 'subregions' and 'subregion' parameters.")
105        subregion = subregions
106
107    return _get_regions(
108        name=name,
109        region=region,
110        subregion=subregion,
111        type=type,
112        merge_regions=merge_regions,
113        regions_geojson_url="https://storage.googleapis.com/opr_stac/reference_geometry/measures_boundaries_4326.geojson",
114        merge_in_projection=merge_in_projection,
115        simplify_tolerance=simplify_tolerance
116    )

Load and filter Antarctic regional boundaries from the MEaSUREs dataset.

The data product is derived from:

Maps of Antarctic ice shelves, the Antarctic coastline and Antarctic basins. The maps are assembled from 2008-2009 ice-front data from ALOS PALSAR and ENVISAT ASAR data acquired during International Polar Year, 2007-2009 (IPY), the InSAR-based grounding line data (MEaSUREs Antarctic Grounding Line from Differential Satellite Radar Interferometry), augmented with other grounding line sources, the Antarctic ice velocity map (MEaSUREs InSAR-Based Antarctica Ice Velocity Map), and the Bedmap-2 DEM.

This data set is part of the NASA Making Earth System Data Records for Use in Research Environments (MEaSUREs) program.

Mouginot, J., B. Scheuchl, and E. Rignot. 2017. MEaSUREs Antarctic Boundaries for IPY 2007-2009 from Satellite Radar, Version 2. [Indicate subset used]. Boulder, Colorado USA. NASA National Snow and Ice Data Center Distributed Active Archive Center. doi: http://dx.doi.org/10.5067/AXE4121732AD. [Date Accessed].

https://nsidc.org/data/nsidc-0709/versions/2

See these two notebooks for examples of how to use this function:

Parameters
  • name (str or list, optional): NAME field value(s) to filter by
  • region (str or list, optional): REGION field value(s) to filter by
  • subregion (str or list, optional): SUBREGION field value(s) to filter by
  • type (str or list, optional): TYPE field value(s) to filter by
  • merge_regions (bool, default True): If True, return a single merged geometry; if False, return list of geometries
  • measures_boundaries_url : str, default "https (//storage.googleapis.com/opr_stac/reference_geometry/measures_boundaries_4326.geojson"): URL to the GeoJSON file containing Antarctic region boundaries
Returns
  • list or dict: If merge_regions=False: List of GeoJSON geometry dicts If merge_regions=True: Single GeoJSON geometry dict of merged regions
Examples

Get George VI ice shelf

>>> george_vi = get_antarctic_regions(name="George_VI", type="FL")

Get all ice shelves, merged into one geometry

>>> all_shelves = get_antarctic_regions(type="FL", merge_regions=True)

Get multiple regions by name

>>> regions = get_antarctic_regions(name=["George_VI", "LarsenC"])
def get_greenland_regions( name=None, region=None, subregion=None, type=None, merge_regions=True, merge_in_projection='EPSG:3413', simplify_tolerance=None):
118def get_greenland_regions(
119    name=None,
120    region=None,
121    subregion=None,
122    type=None,
123    merge_regions=True,
124    merge_in_projection="EPSG:3413",
125    simplify_tolerance=None,
126):
127    """
128    Load and filter Greenland regional boundaries as defined by the GrIMP project
129
130    The data product is derived from:
131
132    > We divide Greenland, including its peripheral glaciers and ice caps, into 260 basins grouped in seven regions:  southwest (SW), central west (CW), (iii) northwest (NW), north (NO), northeast (NE), central east (CE), and southeast (SE). These regions are selected based on ice flow regimes, climate, and the need to partition the ice sheet into zones comparable in size (200,000 km2 to 400,000 km2) and ice production (50 Gt/y to 100 Gt/y, or billion tons per year). Out of the 260 surveyed glaciers, 217 are marine-terminating, i.e., calving into icebergs and melting in contact with ocean waters, and 43 are land-terminating.The actual number of land-terminating glaciers is far larger than 43, but we lump them into larger units for simplification.
133    >
134    > Each glacier catchment is defined using a combination of ice flow direction and surface slope. In areas of fast flow (> 100 m), we use a composite velocity mosaic (Mouginot et al. 2017). In slowmoving areas, we use surface slope using the GIMP DEM (https://nsidc.org/data/nsidc- 0715/versions/1) (Howat et al. 2014) smoothed over 10 ice thicknesses to remove shortwavelength undulations.
135    >
136    > References:
137    >
138    > Mouginot J, Rignot E, Scheuchl B, Millan R (2017) Comprehensive annual ice sheet velocity mapping using landsat-8, sentinel-1, and radarsat-2 data. Remote Sensing 9(4).
139    >
140    > Howat IM, Negrete A, Smith BE (2014) The greenland ice mapping project (GIMP) land classification and surface elevation data sets. The Cryosphere 8(4):1509–1518.
141    >
142    > https://datadryad.org/dataset/doi:10.7280/D1WT11
143
144    Parameters
145    ----------
146    name : str or list, optional
147        NAME field value(s) to filter by
148    region : str or list, optional
149        REGION field value(s) to filter by
150    subregion : str or list, optional
151        SUBREGION field value(s) to filter by
152    type : str or list, optional
153        TYPE field value(s) to filter by
154    merge_regions : bool, default True
155        If True, return a single merged geometry; if False, return list of geometries
156    measures_boundaries_url : str, default "https://storage.googleapis.com/opr_stac/reference_geometry/measures_boundaries_4326.geojson"
157        URL to the GeoJSON file containing Antarctic region boundaries
158
159    Returns
160    -------
161    list or dict
162        If merge_regions=False: List of GeoJSON geometry dicts
163        If merge_regions=True: Single GeoJSON geometry dict of merged regions
164    """
165
166    greenland_boundaries_url = "https://storage.googleapis.com/opr_stac/reference_geometry/greenland_boundaries_4326.geojson"
167
168    return _get_regions(
169        name=name,
170        region=region,
171        subregion=subregion,
172        type=type,
173        merge_regions=merge_regions,
174        regions_geojson_url=greenland_boundaries_url,
175        merge_in_projection=merge_in_projection,
176        simplify_tolerance=simplify_tolerance
177    )

Load and filter Greenland regional boundaries as defined by the GrIMP project

The data product is derived from:

We divide Greenland, including its peripheral glaciers and ice caps, into 260 basins grouped in seven regions: southwest (SW), central west (CW), (iii) northwest (NW), north (NO), northeast (NE), central east (CE), and southeast (SE). These regions are selected based on ice flow regimes, climate, and the need to partition the ice sheet into zones comparable in size (200,000 km2 to 400,000 km2) and ice production (50 Gt/y to 100 Gt/y, or billion tons per year). Out of the 260 surveyed glaciers, 217 are marine-terminating, i.e., calving into icebergs and melting in contact with ocean waters, and 43 are land-terminating.The actual number of land-terminating glaciers is far larger than 43, but we lump them into larger units for simplification.

Each glacier catchment is defined using a combination of ice flow direction and surface slope. In areas of fast flow (> 100 m), we use a composite velocity mosaic (Mouginot et al. 2017). In slowmoving areas, we use surface slope using the GIMP DEM (https://nsidc.org/data/nsidc- 0715/versions/1) (Howat et al. 2014) smoothed over 10 ice thicknesses to remove shortwavelength undulations.

References:

Mouginot J, Rignot E, Scheuchl B, Millan R (2017) Comprehensive annual ice sheet velocity mapping using landsat-8, sentinel-1, and radarsat-2 data. Remote Sensing 9(4).

Howat IM, Negrete A, Smith BE (2014) The greenland ice mapping project (GIMP) land classification and surface elevation data sets. The Cryosphere 8(4):1509–1518.

https://datadryad.org/dataset/doi:10.7280/D1WT11

Parameters
  • name (str or list, optional): NAME field value(s) to filter by
  • region (str or list, optional): REGION field value(s) to filter by
  • subregion (str or list, optional): SUBREGION field value(s) to filter by
  • type (str or list, optional): TYPE field value(s) to filter by
  • merge_regions (bool, default True): If True, return a single merged geometry; if False, return list of geometries
  • measures_boundaries_url : str, default "https (//storage.googleapis.com/opr_stac/reference_geometry/measures_boundaries_4326.geojson"): URL to the GeoJSON file containing Antarctic region boundaries
Returns
  • list or dict: If merge_regions=False: List of GeoJSON geometry dicts If merge_regions=True: Single GeoJSON geometry dict of merged regions
def project_dataset(ds, target_crs):
276def project_dataset(ds, target_crs):
277    """
278    Project dataset coordinates from WGS84 to a target coordinate reference system.
279
280    Takes longitude and latitude coordinates from a dataset and projects them to
281    the specified target CRS, adding 'x' and 'y' coordinate arrays to the dataset.
282
283    Parameters
284    ----------
285    ds : xarray.Dataset
286        Input dataset containing 'Longitude' and 'Latitude' coordinates
287    target_crs : cartopy.crs.CRS or str
288        Target coordinate reference system. Can be a cartopy CRS object or
289        a string representation (e.g., "EPSG:3031")
290
291    Returns
292    -------
293    xarray.Dataset
294        Dataset with added 'x' and 'y' coordinate arrays in the target CRS
295
296    Examples
297    --------
298    >>> import cartopy.crs as ccrs
299    >>> projected_ds = project_dataset(ds, ccrs.SouthPolarStereo(true_scale_latitude=-71))
300    >>> projected_ds = project_dataset(ds, "EPSG:3031")
301    """
302    if hasattr(target_crs, 'to_epsg') and target_crs.to_epsg():
303        target_crs_str = f"EPSG:{target_crs.to_epsg()}"
304    elif isinstance(target_crs, str):
305        target_crs_str = target_crs
306    else:
307        target_crs_str = target_crs.to_proj4_string()
308
309    transformer = Transformer.from_crs("EPSG:4326", target_crs_str, always_xy=True)
310    projected_coords = transformer.transform(ds['Longitude'].values, ds['Latitude'].values)
311
312    ds = ds.assign_coords({
313        'x': (('slow_time'), projected_coords[0]),
314        'y': (('slow_time'), projected_coords[1])
315    })
316    return ds

Project dataset coordinates from WGS84 to a target coordinate reference system.

Takes longitude and latitude coordinates from a dataset and projects them to the specified target CRS, adding 'x' and 'y' coordinate arrays to the dataset.

Parameters
  • ds (xarray.Dataset): Input dataset containing 'Longitude' and 'Latitude' coordinates
  • target_crs (cartopy.crs.CRS or str): Target coordinate reference system. Can be a cartopy CRS object or a string representation (e.g., "EPSG:3031")
Returns
  • xarray.Dataset: Dataset with added 'x' and 'y' coordinate arrays in the target CRS
Examples
>>> import cartopy.crs as ccrs
>>> projected_ds = project_dataset(ds, ccrs.SouthPolarStereo(true_scale_latitude=-71))
>>> projected_ds = project_dataset(ds, "EPSG:3031")
def project_geojson(geometry, source_crs='EPSG:4326', target_crs=None):
318def project_geojson(geometry, source_crs="EPSG:4326", target_crs=None):
319    """
320    Project a geometry from one coordinate reference system to another.
321
322    Uses pyproj.Transformer to reproject geometries between different
323    coordinate reference systems. Commonly used for projecting geometries
324    from WGS84 (lat/lon) to polar stereographic projections.
325
326    Parameters
327    ----------
328    geometry : shapely.geometry.base.BaseGeometry
329        Input geometry to be projected
330    source_crs : str, default "EPSG:4326"
331        Source coordinate reference system (default is WGS84)
332    target_crs : str, default None
333        Target coordinate reference system. If None, automatically selects
334        Antarctic Polar Stereographic (EPSG:3031) for southern hemisphere
335        and Arctic Polar Stereographic (EPSG:3413) for northern hemisphere based on
336        the geometry's centroid latitude.
337
338    Returns
339    -------
340    shapely.geometry.base.BaseGeometry
341        Projected geometry in the target coordinate reference system
342
343    Examples
344    --------
345    >>> from shapely.geometry import Point
346    >>> point = Point(-70, -75)  # lon, lat in WGS84
347    >>> projected = project_geojson(point, "EPSG:4326", "EPSG:3031")
348    """
349
350    if target_crs is None:
351        if geometry.centroid.y < 0:
352            target_crs = "EPSG:3031"  # Antarctic Polar Stereographic
353        else:
354            target_crs = "EPSG:3413"  # Arctic Polar Stereographic
355
356    transformer = Transformer.from_crs(source_crs, target_crs, always_xy=True)
357    projected_geometry = shapely.ops.transform(transformer.transform, geometry)
358    return projected_geometry

Project a geometry from one coordinate reference system to another.

Uses pyproj.Transformer to reproject geometries between different coordinate reference systems. Commonly used for projecting geometries from WGS84 (lat/lon) to polar stereographic projections.

Parameters
  • geometry (shapely.geometry.base.BaseGeometry): Input geometry to be projected
  • source_crs : str, default "EPSG (4326"): Source coordinate reference system (default is WGS84)
  • target_crs (str, default None): Target coordinate reference system. If None, automatically selects Antarctic Polar Stereographic (EPSG:3031) for southern hemisphere and Arctic Polar Stereographic (EPSG:3413) for northern hemisphere based on the geometry's centroid latitude.
Returns
  • shapely.geometry.base.BaseGeometry: Projected geometry in the target coordinate reference system
Examples
>>> from shapely.geometry import Point
>>> point = Point(-70, -75)  # lon, lat in WGS84
>>> projected = project_geojson(point, "EPSG:4326", "EPSG:3031")