Source code for polartoolkit.regions

# Copyright (c) 2024 The Polartoolkit Developers.
# Distributed under the terms of the MIT License.
# SPDX-License-Identifier: MIT
#
# This code is part of the package:
# PolarToolkit (https://github.com/mdtanker/polartoolkit)
#
"""
Bounding regions for commonly plotted polar regions. In stereographic projections. The
format is (xmin, xmax, ymin, ymax), in meters.
"""

from __future__ import annotations

import typing

import pandas as pd
import verde as vd

from polartoolkit import (  # pylint: disable=import-self
    maps,
    regions,  # noqa: PLW0406
    utils,
)

try:
    import ipyleaflet
except ImportError:
[docs] ipyleaflet = None
try: from IPython.display import display except ImportError:
[docs] display = None
##### ##### # Antarctica ##### ##### # regions
[docs] antarctica = (-2800e3, 2800e3, -2800e3, 2800e3)
[docs] west_antarctica = (-2740e3, 570e3, -2150e3, 1670e3)
[docs] east_antarctica = (-840e3, 2880e3, -2400e3, 2600e3)
[docs] antarctic_peninsula = (-2600e3, -1200e3, 170e3, 1800e3)
[docs] marie_byrd_land = (-1500e3, -500e3, -1350e3, -800e3)
[docs] victoria_land = (100e3, 1000e3, -2200e3, -1000e3)
# wilkes_land # queen_maud_land
[docs] saunders_coast = (-980e3, -600e3, -1350e3, -1100e3)
# study_sites
[docs] roosevelt_island = (-480e3, -240e3, -1220e3, -980e3)
[docs] ross_island = (210e3, 360e3, -1400e3, -1250e3)
[docs] minna_bluff = (210e3, 390e3, -1310e3, -1120e3)
# discovery_deep
[docs] mcmurdo_dry_valleys = (320e3, 480e3, -1400e3, -1220e3)
[docs] siple_coast = (-700e3, 30e3, -1110e3, -450e3)
[docs] crary_ice_rise = (-330e3, -40e3, -830e3, -480e3)
[docs] siple_dome = (-630e3, -270e3, -970e3, -630e3)
# ice_shelves # WEST ANTARCTICA
[docs] ross_ice_shelf = (-680e3, 470e3, -1420e3, -310e3)
# withrow_ice_shelf = # swinburne_ice_shelf = # sulzberger_ice_shelf =
[docs] nickerson_ice_shelf = (-980e3, -787e3, -1327e3, -1210e3)
# land_ice_shelf =
[docs] getz_ice_shelf = (-1624e3, -1130e3, -1234e3, -664e3)
# dotson_ice_shelf = () # crosson_ice_shelf = () # thwaites_ice_shelf = () # pine_island_ice_shelf = () # cosgrove_ice_shelf = () # abbott_ice_shelf = () # venable_ice_shelf = () # ferrigno_ice_shelf = () # stange_ice_shelf = () # bach_ice_shelf = () # wilkins_ice_shelf = ()
[docs] george_vi_ice_shelf = (-2150e3, -1690e3, 540e3, 860e3)
# wordie_ice_shelf = ()
[docs] larsen_ice_shelf = (-2430e3, -1920e3, 900e3, 1400e3)
# larson_b_ice_shelf = () # larson_c_ice_shelf = () # larson_d_ice_shelf = () # larson_e_ice_shelf = () # larson_f_ice_shelf = () # larson_g_ice_shelf = ()
[docs] ronne_filchner_ice_shelf = (-1550e3, -500e3, 80e3, 1100e3)
[docs] ronne_ice_shelf = (-1550e3, -725e3, 45e3, 970e3)
# filchner_ice_shelf = # EAST ANTARCTICA # stancomb_brunt_ice_shelf = () # riiser_larsen_ice_shelf = () # quar_ice_shelf = () # ekstrom_ice_shelf = () # atka_ice_shelf = () # jelbart_ice_shelf = ()
[docs] fimbul_ice_shelf = (-260e3, 430e3, 1900e3, 2350e3)
# vigrid_ice_shelf = () # nivl_ice_shelf = () # lazarev_ice_shelf = () # borchgrevink_ice_shelf = ()
[docs] baudouin_ice_shelf = (855e3, 1250e3, 1790e3, 2080e3)
# prince_harald_ice_shelf = () # shirase_ice_shelf = () # rayner_ice_shelf = () # edward_vii_ice_shelf = () # wilma_ice_shelf = () # robert_ice_shelf = () # downer_ice_shelf = ()
[docs] amery_ice_shelf = (1530e3, 2460e3, 430e3, 1000e3)
# publications_ice_shelf = () # west_ice_shelf = () # shackleton_ice_shelf = () # tracy_tremenchus_ice_shelf = () # conger_ice_shelf = () # vicennes_ice_shelf = () # totten_ice_shelf = () # moscow_university_ice_shelf = () # holmes_ice_shelf = () # dibble_ice_shelf = () # mertz_ice_shelf = () # ninnis_ice_shelf = () # cook_east_ice_shelf = () # rennick_ice_shelf = () # lillie_ice_shelf = () # mariner_ice_shelf = () # aviator_ice_shelf = () # nansen_ice_shelf = () # drygalski_ice_shelf = () # glaciers # byrd_glacier # nimrod_glacier
[docs] pine_island_glacier = (-1720e3, -1480e3, -380e3, -70e3)
[docs] thwaites_glacier = (-1650e3, -1200e3, -600e3, -300e3)
[docs] kamb_ice_stream = (-620e3, -220e3, -800e3, -400e3)
# whillans_ice_stream = () # seas
[docs] ross_sea = (-500e3, 450e3, -2100e3, -1300e3)
# amundsen_sea # bellinghausen_sea # weddell_sea # subglacial lakes
[docs] lake_vostok = (1100e3, 1535e3, -470e3, -230e3)
# ice catchements ##### ##### # Greenland ##### ##### # regions
[docs] greenland = (-700e3, 900e3, -3400e3, -600e3)
[docs] north_greenland = (-500e3, 600e3, -1200e3, -650e3)
# northwest_greenland = () # northeast_greenland = () # west_greenland = () # east_greenland = () # southeast_greenland = () # southwest_greenland = () # glaciers
[docs] kangerlussuaq_glacier = (380e3, 550e3, -2340e3, -2140e3)
[docs] def get_regions() -> dict[str, tuple[float, float, float, float]]: """ get all the regions defined in this module. Returns ------- dict[str, tuple[float, float, float, float] ] dictionary of each defined region's name and values """ exclude_list = [ "__", "pd", "vd", "utils", "regions", "TYPE_CHECKING", "Union", "maps", "ipyleaflet", "ipywidgets", "combine_regions", "draw_region", "get_regions", "annotations", "typing", "display", "alter_region", ] return { k: v for k, v in vars(regions).items() if (k not in exclude_list) & (not k.startswith("_")) }
[docs] def alter_region( starting_region: tuple[float, float, float, float], zoom: float = 0, n_shift: float = 0, w_shift: float = 0, ) -> tuple[float, float, float, float]: """ Change a bounding region by shifting the box east/west or north/south, or zooming in or out. Parameters ---------- starting_region : tuple[float, float, float, float] Initial region in meters in format [xmin, xmax, ymin, ymax] zoom : float, optional zoom in or out, in meters, by default 0 n_shift : float, optional shift north, or south if negative, in meters, by default 0 w_shift : float, optional shift west, or east if negative, in meters, by default 0 Returns ------- tuple[float, float, float, float] Returns the altered region """ starting_e, starting_w = starting_region[0], starting_region[1] starting_n, starting_s = starting_region[2], starting_region[3] xmin = starting_e + zoom + w_shift xmax = starting_w - zoom + w_shift ymin = starting_n + zoom - n_shift ymax = starting_s - zoom - n_shift return (xmin, xmax, ymin, ymax)
[docs] def combine_regions( region1: tuple[float, float, float, float], region2: tuple[float, float, float, float], ) -> tuple[float, float, float, float]: """ Get the bounding region of 2 regions. Parameters ---------- region1 : tuple[float, float, float, float] first region, in the format (xmin, xmax, ymin, ymax) region2 : tuple[float, float, float, float] second region in the format (xmin, xmax, ymin, ymax) Returns ------- tuple[float, float, float, float] Bounding region of the 2 supplied regions. """ coords1 = utils.region_to_df(region1) coords2 = utils.region_to_df(region2) coords_combined = pd.concat((coords1, coords2)) reg: tuple[float, float, float, float] = vd.get_region( (coords_combined.easting, coords_combined.northing) ) return reg
[docs] def draw_region(**kwargs: typing.Any) -> list[typing.Any]: """ Plot an interactive map, and use the "Draw a Rectangle" button to draw a rectangle and get the bounding region. Vertices will be returned as the output of the function. Returns ------- list[typing.Any] Returns a list of list of vertices for each polyline. Example ------- >>> from polartoolkit import regions, utils ... >>> polygon = regions.draw_region() >>> region = utils.polygon_to_region(polygon, hemisphere="north") """ if ipyleaflet is None: msg = """ Missing optional dependency 'ipyleaflet' required for interactive plotting. """ raise ImportError(msg) if display is None: msg = "Missing optional dependency 'ipython' required for interactive plotting." raise ImportError(msg) m = maps.interactive_map(**kwargs, show=False) def clear_m() -> None: global poly # pylint: disable=global-variable-undefined # noqa: PLW0603 poly = [] # type: ignore[name-defined] clear_m() mydrawcontrol = ipyleaflet.DrawControl( polygon={ "shapeOptions": { "fillColor": "#fca45d", "color": "#fca45d", "fillOpacity": 0.5, } }, polyline={}, circlemarker={}, rectangle={}, ) def handle_rect_draw(self: typing.Any, action: str, geo_json: typing.Any) -> None: # noqa: ARG001 # pylint: disable=unused-argument global poly # noqa: PLW0602 # pylint: disable=global-variable-not-assigned shapes = [] for coords in geo_json["geometry"]["coordinates"][0][:-1][:]: shapes.append(list(coords)) shapes = list(shapes) if action == "created": poly.append(shapes) # type: ignore[name-defined] mydrawcontrol.on_draw(handle_rect_draw) m.add_control(mydrawcontrol) clear_m() display(m) return poly # type: ignore[no-any-return, name-defined]