Example #1
0
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)
    )
Example #2
0
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)
Example #3
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)
Example #4
0
 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)
Example #5
0
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)
Example #6
0
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)
Example #7
0
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)
Example #8
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),
    )