def test_optional_arguments(numbers, names, abbrevs, name): if name is None: result = Regions(outlines, numbers, names, abbrevs) else: result = Regions(outlines, numbers, names, abbrevs, name) if numbers is None: numbers = [0, 1] if names is None: names = _create_expected_str_list(numbers, "Region") elif isinstance(names, six.string_types): names = _create_expected_str_list(numbers, names) if abbrevs is None: abbrevs = _create_expected_str_list(numbers, "r") elif isinstance(abbrevs, six.string_types): abbrevs = _create_expected_str_list(numbers, abbrevs) expected_centroids = [[0.5, 0.5], [0.5, 1.5]] if name is None: name = "unnamed" assert result.numbers == numbers assert result.names == names assert result.abbrevs == abbrevs assert np.allclose(result.centroids, expected_centroids) assert result.name == name
def test_centroid_multipolygon(): multipoly_equal = [MultiPolygon([poly1, poly2])] test_regions_multipoly_equal = Regions(multipoly_equal) # two equally sized polygons: uses the centroid of the first one assert np.allclose(test_regions_multipoly_equal.centroids, [[0.5, 0.5]]) # two un-equally sized polygons: uses the centroid of the larger one outl2_unequal = ((0, 1), (0, 2), (2, 2.0), (2, 1)) poly2_unequal = Polygon(outl2_unequal) multipoly_unequal = [MultiPolygon([poly1, poly2_unequal])] test_regions_multipoly_unequal = Regions(multipoly_unequal) assert np.allclose(test_regions_multipoly_unequal.centroids, [[1.0, 1.5]])
def test_mask_poly_z_value(method): outl1 = Polygon(((0, 0, 1), (0, 1, 1), (1, 1.0, 1), (1, 0, 1))) outl2 = Polygon(((0, 1, 1), (0, 2, 1), (1, 2.0, 1), (1, 1, 1))) outlines = [outl1, outl2] r_z = Regions(outlines) expected = expected_mask_2D() result = r_z.mask(dummy_lon, dummy_lat, method=method) assert isinstance(result, xr.DataArray) assert np.allclose(result, expected, equal_nan=True) assert np.all(np.equal(result.lat.values, dummy_lat)) assert np.all(np.equal(result.lon.values, dummy_lon))
def test_mask_poly_z_value(method): if method == "legacy": pytest.xfail("legacy does not support z-coordinates") outl1 = Polygon(((0, 0, 1), (0, 1, 1), (1, 1.0, 1), (1, 0, 1))) outl2 = Polygon(((0, 1, 1), (0, 2, 1), (1, 2.0, 1), (1, 1, 1))) outlines = [outl1, outl2] r_z = Regions(outlines) expected = expected_mask() result = r_z.mask(lon, lat, method=method, xarray=True) assert isinstance(result, xr.DataArray) assert np.allclose(result, expected, equal_nan=True) assert np.all(np.equal(result.lat.values, lat)) assert np.all(np.equal(result.lon.values, lon))
def test_lon_extent(): assert test_regions1.lon_180 assert not test_regions1.lon_360 outl_ = ((0, 0), (0, 1), (360, 1.0), (360, 0)) test_regions_ = Regions([outl_]) assert not test_regions_.lon_180 assert test_regions_.lon_360 outl_ = ((-1, 0), (-1, 1), (360, 1.0), (360, 0)) test_regions_ = Regions([outl_]) with pytest.raises(ValueError, match="lon has both data that is larger than 180 "): test_regions_.lon_180 with pytest.raises(ValueError, match="lon has both data that is larger than 180 "): test_regions_.lon_360
def test_getitem_sorted(numbers): r = Regions([outl1] * 20)[numbers] numbers_expected = sorted(numbers) abbrevs_expected = ["r{}".format(n) for n in numbers_expected] names_expected = ["Region{}".format(n) for n in numbers_expected] assert r.numbers == numbers_expected assert r.abbrevs == abbrevs_expected assert r.names == names_expected
def test_mask_wrap(method): # create a test case where the outlines and the lon coordinates # are different # outline 0..359.9 outl1 = ((359, 0), (359, 1), (0, 1.0), (0, 0)) outl2 = ((359, 1), (359, 2), (0, 2.0), (0, 1)) outlines = [outl1, outl2] r = Regions(outlines) # lon -180..179.9 lon = [-1.5, -0.5] lat = [0.5, 1.5] result = r.mask(lon, lat, method=method, wrap_lon=False).values assert np.all(np.isnan(result)) # this is the wrong wrapping result = r.mask(lon, lat, method=method, wrap_lon=180).values assert np.all(np.isnan(result)) expected = expected_mask_2D() # determine the wrap automatically result = r.mask(lon, lat, method=method, wrap_lon=True).values assert np.allclose(result, expected, equal_nan=True) # determine the wrap by hand result = r.mask(lon, lat, method=method, wrap_lon=360).values assert np.allclose(result, expected, equal_nan=True)
def test_mask_autowrap(method): expected = expected_mask_2D() # create a test case where the outlines and the lon coordinates # are different - or the same - should work either way # 1. -180..180 regions and -180..180 lon lon = [0.5, 1.5] lat = [0.5, 1.5] result = dummy_region.mask(lon, lat, method=method).values assert np.allclose(result, expected, equal_nan=True) # 2. -180..180 regions and 0..360 lon # outline -180..180 outl1 = ((-180, 0), (-180, 1), (-1, 1.0), (-1, 0)) outl2 = ((-180, 1), (-180, 2), (-1, 2.0), (-1, 1)) outlines = [outl1, outl2] r = Regions(outlines) # lon -180..179.9 lon = [358.5, 359.5] lat = [0.5, 1.5] result = r.mask(lon, lat, method=method).values assert np.allclose(result, expected, equal_nan=True) # 3. 0..360 regions and -180..180 lon # outline 0..359.9 outl1 = ((359, 0), (359, 1), (0, 1.0), (0, 0)) outl2 = ((359, 1), (359, 2), (0, 2.0), (0, 1)) outlines = [outl1, outl2] r = Regions(outlines) # lon -180..179.9 lon = [-1.5, -0.5] lat = [0.5, 1.5] result = r.mask(lon, lat, method=method).values assert np.allclose(result, expected, equal_nan=True) # 3. 0..360 regions and 0..360 lon # lon 0..359.9 lon = [0.5, 359.5] lat = [0.5, 1.5] result = r.mask(lon, lat, method=method).values assert np.allclose(result, expected, equal_nan=True)
def test_plot_lines_maybe_subsample(plotfunc, n, expected): """only subset non-polygons if they have less than 10 elements GH153 should eventually be superseeded by GH109""" # create closed coordinates with n points coords = np.linspace(interior1_closed[0], interior1_closed[1], num=n - 4) coords = np.vstack((coords, interior1_closed[1:])) r = Regions([coords]) func = getattr(r, plotfunc) with figure_context(): ax = func(subsample=True) lines = ax.collections[0].get_paths() assert len(lines) == 1 assert np.allclose(lines[0].vertices.shape, (expected, 2))
def test_regions_sorted(): numbers = [3, 1, 2] outl = [poly1, poly1, poly2] names = ["R3", "R1", "R2"] abbrevs = ["r3", "r1", "r2"] r = Regions(outl, numbers, names, abbrevs) assert r.numbers == [1, 2, 3] assert r.names == sorted(names) assert r.abbrevs == sorted(abbrevs) assert r.polygons[0].equals(poly1) assert r.polygons[1].equals(poly2) assert r.polygons[2].equals(poly1)
# TODO: use func(*(-161, -29, 2), *(75, 13, -2)) after dropping py27 ds_US_180 = create_lon_lat_dataarray_from_bounds(*(-161, -29, 2) + (75, 13, -2)) ds_US_360 = create_lon_lat_dataarray_from_bounds(*(360 + -161, 360 + -29, 2) + (75, 13, -2)) outline_180 = np.array([[-100.0, 50.0], [-100.0, 28.0], [-80.0, 28.0], [-80.0, 50.0]]) outline_360 = outline_180 + [360, 0] outline_hole_180 = np.array([[-86.0, 44.0], [-86.0, 34.0], [-94.0, 34.0], [-94.0, 44.0]]) outline_hole_360 = outline_hole_180 + [360, 0] r_US_180_ccw = Regions([outline_180]) # counter clockwise r_US_180_cw = Regions([outline_180[::-1]]) # clockwise r_US_360_ccw = Regions([outline_360]) # counter clockwise r_US_360_cw = Regions([outline_360[::-1]]) # clockwise # define poylgon with hole poly = Polygon(outline_180, [outline_hole_180]) r_US_hole_180_cw = Regions([poly]) # clockwise poly = Polygon(outline_180, [outline_hole_180[::-1]]) r_US_hole_180_ccw = Regions([poly]) # counter clockwise poly = Polygon(outline_360, [outline_hole_360]) r_US_hole_360_cw = Regions([poly]) # clockwise poly = Polygon(outline_360, [outline_hole_360[::-1]]) r_US_hole_360_ccw = Regions([poly]) # counter clockwise
# ============================================================================= # set up the testing regions name = "Example" numbers1 = [0, 1] names = ["Unit Square1", "Unit Square2"] abbrevs = ["uSq1", "uSq2"] outl1 = ((0, 0), (0, 1), (1, 1.0), (1, 0)) outl2 = ((0, 1), (0, 2), (1, 2.0), (1, 1)) outlines = [outl1, outl2] test_regions1 = Regions(outlines, numbers1, names, abbrevs, name=name) numbers2 = [1, 2] names_dict = {1: "Unit Square1", 2: "Unit Square2"} abbrevs_dict = {1: "uSq1", 2: "uSq2"} poly1 = Polygon(outl1) poly2 = Polygon(outl2) poly = {1: poly1, 2: poly2} test_regions2 = Regions(poly, numbers2, names_dict, abbrevs_dict, name=name) # numbers as array numbers3 = [2, 3] test_regions3 = Regions(outlines, np.array(numbers3), names, abbrevs, name=name)
name = "Example" numbers = [0, 1] names = ["Unit Square1", "Unit Square2"] abbrevs = ["uSq1", "uSq2"] outl1 = ((0, 0), (0, 1), (1, 1.0), (1, 0)) outl2 = ((0, 1), (0, 2), (1, 2.0), (1, 1)) outlines = [outl1, outl2] # polygons are automatically closed outl1_closed = outl1 + outl1[:1] outl2_closed = outl2 + outl2[:1] r1 = Regions(name=name, numbers=numbers, names=names, abbrevs=abbrevs, outlines=outlines) numbers = [1, 2] names = {1: "Unit Square1", 2: "Unit Square2"} abbrevs = {1: "uSq1", 2: "uSq2"} poly1 = Polygon(outl1) poly2 = Polygon(outl2) poly = {1: poly1, 2: poly2} r2 = Regions(name=name, numbers=numbers, names=names, abbrevs=abbrevs, outlines=poly)
import numpy as np from regionmask import Regions outl1 = ((0, 0), (0, 1), (1, 1.0), (1, 0)) outl2 = ((0, 1), (0, 2), (1, 2.0), (1, 1)) # no gridpoint in outl3 outl3 = ((0, 2), (0, 3), (1, 3.0), (1, 2)) dummy_outlines = [outl1, outl2, outl3] dummy_region = Regions(dummy_outlines) dummy_outlines_poly = dummy_region.polygons dummy_lon = [0.5, 1.5] dummy_lat = [0.5, 1.5] dummy_ll_dict = dict(lon=dummy_lon, lat=dummy_lat) # in this example the result looks: # | a fill | # | b fill | def expected_mask_2D(a=0, b=1, fill=np.NaN): return np.array([[a, fill], [b, fill]]) def expected_mask_3D(drop): a = [[True, False], [False, False]] b = [[False, False], [True, False]] c = [[False, False], [False, False]]
def test_error_on_non_numeric(numbers): with pytest.raises(ValueError, match="'numbers' must be numeric"): Regions(poly, numbers)