Example #1
0
def test_tile_invalid_bounds(landsat_get_mtl, monkeypatch):
    """
    Should raise an error with invalid tile
    """

    monkeypatch.setattr(landsat8, 'LANDSAT_BUCKET', LANDSAT_BUCKET)
    landsat_get_mtl.return_value = LANDSAT_METADATA

    tile_z = 8
    tile_x = 701
    tile_y = 102

    with pytest.raises(TileOutsideBounds):
        landsat8.tile(LANDSAT_SCENE_C1, tile_x, tile_y, tile_z)
Example #2
0
def expression(sceneid, tile_x, tile_y, tile_z, expr, **kwargs):
    """
    """
    bands_names = tuple(set(re.findall(r'b(?P<bands>[0-9A]{1,2})', expr)))
    rgb = expr.split(',')

    if sceneid.startswith('L'):
        from rio_tiler.landsat8 import tile
        arr, mask = tile(sceneid,
                         tile_x,
                         tile_y,
                         tile_z,
                         bands=bands_names,
                         **kwargs)
    elif sceneid.startswith('S2'):
        from rio_tiler.sentinel2 import tile
        arr, mask = tile(sceneid,
                         tile_x,
                         tile_y,
                         tile_z,
                         bands=bands_names,
                         **kwargs)
    elif sceneid.startswith('CBERS'):
        from rio_tiler.cbers import tile
        arr, mask = tile(sceneid,
                         tile_x,
                         tile_y,
                         tile_z,
                         bands=bands_names,
                         **kwargs)
    else:
        from rio_tiler.main import tile
        bands = tuple(map(int, bands_names))
        arr, mask = tile(sceneid,
                         tile_x,
                         tile_y,
                         tile_z,
                         indexes=bands,
                         **kwargs)

    ctx = {}
    for bdx, b in enumerate(bands_names):
        ctx['b{}'.format(b)] = arr[bdx]

    return np.array([
        np.nan_to_num(ne.evaluate(bloc.strip(), local_dict=ctx))
        for bloc in rgb
    ]), mask
Example #3
0
def tile(scene, tile_z, tile_x, tile_y, tileformat):
    """Handle tile requests
    """
    if tileformat == 'jpg':
        tileformat = 'jpeg'

    query_args = APP.current_request.query_params
    query_args = query_args if isinstance(query_args, dict) else {}

    bands = query_args.get('rgb', '4,3,2')
    bands = tuple(re.findall(r'\d+', bands))

    histoCut = query_args.get('histo', ';'.join(['0,16000'] * len(bands)))
    histoCut = re.findall(r'\d+,\d+', histoCut)
    histoCut = list(map(lambda x: list(map(int, x.split(','))), histoCut))

    if len(bands) != len(histoCut):
        raise LandsatTilerError('The number of bands doesn\'t match the number of histogramm values')

    tilesize = query_args.get('tile', 256)
    tilesize = int(tilesize) if isinstance(tilesize, str) else tilesize

    pan = True if query_args.get('pan') else False
    tile, mask = landsat8.tile(scene, tile_x, tile_y, tile_z, bands, pan=pan, tilesize=tilesize)

    rtile = np.zeros((len(bands), tilesize, tilesize), dtype=np.uint8)
    for bdx in range(len(bands)):
        rtile[bdx] = np.where(mask, linear_rescale(tile[bdx], in_range=histoCut[bdx], out_range=[0, 255]), 0)
    img = array_to_img(rtile, mask=mask)
    str_img = b64_encode_img(img, tileformat)
    return ('OK', f'image/{tileformat}', str_img)
def mvttiles(
    scene: str,
    z: int,
    x: int,
    y: int,
    bands: str = None,
    tile_size: Union[str, int] = 256,
    pixel_selection: str = "first",
    feature_type: str = "point",
    resampling_method: str = "nearest",
) -> Tuple[str, str, BinaryIO]:
    """Handle MVT tile requests."""
    if tile_size is not None and isinstance(tile_size, str):
        tile_size = int(tile_size)

    bands = tuple(bands.split(","))
    tile, mask = landsat8.tile(scene, x, y, z, bands=bands, tilesize=tile_size)

    band_descriptions = [f"Band_{b}" for b in bands]
    return (
        "OK",
        "application/x-protobuf",
        mvtEncoder(tile,
                   mask,
                   band_descriptions,
                   "landsat",
                   feature_type=feature_type),
    )
Example #5
0
def tiles(
    scene,
    z,
    x,
    y,
    scale=1,
    ext="png",
    bands=None,
    expr=None,
    rescale=None,
    color_formula=None,
    color_map=None,
    pan=False,
):
    """Handle tile requests."""
    if ext == "jpg":
        driver = "jpeg"
    elif ext == "jp2":
        driver = "JP2OpenJPEG"
    else:
        driver = ext

    if bands and expr:
        raise LandsatTilerError("Cannot pass bands and expression")
    if not bands and not expr:
        raise LandsatTilerError("Need bands or expression")

    if bands:
        bands = tuple(bands.split(","))

    tilesize = scale * 256

    pan = True if pan else False

    if expr is not None:
        tile, mask = expression(scene, x, y, z, expr, tilesize=tilesize)  # , pan=pan)

    elif bands is not None:
        tile, mask = landsat8.tile(
            scene, x, y, z, bands=bands, tilesize=tilesize  # , pan=pan
        )

    rtile, rmask = _postprocess(
        tile, mask, tilesize, rescale=rescale, color_formula=color_formula
    )

    if color_map:
        color_map = get_colormap(color_map, format="gdal")

    options = img_profiles.get(driver, {})
    return (
        "OK",
        f"image/{ext}",
        array_to_image(rtile, rmask, img_format=driver, color_map=color_map, **options),
    )
Example #6
0
def test_tile_valid_default(landsat_get_mtl, monkeypatch):
    """
    Should work as expected
    """

    monkeypatch.setattr(landsat8, 'LANDSAT_BUCKET', LANDSAT_BUCKET)
    landsat_get_mtl.return_value = LANDSAT_METADATA

    tile_z = 8
    tile_x = 71
    tile_y = 102

    assert landsat8.tile(LANDSAT_SCENE_C1, tile_x, tile_y,
                         tile_z).shape == (3, 256, 256)
Example #7
0
def test_tile_invalidband(landsat_get_mtl, monkeypatch):
    """Should raise an error on invalid band name."""
    monkeypatch.setattr(landsat8, "LANDSAT_BUCKET", LANDSAT_BUCKET)

    tile_z = 8
    tile_x = 71
    tile_y = 102
    bands = "25"

    with pytest.raises(InvalidBandName):
        data, mask = landsat8.tile(LANDSAT_SCENE_C1,
                                   tile_x,
                                   tile_y,
                                   tile_z,
                                   bands=bands)
    landsat_get_mtl.assert_not_called()
Example #8
0
def test_tile_valid_nrg(landsat_get_mtl, monkeypatch):
    """Should return a custom band combination tile."""
    monkeypatch.setattr(landsat8, "LANDSAT_BUCKET", LANDSAT_BUCKET)
    landsat_get_mtl.return_value = LANDSAT_METADATA

    tile_z = 8
    tile_x = 71
    tile_y = 102
    bands = ("5", "4", "3")
    data, mask = landsat8.tile(LANDSAT_SCENE_C1,
                               tile_x,
                               tile_y,
                               tile_z,
                               bands=bands)
    assert data.shape == (3, 256, 256)
    assert mask.shape == (256, 256)
Example #9
0
def test_tile_valid_tir(landsat_get_mtl, monkeypatch):
    """Should return a tile and mask from TIR band."""
    monkeypatch.setattr(landsat8, "LANDSAT_BUCKET", LANDSAT_BUCKET)
    landsat_get_mtl.return_value = LANDSAT_METADATA

    tile_z = 8
    tile_x = 71
    tile_y = 102
    bands = "10"

    data, mask = landsat8.tile(LANDSAT_SCENE_C1,
                               tile_x,
                               tile_y,
                               tile_z,
                               bands=bands)
    assert data.shape == (1, 256, 256)
    assert mask.shape == (256, 256)
Example #10
0
def landsat_ratio(scene, tile_z, tile_x, tile_y, tileformat):
    """
    Handle processing requests
    """
    query_args = LANDSAT_APP.current_request.query_params
    query_args = query_args if isinstance(query_args, dict) else {}

    ratio_value = query_args.get('ratio', 'ndvi')

    if ratio_value not in RATIOS.keys():
        raise LandsatTilerError('Invalid ratio: {}'.format(ratio_value))

    equation = RATIOS[ratio_value]['eq']
    band_names = list(set(re.findall('b[0-9]{1,2}', equation)))
    bands = tuple(map(lambda x: x.strip('b'), band_names))

    tilesize = query_args.get('tile', 256)
    tilesize = int(tilesize) if isinstance(tilesize, str) else tilesize

    tile = landsat8.tile(scene,
                         tile_x,
                         tile_y,
                         tile_z,
                         bands,
                         tilesize=tilesize)
    for bdx, b in enumerate(band_names):
        globals()[b] = tile[bdx]

    tile = np.where(
        reduce(lambda x, y: x * y, [globals()[i] for i in band_names]) > 0,
        np.nan_to_num(ne.evaluate(equation)), -9999)

    range_val = equation = RATIOS[ratio_value]['rg']
    rtile = np.where(
        tile != -9999,
        linear_rescale(tile, in_range=range_val, out_range=[1, 255]),
        0).astype(np.uint8)

    tile = array_to_img(rtile,
                        tileformat,
                        color_map=get_colormap(name='cfastie'))
    if tileformat == 'jpg':
        tileformat = 'jpeg'

    return ('OK', f'image/{tileformat}', tile)
Example #11
0
def landsat_tile(scene, tile_z, tile_x, tile_y, tileformat):
    """
    Handle tile requests
    """
    query_args = LANDSAT_APP.current_request.query_params
    query_args = query_args if isinstance(query_args, dict) else {}

    rgb = query_args.get('rgb', '4,3,2')
    rgb = map(int, rgb.split(',')) if isinstance(rgb, str) else rgb
    rgb = tuple(rgb)

    r_bds = query_args.get('r_bds', '0,16000')
    if isinstance(r_bds, str):
        r_bds = map(int, r_bds.split(','))
    r_bds = tuple(r_bds)

    g_bds = query_args.get('g_bds', '0,16000')
    if isinstance(g_bds, str):
        g_bds = map(int, g_bds.split(','))
    g_bds = tuple(g_bds)

    b_bds = query_args.get('b_bds', '0,16000')
    if isinstance(b_bds, str):
        b_bds = map(int, b_bds.split(','))
    b_bds = tuple(b_bds)

    tilesize = query_args.get('tile', 256)
    tilesize = int(tilesize) if isinstance(tilesize, str) else tilesize

    pan = True if query_args.get('pan') else False

    tile = landsat8.tile(scene,
                         tile_x,
                         tile_y,
                         tile_z,
                         rgb,
                         r_bds,
                         g_bds,
                         b_bds,
                         pan=pan,
                         tilesize=tilesize)

    tile = array_to_img(tile, tileformat)

    return ('OK', f'image/{tileformat}', tile)
Example #12
0
def test_tile_valid_pan(landsat_get_mtl, monkeypatch):
    """
    Should work as expected
    """

    monkeypatch.setattr(landsat8, 'LANDSAT_BUCKET', LANDSAT_BUCKET)
    landsat_get_mtl.return_value = LANDSAT_METADATA

    tile_z = 8
    tile_x = 71
    tile_y = 102

    data, mask = landsat8.tile(LANDSAT_SCENE_C1,
                               tile_x,
                               tile_y,
                               tile_z,
                               pan=True)
    assert data.shape == (3, 256, 256)
    assert mask.shape == (256, 256)
Example #13
0
def tile(scene, tile_z, tile_x, tile_y, tileformat):
    if tileformat == 'jpg':
        tileformat = 'jpeg'

    query_args = APP.current_request.query_params
    query_args = query_args if isinstance(query_args, dict) else {}

    bands = query_args.get('rgb', '4,3,2')

    label_id = -1
    if bands == '12,12,12':
        label_id = 0
        bands = '4,3,2'
    elif bands == '13,13,13':
        label_id = 1
        bands = '4,3,2'
    elif bands == '14,14,14':
        label_id = 2
        bands = '4,3,2'
    elif bands == '15,15,15':
        label_id = 3
        bands = '4,3,2'

    bands = tuple(re.findall(r'\d+', bands))

    histoCut = query_args.get('histo', ';'.join(['0,16000'] * len(bands)))
    histoCut = re.findall(r'\d+,\d+', histoCut)
    histoCut = list(map(lambda x: list(map(int, x.split(','))), histoCut))

    if len(bands) != len(histoCut):
        raise LandsatTilerError(
            'The number of bands doesn\'t match the number of histogramm values'
        )

    tilesize = query_args.get('tile', 256)
    tilesize = int(tilesize) if isinstance(tilesize, str) else tilesize

    pan = True if query_args.get('pan') else False
    tile, mask = landsat8.tile(scene,
                               tile_x,
                               tile_y,
                               tile_z,
                               bands,
                               pan=pan,
                               tilesize=tilesize)

    rtile = np.zeros((len(bands), tilesize, tilesize), dtype=np.uint8)
    for bdx in range(len(bands)):
        rtile[bdx] = np.where(
            mask,
            linear_rescale(tile[bdx],
                           in_range=histoCut[bdx],
                           out_range=[0, 255]), 0)
    img = array_to_img(rtile, mask=mask)
    str_img = b64_encode_img(img, tileformat)

    if label_id != -1:
        data = {
            'label_id': label_id,
            'img': str_img,
        }

        r = requests.post(f"http://kursach.ngrok.io/getmask/", json=data)

        str_img = r.json()['mask']

        img = Image.open(io.BytesIO(base64.decodebytes(eval(f"b'{str_img}'"))))
        img_np = np.asarray(img).T

        img = array_to_img(img_np, mask=mask)
        str_img = b64_encode_img(img, tileformat)

    return ('OK', f'image/{tileformat}', str_img)
Example #14
0
def tiles(
    scene: str,
    z: int,
    x: int,
    y: int,
    scale: int = 1,
    ext: str = "png",
    bands: str = None,
    expr: str = None,
    rescale: str = None,
    color_formula: str = None,
    color_map: str = None,
    pan: bool = False,
) -> Tuple[str, str, BinaryIO]:
    """Handle tile requests."""
    driver = "jpeg" if ext == "jpg" else ext

    if bands and expr:
        raise LandsatTilerError("Cannot pass bands and expression")

    tilesize = scale * 256

    pan = True if pan else False
    if expr is not None:
        tile, mask = expression(scene,
                                x,
                                y,
                                z,
                                expr=expr,
                                tilesize=tilesize,
                                pan=pan)

    elif bands is not None:
        tile, mask = landsat8.tile(scene,
                                   x,
                                   y,
                                   z,
                                   bands=tuple(bands.split(",")),
                                   tilesize=tilesize,
                                   pan=pan)
    else:
        raise LandsatTilerError("No bands nor expression given")

    rtile, rmask = _postprocess(tile,
                                mask,
                                rescale=rescale,
                                color_formula=color_formula)

    if color_map:
        color_map = get_colormap(color_map, format="gdal")

    options = img_profiles.get(driver, {})
    return (
        "OK",
        f"image/{ext}",
        array_to_image(rtile,
                       rmask,
                       img_format=driver,
                       color_map=color_map,
                       **options),
    )