def test_compute_consistency(use_testdb, testdb, raster_file_xyz): import terracotta from terracotta.xyz import get_tile_data from terracotta.handlers import compute from terracotta.image import to_uint8 settings = terracotta.get_settings() raw_img = compute.compute( 'v1 + v2', ['val21', 'x'], {'v1': 'val22', 'v2': 'val23'}, stretch_range=(0, 10000), tile_xyz=raster_file_xyz ) img_data = np.asarray(Image.open(raw_img)) assert img_data.shape == settings.DEFAULT_TILE_SIZE driver = terracotta.get_driver(testdb) with driver.connect(): v1 = get_tile_data(driver, ['val21', 'x', 'val22'], raster_file_xyz) v2 = get_tile_data(driver, ['val21', 'x', 'val23'], raster_file_xyz) np.testing.assert_array_equal( img_data, to_uint8(v1 + v2, 0, 10000) )
def test_singleband_explicit_colormap(use_testdb, testdb, raster_file_xyz): import terracotta from terracotta.xyz import get_tile_data from terracotta.handlers import singleband ds_keys = ['val21', 'x', 'val22'] nodata = 10000 settings = terracotta.get_settings() driver = terracotta.get_driver(testdb) with driver.connect(): tile_data = get_tile_data(driver, ds_keys, tile_xyz=raster_file_xyz, preserve_values=True, tile_size=settings.DEFAULT_TILE_SIZE) # Get some values from the raster to use for colormap classes = np.unique(tile_data) classes = classes[:254] colormap = {} for i in range(classes.shape[0]): val = classes[i] color = val % 256 colormap[val] = (color, color, color, color) colormap[nodata] = (100, 100, 100, 100) raw_img = singleband.singleband(ds_keys, raster_file_xyz, colormap=colormap) img_data = np.asarray(Image.open(raw_img).convert('RGBA')) # get unstretched data to compare to with driver.connect(): tile_data = get_tile_data(driver, ds_keys, tile_xyz=raster_file_xyz, preserve_values=True, tile_size=img_data.shape[:2]) # check that labels are mapped to colors correctly for cmap_label, cmap_color in colormap.items(): if cmap_label == nodata: # make sure nodata is still transparent assert np.all(img_data[tile_data == cmap_label, -1] == 0) else: assert np.all( img_data[tile_data == cmap_label] == np.asarray(cmap_color)) # check that all data outside of labels is transparent keys_arr = np.array(list(colormap.keys()), dtype=np.int16) assert np.all(img_data[~np.isin(tile_data, keys_arr), -1] == 0)
def test_rgb_stretch(stretch_range, use_testdb, testdb, raster_file_xyz): import terracotta from terracotta.xyz import get_tile_data from terracotta.handlers import rgb ds_keys = ['val21', 'x', 'val22'] raw_img = rgb.rgb(ds_keys[:2], ['val22', 'val23', 'val24'], raster_file_xyz, stretch_ranges=[stretch_range] * 3) img_data = np.asarray(Image.open(raw_img))[..., 0] # get unstretched data to compare to driver = terracotta.get_driver(testdb) with driver.connect(): tile_data = get_tile_data(driver, ds_keys, tile_xyz=raster_file_xyz, tile_size=img_data.shape) # filter transparent values valid_mask = ~tile_data.mask assert np.all(img_data[~valid_mask] == 0) valid_img = img_data[valid_mask] valid_data = tile_data.compressed() assert np.all(valid_img[valid_data < stretch_range[0]] == 1) stretch_range_mask = (valid_data > stretch_range[0]) & (valid_data < stretch_range[1]) assert np.all(valid_img[stretch_range_mask] >= 1) assert np.all(valid_img[stretch_range_mask] <= 255) assert np.all(valid_img[valid_data > stretch_range[1]] == 255)
def get_band_future(band_key: str) -> Future: band_keys = (*some_keys, band_key) return xyz.get_tile_data(driver, band_keys, tile_xyz=tile_xyz, tile_size=tile_size_, asynchronous=True)
def test_colormap_consistency(use_testdb, testdb, raster_file_xyz, stretch_range, cmap_name): """Test consistency between /colormap and images returned by /singleband""" import terracotta from terracotta.xyz import get_tile_data from terracotta.handlers import singleband, colormap ds_keys = ['val21', 'x', 'val22'] # get image with applied stretch and colormap raw_img = singleband.singleband(ds_keys, raster_file_xyz, stretch_range=stretch_range, colormap=cmap_name) img_data = np.asarray(Image.open(raw_img).convert('RGBA')) # get raw data to compare to driver = terracotta.get_driver(testdb) with driver.connect(): tile_data = get_tile_data(driver, ds_keys, tile_xyz=raster_file_xyz, tile_size=img_data.shape[:2]) # make sure all pixel values are included in colormap num_values = stretch_range[1] - stretch_range[0] + 1 # get colormap for given stretch cmap = colormap.colormap(colormap=cmap_name, stretch_range=stretch_range, num_values=num_values) cmap = dict(row.values() for row in cmap) # test nodata nodata_mask = tile_data.mask assert np.all(img_data[nodata_mask, -1] == 0) # test clipping below_mask = tile_data < stretch_range[0] assert np.all(img_data[below_mask & ~nodata_mask, :-1] == cmap[stretch_range[0]][:-1]) above_mask = tile_data > stretch_range[1] assert np.all(img_data[above_mask & ~nodata_mask, :-1] == cmap[stretch_range[1]][:-1]) # test values inside stretch_range values_to_test = np.unique(tile_data.compressed()) values_to_test = values_to_test[(values_to_test >= stretch_range[0]) & (values_to_test <= stretch_range[1])] for val in values_to_test: rgba = cmap[val] assert np.all(img_data[tile_data == val] == rgba)
def singleband(keys: Union[Sequence[str], Mapping[str, str]], tile_xyz: Tuple[int, int, int] = None, *, colormap: Union[str, Mapping[Number, RGB], None] = None, stretch_range: Tuple[Number, Number] = None, tile_size: Tuple[int, int] = None) -> BinaryIO: """Return singleband image as PNG""" cmap_or_palette: Union[str, Sequence[RGB], None] if stretch_range is None: stretch_min, stretch_max = None, None else: stretch_min, stretch_max = stretch_range preserve_values = isinstance(colormap, collections.Mapping) settings = get_settings() if tile_size is None: tile_size = settings.DEFAULT_TILE_SIZE driver = get_driver(settings.DRIVER_PATH, provider=settings.DRIVER_PROVIDER) with driver.connect(): metadata = driver.get_metadata(keys) tile_data = xyz.get_tile_data(driver, keys, tile_xyz, tile_size=tile_size, preserve_values=preserve_values) if preserve_values: # bin output image into supplied labels, starting at 1 colormap = cast(Mapping, colormap) labels, label_colors = list(colormap.keys()), list(colormap.values()) cmap_or_palette = label_colors out = image.label(tile_data, labels) else: # determine stretch range from metadata and arguments stretch_range_ = list(metadata['range']) if stretch_min is not None: stretch_range_[0] = stretch_min if stretch_max is not None: stretch_range_[1] = stretch_max cmap_or_palette = cast(Optional[str], colormap) out = image.to_uint8(tile_data, *stretch_range_) return image.array_to_png(out, colormap=cmap_or_palette)
def test_singleband_explicit_colormap(use_testdb, testdb, raster_file_xyz): import terracotta from terracotta.xyz import get_tile_data from terracotta.handlers import singleband ds_keys = ['val21', 'x', 'val22'] nodata = 10000 colormap = {i: (i, i, i, i) for i in range(1, 150)} colormap[nodata] = (100, 100, 100, 100) raw_img = singleband.singleband(ds_keys, raster_file_xyz, colormap=colormap) img_data = np.asarray(Image.open(raw_img).convert('RGBA')) # get unstretched data to compare to driver = terracotta.get_driver(testdb) with driver.connect(): tile_data = get_tile_data(driver, ds_keys, tile_xyz=raster_file_xyz, tile_size=img_data.shape[:2]) # check that labels are mapped to colors correctly for cmap_label, cmap_color in colormap.items(): if cmap_label == nodata: # make sure nodata is still transparent assert np.all(img_data[tile_data == cmap_label, -1] == 0) else: assert np.all( img_data[tile_data == cmap_label] == np.asarray(cmap_color)) # check that all data outside of labels is transparent assert np.all(img_data[~np.isin(tile_data, colormap.keys()), -1] == 0)
def test_compute_transparency_mask(use_testdb, testdb, raster_file_xyz): import terracotta from terracotta.xyz import get_tile_data from terracotta.handlers import compute raw_img = compute.compute( 'masked_where(v1 > 0, v1 + v2)', ['val21', 'x'], {'v1': 'val22', 'v2': 'val23'}, stretch_range=(0, 10000), tile_xyz=raster_file_xyz ) img_data = np.asarray(Image.open(raw_img).convert('RGBA')) driver = terracotta.get_driver(testdb) with driver.connect(): v1 = get_tile_data(driver, ['val21', 'x', 'val22'], raster_file_xyz) alpha = img_data[..., 3] np.testing.assert_array_equal( alpha, np.where(v1.mask | (v1 > 0), 0, 255), )