Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_array_to_png_singleband_invalid():
from terracotta import image, exceptions
with pytest.raises(exceptions.InvalidArgumentsError) as exc:
image.array_to_png(np.zeros((20, 20)), colormap='unknown')
assert 'invalid color map' in str(exc.value)
with pytest.raises(exceptions.InvalidArgumentsError) as exc:
image.array_to_png(np.zeros((20, 20)), colormap=[(0, 0, 0, 0)] * 1000)
assert 'must contain less' in str(exc.value)
with pytest.raises(ValueError) as exc:
image.array_to_png(np.zeros((20, 20)), colormap=[(0, 0, 0)] * 10)
assert 'must have shape' in str(exc.value)
def test_rgb_invalid_stretch(use_testdb, raster_file_xyz):
from terracotta import exceptions
from terracotta.handlers import rgb
stretch_range = [100, 0]
ds_keys = ['val21', 'x', 'val22']
with pytest.raises(exceptions.InvalidArgumentsError):
rgb.rgb(ds_keys[:2], ['val22', 'val23', 'val24'], raster_file_xyz,
stretch_ranges=[stretch_range] * 3)
def get_rgb(tile_z: int, tile_y: int, tile_x: int, path: str) -> Any:
"""Return PNG image of requested RGB tile"""
from terracotta.handlers.rgb import rgb
some_keys = path.split('/')
tile_xyz = (tile_x, tile_y, tile_z)
rgb_values = [request.args.get(k) for k in ('r', 'g', 'b')]
if not all(rgb_values):
raise exceptions.InvalidArgumentsError('r, g, and b arguments must be given')
stretch_method = request.args.get('stretch_method', 'stretch')
stretch_options = {
'data_range': [json.loads(request.args.get(k, 'null')) for k in
('r_range', 'g_range', 'b_range')],
'percentiles': json.loads(request.args.get('percentiles', 'null'))
}
image = rgb(
some_keys, tile_xyz, rgb_values,
stretch_method=stretch_method, stretch_options=stretch_options
)
return send_file(image, mimetype='image/png')
transparency = (0, 0, 0)
palette = None
elif img_data.ndim == 2: # encode paletted image
mode = 'L'
if colormap is None:
palette = None
transparency = 0
else:
if isinstance(colormap, str):
# get and apply colormap by name
try:
cmap_vals = get_cmap(colormap)
except ValueError as exc:
raise exceptions.InvalidArgumentsError(
f'Encountered invalid color map {colormap}') from exc
if cmap_vals.shape[1] == 4:
palette = np.concatenate((
np.zeros(3, dtype='uint8'),
cmap_vals[:, 0:3].flatten()
))
transparency = cmap_vals[:, 3].tobytes()
else:
palette = np.concatenate((
np.zeros(3, dtype='uint8'),
cmap_vals.flatten()
))
transparency = 0
else:
# explicit mapping
if len(colormap) > 255:
Red, green, and blue channels correspond to the given values `rgb_values` of the key
missing from `some_keys`.
"""
import numpy as np
# make sure all stretch ranges contain two values
if stretch_ranges is None:
stretch_ranges = [None, None, None]
if len(stretch_ranges) != 3:
raise exceptions.InvalidArgumentsError('stretch_ranges argument must contain 3 values')
stretch_ranges_ = [stretch_range or (None, None) for stretch_range in stretch_ranges]
if len(rgb_values) != 3:
raise exceptions.InvalidArgumentsError('rgb_values argument must contain 3 values')
settings = get_settings()
if tile_size is None:
tile_size_ = settings.DEFAULT_TILE_SIZE
else:
tile_size_ = tile_size
driver = get_driver(settings.DRIVER_PATH, provider=settings.DRIVER_PROVIDER)
with driver.connect():
key_names = driver.key_names
if len(some_keys) != len(key_names) - 1:
raise exceptions.InvalidArgumentsError('must specify all keys except last one')
if cmap_vals.shape[1] == 4:
palette = np.concatenate((
np.zeros(3, dtype='uint8'),
cmap_vals[:, 0:3].flatten()
))
transparency = cmap_vals[:, 3].tobytes()
else:
palette = np.concatenate((
np.zeros(3, dtype='uint8'),
cmap_vals.flatten()
))
transparency = 0
else:
# explicit mapping
if len(colormap) > 255:
raise exceptions.InvalidArgumentsError(
'Explicit color map must contain less than 256 values'
)
colormap_array = np.asarray(colormap, dtype='uint8')
if colormap_array.ndim != 2 or colormap_array.shape[1] != 4:
raise ValueError('Explicit color mapping must have shape (n, 4)')
rgb, alpha = colormap_array[:, :-1], colormap_array[:, -1]
palette = np.concatenate((
np.zeros(3, dtype='uint8'),
rgb.flatten(),
np.zeros(3 * (256 - len(colormap) - 1), dtype='uint8')
))
# PIL expects paletted transparency as raw bytes
transparency_arr = np.concatenate((
raise exceptions.InvalidArgumentsError('rgb_values argument must contain 3 values')
settings = get_settings()
if tile_size is None:
tile_size_ = settings.DEFAULT_TILE_SIZE
else:
tile_size_ = tile_size
driver = get_driver(settings.DRIVER_PATH, provider=settings.DRIVER_PROVIDER)
with driver.connect():
key_names = driver.key_names
if len(some_keys) != len(key_names) - 1:
raise exceptions.InvalidArgumentsError('must specify all keys except last one')
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)
futures = [get_band_future(key) for key in rgb_values]
band_items = zip(rgb_values, stretch_ranges_, futures)
out_arrays = []
for i, (band_key, band_stretch_override, band_data_future) in enumerate(band_items):
keys = (*some_keys, band_key)
metadata = driver.get_metadata(keys)
band_stretch_range = list(metadata['range'])
for i, (band_key, band_stretch_override, band_data_future) in enumerate(band_items):
keys = (*some_keys, band_key)
metadata = driver.get_metadata(keys)
band_stretch_range = list(metadata['range'])
scale_min, scale_max = band_stretch_override
if scale_min is not None:
band_stretch_range[0] = scale_min
if scale_max is not None:
band_stretch_range[1] = scale_max
if band_stretch_range[1] < band_stretch_range[0]:
raise exceptions.InvalidArgumentsError(
'Upper stretch bound must be higher than lower bound'
)
band_data = band_data_future.result()
out_arrays.append(image.to_uint8(band_data, *band_stretch_range))
out = np.ma.stack(out_arrays, axis=-1)
return image.array_to_png(out)