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)
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
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), )
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), )
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)
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()
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)
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)
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)
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)
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)
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)
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), )