def test_clip_to_extent(self): proto = RegularGrid((500, 500, 30, 30, 0, 0), np.zeros((15, 15))) clipped = self.rast.clip(*proto.extent("edge")) self.assertEqual(clipped.size, (15, 15)) self.assertEqual(clipped.transform, (510, 510, 30, 30, 0, 0)) X, Y = clipped.center_coords() self.assertEqual(X[0, 0], 525) self.assertEqual(X[0, -1], 945) self.assertEqual(Y[0, 0], 525) self.assertEqual(Y[-1, 0], 945)
def test_extent_crs(self): pe = peaks(n=49) crs = karta.crs.ProjectedCRS( "+proj=utm +zone=12 +ellps=WGS84 +north=True", "UTM 12N (WGS 84)") rast_utm12N = RegularGrid((0.0, 0.0, 10000.0, 10000.0, 0.0, 0.0), values=pe, crs=crs) a, b, c, d = rast_utm12N.extent(reference='center', crs=karta.crs.LonLatWGS84) self.assertAlmostEqual(a, -115.45687156) self.assertAlmostEqual(b, -111.13480112) self.assertAlmostEqual(c, 0.0450996517) self.assertAlmostEqual(d, 4.3878488543)
class RegularGridTests(unittest.TestCase): def setUp(self): pe = peaks(n=49) self.rast = RegularGrid((0.0, 0.0, 30.0, 30.0, 0.0, 0.0), values=pe) # def test_newgrid(self): # g = newgrid([0, 0, 10, 5], resolution=(2, 2), skew=(0, 0)) # self.assertEqual(g.shape, (3, 5)) # g = newgrid([0, 0, 10, 10], resolution=(2, 2), skew=(1, -1)) # self.assertEqual(g.shape, (3, 5)) def test_resolution(self): grid = RegularGrid([0.0, 0.0, 25.0, 35.0, 10.0, 10.0]) self.assertEqual(grid.resolution, (25.0, 35.0)) def test_coordinates(self): cg = self.rast.coordinates() self.assertTrue( isinstance(cg, karta.raster.coordgen.CoordinateGenerator)) self.assertEqual(cg.transform, self.rast.transform) def test_bbox(self): pe = peaks(n=49) pe[40:, :] = np.nan pe[:, :5] = np.nan grid = RegularGrid((0.0, 0.0, 30.0, 30.0, 0.0, 0.0), values=pe) self.assertEqual(grid.bbox(), (0, 0, 30 * 49, 30 * 49)) def test_data_bbox(self): pe = peaks(n=49) pe[40:, :] = np.nan pe[:, :5] = np.nan grid = RegularGrid((0.0, 0.0, 30.0, 30.0, 0.0, 0.0), values=pe) self.assertEqual(grid.data_bbox(), (5 * 30, 0, 30 * 49, 30 * 40)) def test_add_rgrid(self): rast2 = RegularGrid(self.rast.transform, values=np.random.random(self.rast.size)) res = self.rast + rast2 self.assertTrue(np.all(res[:, :] == self.rast[:, :] + rast2[:, :])) def test_sub_rgrid(self): rast2 = RegularGrid(self.rast.transform, values=np.random.random(self.rast.size)) res = self.rast - rast2 self.assertTrue(np.all(res[:, :] == self.rast[:, :] - rast2[:, :])) def test_center_coords(self): grid = RegularGrid((0.0, 0.0, 30.0, 30.0, 0.0, 0.0), values=np.zeros([49, 49])) ans = np.meshgrid(np.arange(15.0, 1471.0, 30.0), np.arange(15.0, 1471.0, 30.0)) self.assertEqual(0.0, np.sum(grid.center_coords()[0] - ans[0])) self.assertEqual(0.0, np.sum(grid.center_coords()[1] - ans[1])) def test_center_coords_skewed(self): grid = RegularGrid((15.0, 15.0, 30.0, 30.0, 20.0, 10.0), values=np.zeros([5, 5])) X, Y = grid.center_coords() self.assertEqual(X[0, 0], 40.0) self.assertEqual(Y[0, 0], 35.0) self.assertEqual(X[-1, 0], 120.0) self.assertEqual(Y[-1, 0], 155.0) self.assertEqual(X[-1, -1], 240.0) self.assertEqual(Y[-1, -1], 195.0) def test_aschunks(self): grid = RegularGrid((0, 0, 1, 1, 0, 0), values=peaks(512)) for chunk in grid.aschunks(size=(64, 64)): self.assertEqual(chunk.size, (64, 64)) def test_aschunks_overlap(self): grid = RegularGrid((0, 0, 1, 1, 0, 0), values=peaks(512)) count = 0 for chunk in grid.aschunks(size=(64, 64), overlap=(32, 32)): count += 1 self.assertEqual(count, 256) def test_index_multiband(self): p = peaks(512) grid = RegularGrid((0, 0, 1, 1, 0, 0), values=np.dstack([p, np.where(p > 0, p, np.nan), p]), nodata_value=np.nan) grid[grid.data_mask_full] def test_apply(self): msk = np.zeros([8, 8], dtype=np.bool) msk[3, 2] = True msk[:2, 3:] = True val = np.arange(64, dtype=np.float64).reshape([8, 8]) val_ = val.copy() val[msk] = -1 grid = RegularGrid([0, 0, 1, 1, 0, 0], values=val, nodata_value=-1) newgrid = grid.apply(lambda x: x**2) npt.assert_equal(newgrid[msk], -1) npt.assert_equal(newgrid[:, :, 0][~msk], val_[~msk]**2) def test_apply_inplace(self): msk = np.zeros([8, 8], dtype=np.bool) msk[3, 2] = True msk[:2, 3:] = True val = np.arange(64, dtype=np.float64).reshape([8, 8]) val_ = val.copy() val[msk] = -1 grid = RegularGrid([0, 0, 1, 1, 0, 0], values=val, nodata_value=-1) grid.apply(lambda x: x**2, inplace=True) self.assertTrue(np.all(grid[:, :, 0][msk] == -1)) self.assertTrue(np.all(grid[:, :, 0][~msk] == val_[~msk]**2)) def test_merge(self): grid1 = RegularGrid([10, 20, 1, 1, 0, 0], values=np.ones([8, 8])) grid2 = RegularGrid([7, 22, 1, 1, 0, 0], values=2 * np.ones([4, 6])) grid3 = RegularGrid([12, 15, 1, 1, 0, 0], values=3 * np.ones([5, 5])) grid_combined = karta.raster.merge([grid1, grid2, grid3]) self.assertEqual(grid_combined.transform, (7.0, 15.0, 1.0, 1.0, 0.0, 0.0)) self.assertEqual(grid_combined.size, (13, 11)) self.assertEqual(np.sum(np.isnan(grid_combined[:, :])), 42) def test_merge_weighted(self): grid1 = RegularGrid([10, 20, 1, 1, 0, 0], values=np.ones([8, 8])) grid2 = RegularGrid([7, 22, 1, 1, 0, 0], values=2 * np.ones([4, 6])) grid3 = RegularGrid([12, 19, 1, 1, 0, 0], values=3 * np.ones([5, 5])) grid_combined = karta.raster.merge([grid1, grid2, grid3], weights=[1, 2, 3]) self.assertAlmostEqual(grid_combined[4, 4, 0], 1.66666666666) self.assertAlmostEqual(grid_combined[2, 8, 0], 2.5) self.assertAlmostEqual(grid_combined[4, 5, 0], 2.33333333333) def test_merge_multiband(self): grid3a = RegularGrid([0, 0, 1, 1, 0, 0], values=np.array([1, 2, 3]) * np.ones((16, 16, 3))) grid3b = RegularGrid([4, 4, 1, 1, 0, 0], values=np.array([2, 3, 4]) * np.ones((16, 16, 3))) grid3_mosaic = karta.raster.merge([grid3a, grid3b]) self.assertEqual(np.nansum(grid3_mosaic[:, :, 0]), 552) self.assertEqual(np.nansum(grid3_mosaic[:, :, 1]), 920) self.assertEqual(np.nansum(grid3_mosaic[:, :, 2]), 1288) def test_align_origin(self): xx, yy = np.meshgrid(np.linspace(0, 1, 50), np.linspace(0, 1, 30)) zz = 2.0 * xx**2 - 3.0 * yy**2 grid = RegularGrid((27, 53, 5, 5, 0, 0), values=zz) new_grid = grid._align_origin(5, 5, method='linear') self.assertEqual(new_grid.origin, (25, 55)) self.assertTrue(np.isnan(new_grid.values[0, 0])) def test_resample_nearest(self): # use linear function so that nearest neighbour and linear interp are # exact def makegrid(start, finish, n, res): xx, yy = np.meshgrid(np.linspace(start, finish, n), np.linspace(start, finish, n)) zz = 2.0 * xx - 3.0 * yy return RegularGrid((0.0, 0.0, res, res, 0.0, 0.0), values=zz) # node numbers from a line with extreme edges at [0, 1] g = makegrid(0.0, 1.0 - 2.0 / 300, 150, 2.0) sol = makegrid(0.0, 1.0 - 6.0 / 300, 50, 6.0) gnew = g.resample(6.0, 6.0, method='nearest') residue = gnew[:, :] - sol[:, :] self.assertTrue(np.max(np.abs(residue)) < 1e-12) def test_resample_linear(self): # use linear function so that nearest neighbour and linear interp are # exact def makegrid(start, finish, n, res): xx, yy = np.meshgrid(np.linspace(start, finish, n), np.linspace(start, finish, n)) zz = 2.0 * xx - 3.0 * yy return RegularGrid((0.0, 0.0, res, res, 0.0, 0.0), values=zz) # node numbers from a line with extreme edges at [0, 1] g = makegrid(0.0, 1.0 - 2.0 / 300, 150, 2.0) sol = makegrid(0.0, 1.0 - 6.0 / 300, 50, 6.0) gnew = g.resample(6.0, 6.0, method='linear') residue = gnew[:, :] - sol[:, :] self.assertTrue(np.max(np.abs(residue)) < 1e-12) def test_sample_nearest_out_of_bounds(self): g = RegularGrid([0, 0, 1, 1, 0, 0], values=np.ones((10, 10))) v = g.sample_nearest(np.array([7, 9, 12, 15]), np.array([3, 1, -1, 1])) self.assertEqual(v[0][0], 1.0) self.assertEqual(v[0][1], 1.0) self.assertTrue(np.isnan(v[0][2])) self.assertTrue(np.isnan(v[0][3])) def test_sample_linear_out_of_bounds(self): g = RegularGrid([0, 0, 1, 1, 0, 0], values=np.ones((10, 10))) v = g.sample_bilinear(np.array([7, 9, 12, 15]), np.array([3, 1, -1, 1])) self.assertEqual(v[0][0], 1.0) self.assertEqual(v[0][1], 1.0) self.assertTrue(np.isnan(v[0][2])) self.assertTrue(np.isnan(v[0][3])) def test_resample_multiband(self): grid = RegularGrid((0, 0, 1, 1, 0, 0), values=np.dstack([ np.ones((64, 64)), 2 * np.ones((64, 64)), 3 * np.ones((64, 64)) ])) grid2 = grid.resample(0.5, 0.5) self.assertEqual(grid2[0, 0, 0], 1.0) self.assertEqual(grid2[0, 0, 1], 2.0) self.assertEqual(grid2[0, 0, 2], 3.0) def test_sample_nearest(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.array([[0, 1], [1, 0.5]])) self.assertEqual(grid.sample_nearest(0.6, 0.7), 0.0) self.assertEqual(grid.sample_nearest(0.6, 1.3), 1.0) self.assertEqual(grid.sample_nearest(1.4, 0.3), 1.0) self.assertEqual(grid.sample_nearest(1.6, 1.3), 0.5) def test_sample_nearest_vector(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.arange(64).reshape([8, 8])) res = grid.sample_nearest(np.arange(1, 7, 0.5), np.arange(2, 5, 0.25)) self.assertEqual(res.shape, (1, 12)) def test_sample_nearest_array(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.arange(64).reshape([8, 8])) X, Y = np.meshgrid(np.arange(1, 7, 0.5), np.arange(2, 5, 0.25)) res = grid.sample_nearest(X, Y) self.assertEqual(res.shape, (1, 12, 12)) def test_sample_nearest_array_order(self): grid = RegularGrid((0, 0, 1, 1, 0, 0), values=np.dstack([ np.ones((64, 64)), 2 * np.ones((64, 64)), 3 * np.ones((64, 64)) ])) X, Y = np.meshgrid(np.arange(2, 10), np.arange(5, 13)) val = grid.sample_nearest(X, Y) self.assertEqual(val[0, 0, 0], 1.0) self.assertEqual(val[1, 0, 0], 2.0) self.assertEqual(val[2, 0, 0], 3.0) def test_sample_nearest_skewed(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.5, 0.2], values=np.array([[0, 1], [1, 0.5]])) self.assertEqual(grid.sample_nearest(1, 0.75), 0.0) self.assertEqual(grid.sample_nearest(1.5, 1.05), 1.0) self.assertEqual(grid.sample_nearest(1.2, 1.4), 1.0) self.assertEqual(grid.sample_nearest(2.0, 1.7), 0.5) def test_sample_bilinear(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.array([[0, 1], [1, 0.5]])) self.assertEqual(grid.sample_bilinear(1.0, 1.0), 0.625) def test_sample_bilinear_vector(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.arange(64, dtype=np.float64).reshape([8, 8])) res = grid.sample_bilinear(np.arange(1, 7, 0.5), np.arange(2, 5, 0.25)) self.assertEqual(res.shape, (1, 12)) def test_sample_bilinear_array(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.arange(64, dtype=np.float64).reshape([8, 8])) X, Y = np.meshgrid(np.arange(1, 7, 0.5), np.arange(2, 5, 0.25)) res = grid.sample_bilinear(X, Y) self.assertEqual(res.shape, (1, 12, 12)) def test_sample_bilinear_int(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.array([[0, 2], [2, 1]], dtype=np.int32)) self.assertEqual(grid.sample_bilinear(1.0, 1.0), 1) def test_sample_bilinear_uint(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.array([[0, 2], [2, 1]], dtype=np.uint16)) self.assertEqual(grid.sample_bilinear(1.0, 1.0), 1) def test_sample_bilinear_uint8(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.array([[0, 2], [2, 1]], dtype=np.uint8)) self.assertEqual(grid.sample_bilinear(1.0, 1.0), 1) def test_sample_bilinear_multiband(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.dstack([[[0, 1], [1, 0.5]], [[1, 2], [2, 1.5]]])) res = grid.sample_bilinear(1.0, 1.0) self.assertTrue(np.all(res == np.array([0.625, 1.625]))) def test_sample_bilinear_skewed(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.5, 0.2], values=np.array([[0, 1], [1, 0.5]])) self.assertEqual(grid.sample_bilinear(1.5, 1.2), 0.625) def test_sample_bilinear2(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.array([[0, 1], [1, 0.5]])) xi, yi = np.meshgrid(np.linspace(0.5, 1.5), np.linspace(0.5, 1.5)) z = grid.sample_bilinear(xi, yi).ravel() self.assertEqual([z[400], z[1200], z[1550], z[2120]], [ 0.16326530612244894, 0.48979591836734693, 0.63265306122448983, 0.74052478134110788 ]) def test_sample_multipoint(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.array([[0, 1], [1, 0.5]])) mp = karta.Multipoint([(0.6, 0.7), (0.6, 1.3), (1.4, 0.3), (1.6, 1.3)], crs=grid.crs) self.assertTrue( np.all( np.allclose(grid.sample(mp, method="nearest"), np.array([0.0, 1.0, 1.0, 0.5])))) def test_sample_2d_array(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.array([[0, 1], [1, 0.5]])) xi = np.array([[0.7, 1.3], [0.7, 1.3]]) yi = np.array([[0.7, 0.7], [1.3, 1.3]]) z = grid.sample(xi, yi, method="nearest") self.assertTrue(np.all(z == np.array([[0, 1], [1, 0.5]]))) def test_vertex_coords(self): grid = RegularGrid((0.0, 0.0, 30.0, 30.0, 0.0, 0.0), values=np.zeros([49, 49])) ans = np.meshgrid(np.arange(15.0, 1486.0, 30.0), np.arange(15.0, 1486.0, 30.0)) self.assertTrue(np.sum(grid.vertex_coords()[0] - ans[0]) < 1e-10) self.assertTrue(np.sum(grid.vertex_coords()[1] - ans[1]) < 1e-10) def test_vertex_coords_skewed(self): grid = RegularGrid((0.0, 0.0, 30.0, 30.0, 20.0, 10.0), values=np.zeros([5, 5])) ans = np.meshgrid(np.arange(15.0, 1486.0, 30.0), np.arange(15.0, 1486.0, 30.0)) self.assertTrue(np.sum(self.rast.vertex_coords()[0] - ans[0]) < 1e-10) self.assertTrue(np.sum(self.rast.vertex_coords()[1] - ans[1]) < 1e-10) def test_extent(self): ereg = (0.0, 1470.0, 0.0, 1470.0) creg = (15.0, 1455.0, 15.0, 1455.0) self.assertEqual(self.rast.extent(reference='center'), creg) self.assertEqual(self.rast.extent(reference='edge'), ereg) def test_extent_crs(self): pe = peaks(n=49) crs = karta.crs.ProjectedCRS( "+proj=utm +zone=12 +ellps=WGS84 +north=True", "UTM 12N (WGS 84)") rast_utm12N = RegularGrid((0.0, 0.0, 10000.0, 10000.0, 0.0, 0.0), values=pe, crs=crs) a, b, c, d = rast_utm12N.extent(reference='center', crs=karta.crs.LonLatWGS84) self.assertAlmostEqual(a, -115.45687156) self.assertAlmostEqual(b, -111.13480112) self.assertAlmostEqual(c, 0.0450996517) self.assertAlmostEqual(d, 4.3878488543) def test_data_extent(self): grid = RegularGrid((0, 0, 1, 1, 0, 0), values=np.zeros((128, 128), dtype=np.float64)) grid[:, :4] = grid.nodata grid[:, -7:] = grid.nodata grid[:21, :] = grid.nodata grid[-17:, :] = grid.nodata self.assertEqual(grid.data_extent("edge"), (4, 121, 21, 111)) self.assertEqual(grid.data_extent("center"), (4.5, 120.5, 21.5, 110.5)) def test_minmax_nodata(self): values = np.array([[4, 5, 3], [4, 2, -9], [3, 6, 1]]) self.rast = RegularGrid((0.0, 0.0, 30.0, 30.0, 0.0, 0.0), values=values, nodata_value=-9) minmax = self.rast.minmax() self.assertEqual(minmax, (1, 6)) def test_minmax_nodata2(self): values = -9 * np.ones([3, 3]) self.rast = RegularGrid((0.0, 0.0, 30.0, 30.0, 0.0, 0.0), values=values, nodata_value=-9) minmax = self.rast.minmax() self.assertTrue(np.isnan(minmax[0])) self.assertTrue(np.isnan(minmax[1])) def test_minmax(self): mx = self.rast.max() self.assertEqual(mx, 8.075173545159231) mn = self.rast.min() self.assertEqual(mn, -6.5466445243204294) minmax = self.rast.minmax() self.assertEqual(minmax, (-6.5466445243204294, 8.075173545159231)) def test_clip(self): clipped = self.rast.clip(500, 950, 500, 950) self.assertEqual(clipped.size, (15, 15)) self.assertEqual(clipped.transform, (510, 510, 30, 30, 0, 0)) X, Y = clipped.center_coords() self.assertEqual(X[0, 0], 525) self.assertEqual(X[0, -1], 945) self.assertEqual(Y[0, 0], 525) self.assertEqual(Y[-1, 0], 945) def test_clip_to_extent(self): proto = RegularGrid((500, 500, 30, 30, 0, 0), np.zeros((15, 15))) clipped = self.rast.clip(*proto.extent("edge")) self.assertEqual(clipped.size, (15, 15)) self.assertEqual(clipped.transform, (510, 510, 30, 30, 0, 0)) X, Y = clipped.center_coords() self.assertEqual(X[0, 0], 525) self.assertEqual(X[0, -1], 945) self.assertEqual(Y[0, 0], 525) self.assertEqual(Y[-1, 0], 945) def test_resize_smaller(self): proto = RegularGrid((500, 500, 30, 30, 0, 0), values=peaks(50)) newgrid = proto.resize([620, 650, 1370, 1310]) self.assertEqual(newgrid.transform, (620.0, 650.0, 30.0, 30.0, 0.0, 0.0)) self.assertTrue(np.all(newgrid[:, :] == proto[5:27, 4:29])) def test_resize_larger(self): proto = RegularGrid((500, 500, 30, 30, 0, 0), values=peaks(50)) newgrid = proto.resize([380, 320, 380 + 30 * 60, 320 + 30 * 62]) self.assertEqual(newgrid.transform, (380.0, 320.0, 30.0, 30.0, 0.0, 0.0)) self.assertTrue(np.all(newgrid[6:56, 4:54] == proto[:, :])) self.assertTrue(np.isnan(newgrid[0, 0])) def test_resize_lower_left(self): proto = RegularGrid((500, 500, 30, 30, 0, 0), values=peaks(50)) newgrid = proto.resize([380, 320, 380 + 30 * 30, 320 + 30 * 32]) self.assertEqual(newgrid.transform, (380.0, 320.0, 30.0, 30.0, 0.0, 0.0)) self.assertTrue(np.all(newgrid[6:, 4:] == proto[:26, :26])) def test_resize_upper_right(self): proto = RegularGrid((500, 500, 30, 30, 0, 0), values=peaks(50)) newgrid = proto.resize([1940, 1910, 1940 + 30 * 10, 1910 + 30 * 7]) self.assertEqual(newgrid.transform, (1940.0, 1910.0, 30.0, 30.0, 0.0, 0.0)) self.assertTrue(np.all(newgrid[:3, :2] == proto[-3:, -2:])) def test_data_mask_nan(self): T = [0.0, 0.0, 1.0, 1.0, 0.0, 0.0] v = np.arange(64, dtype=np.float64).reshape([8, 8]) v[0, 2:7] = np.nan g = RegularGrid(T, values=v, nodata_value=np.nan) self.assertEqual(np.sum(g.data_mask), 59) def test_data_mask_nonnan(self): T = [0.0, 0.0, 1.0, 1.0, 0.0, 0.0] v = np.arange(64, dtype=np.int8).reshape([8, 8]) v[0, 2:7] = -1 g = RegularGrid(T, values=v, nodata_value=-1) self.assertEqual(np.sum(g.data_mask), 59) def test_mask_poly(self): t = -np.linspace(0, 2 * np.pi, 200) xp = ((2 + np.cos(7 * t)) * np.cos(t + 0.3) + 4) * 12 yp = ((2 + np.cos(7 * t)) * np.sin(t + 0.2) + 4) * 12 poly = karta.Polygon(zip(xp, yp), crs=karta.crs.Cartesian) grid = RegularGrid([0.0, 0.0, 0.1, 0.1, 0.0, 0.0], values=np.arange(1e6).reshape(1000, 1000), crs=karta.crs.Cartesian) masked_grid = grid.mask_by_poly(poly) self.assertEqual(int(np.nansum(masked_grid[:, :])), 97048730546) def test_mask_poly_inplace(self): t = -np.linspace(0, 2 * np.pi, 200) xp = ((2 + np.cos(7 * t)) * np.cos(t + 0.3) + 4) * 12 yp = ((2 + np.cos(7 * t)) * np.sin(t + 0.2) + 4) * 12 poly = karta.Polygon(zip(xp, yp), crs=karta.crs.Cartesian) grid = RegularGrid([0.0, 0.0, 0.1, 0.1, 0.0, 0.0], values=np.arange(1e6).reshape(1000, 1000), crs=karta.crs.Cartesian) grid.mask_by_poly(poly, inplace=True) self.assertEqual(int(np.nansum(grid[:, :])), 97048730546) def test_mask_poly_partial(self): t = -np.linspace(0, 2 * np.pi, 200) xp = ((2 + np.cos(7 * t)) * np.cos(t + 0.3) + 2) * 12 yp = ((2 + np.cos(7 * t)) * np.sin(t + 0.2) + 2) * 12 poly = karta.Polygon(zip(xp, yp), crs=karta.crs.Cartesian) grid = RegularGrid([0.0, 0.0, 0.1, 0.1, 0.0, 0.0], values=np.arange(1e6).reshape(1000, 1000), crs=karta.crs.Cartesian) masked_grid = grid.mask_by_poly(poly) self.assertEqual(masked_grid.data_mask.sum(), 181424) def test_mask_poly_partial2(self): # this case has the first transect begin off-grid, which has caused # problems in the past g = RegularGrid([0, 0, 1, 1, 0, 0], values=np.ones((7, 7))) p = karta.Polygon([(-2, 3), (8, -5), (8, -1), (-2, 7)]) gc = g.mask_by_poly(p) self.assertEqual(gc.data_mask.sum(), 20) def test_mask_poly_multiple(self): # mask by multiple polygons t = -np.linspace(0, 2 * np.pi, 200) xp = ((2 + np.cos(7 * t)) * np.cos(t + 0.3) + 4) * 4 + 15 yp = ((2 + np.cos(7 * t)) * np.sin(t + 0.2) + 4) * 4 + 72 poly = karta.Polygon(zip(xp, yp), crs=karta.crs.Cartesian) xp2 = ((2 + np.cos(7 * t)) * np.cos(t + 0.3) + 4) * 6 + 40 yp2 = ((2 + np.cos(7 * t)) * np.sin(t + 0.2) + 4) * 6 + 30 poly2 = karta.Polygon(zip(xp2, yp2), crs=karta.crs.Cartesian) grid = RegularGrid([0.0, 0.0, 0.1, 0.1, 0.0, 0.0], values=np.arange(1e6).reshape(1000, 1000), crs=karta.crs.Cartesian) masked_grid = grid.mask_by_poly([poly, poly2]) self.assertEqual(int(np.nansum(masked_grid[:, :])), 47081206720) def test_mask_poly_multiband(self): t = -np.linspace(0, 2 * np.pi, 200) xp = ((2 + np.cos(7 * t)) * np.cos(t + 0.3) + 4) * 12 yp = ((2 + np.cos(7 * t)) * np.sin(t + 0.2) + 4) * 12 poly = karta.Polygon(zip(xp, yp), crs=karta.crs.Cartesian) grid = RegularGrid([0.0, 0.0, 0.1, 0.1, 0.0, 0.0], values=np.broadcast_to( np.atleast_3d( np.arange(1e6).reshape(1000, 1000)), (1000, 1000, 3)), crs=karta.crs.Cartesian) masked_grid = grid.mask_by_poly(poly) self.assertEqual(int(np.nansum(masked_grid[:, :])), 97048730546 * 3) def test_mask_poly_inverted(self): # grids where transform dy is negative (common for geotiffs) t = -np.linspace(0, 2 * np.pi, 200) xp = ((2 + np.cos(7 * t)) * np.cos(t + 0.3) + 4) * 12 yp = ((2 + np.cos(7 * t)) * np.sin(t + 0.2) + 4) * 12 poly = karta.Polygon(zip(xp, yp), crs=karta.crs.Cartesian) grid = RegularGrid([0.0, 100, 0.1, -0.1, 0.0, 0.0], values=np.arange(1e6).reshape(1000, 1000), crs=karta.crs.Cartesian) masked_grid = grid.mask_by_poly(poly) self.assertEqual(int(np.nansum(masked_grid[:, :])), 97048730546) def test_mask_multipoly(self): t = -np.linspace(0, 2 * np.pi, 200) coords = [] for dx, dy in [(60, 30), (45, 80), (25, 35)]: xp = (2 + np.cos(7 * t)) * np.cos(t + 0.3) * 6 + dx yp = (2 + np.cos(7 * t)) * np.sin(t + 0.2) * 6 + dy coords.append([list(zip(xp, yp))]) poly = karta.Multipolygon(coords, crs=karta.crs.Cartesian) grid = RegularGrid([0.0, 0, 0.1, 0.1, 0.0, 0.0], values=np.arange(1e6).reshape(1000, 1000), crs=karta.crs.Cartesian) masked_grid = grid.mask_by_poly(poly) self.assertEqual(int(np.nansum(masked_grid[:, :])), 73399874364) def test_positions(self): grid = RegularGrid([0.0, 0.0, 1.0, 1.0, 0.0, 0.0], values=np.zeros((3, 3))) (i, j) = grid.positions(1.5, 1.5) self.assertEqual((i, j), (1.0, 1.0)) (i, j) = grid.positions(2.0, 1.5) self.assertEqual((i, j), (1.0, 1.5)) def test_indices(self): ind = self.rast.indices(15.0, 15.0) self.assertEqual(tuple(ind), (0, 0)) ind = self.rast.indices(1455.0, 1455.0) self.assertEqual(tuple(ind), (48, 48)) def test_indices_onevec(self): ind = self.rast.indices([15.0], [15.0]) self.assertEqual(tuple(ind), (0, 0)) ind = self.rast.indices(1455.0, 1455.0) self.assertEqual(tuple(ind), (48, 48)) def test_indices_vec(self): ind = self.rast.indices(np.arange(15.0, 1470, 5), np.arange(15.0, 1470, 5)) xi = np.array([ 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48 ]) yi = np.array([ 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48 ]) self.assertTrue(np.all(ind[0] == xi)) self.assertTrue(np.all(ind[1] == yi)) def test_profile(self): path = karta.Line([(15.0, 15.0), (1484.0, 1484.0)], crs=karta.crs.Cartesian) pts, z = self.rast.profile(path, resolution=42.426406871192853, method="nearest") expected = self.rast[:, :].diagonal() self.assertEqual(len(pts), 49) self.assertTrue(np.allclose(z, expected)) def test_gridpoints_float64(self): # should use fast C version np.random.seed(49) x = np.random.rand(20000) * 10.0 - 5.0 y = np.random.rand(20000) * 10.0 - 5.0 z = x**2 + y**3 T = [-5.0, -5.0, 0.25, 0.25, 0.0, 0.0] grid = karta.raster.gridpoints(x, y, z, T, karta.crs.Cartesian) Xg, Yg = grid.center_coords() self.assertTrue( np.sum(np.abs(Xg**2 + Yg**3 - grid[:, :, 0])) / Xg.size < 0.45) def test_gridpoints_float32(self): # should use Python fallback np.random.seed(49) x = np.random.rand(20000).astype(np.float32) * 10.0 - 5.0 y = np.random.rand(20000).astype(np.float32) * 10.0 - 5.0 z = x**2 + y**3 T = [-5.0, -5.0, 0.25, 0.25, 0.0, 0.0] grid = karta.raster.gridpoints(x, y, z, T, karta.crs.Cartesian) Xg, Yg = grid.center_coords() self.assertTrue( np.sum(np.abs(Xg**2 + Yg**3 - grid[:, :, 0])) / Xg.size < 0.45) def test_set_nodata(self): v = np.arange(64, dtype=np.float64).reshape([8, 8]) v[2:4, 5:7] = -1 grid = RegularGrid([0, 0, 1, 1, 0, 0], values=v, nodata_value=-1) self.assertEqual(grid.nodata, -1.0) ret = grid.set_nodata_value(np.nan) self.assertEqual(ret, grid) self.assertTrue(np.isnan(grid.nodata)) self.assertEqual(np.sum(np.isnan(grid[:, :])), 4) self.assertEqual(np.sum(grid[:, :] == -1.0), 0)