def test_threads(): """Test mosaic tiler.""" assets = [asset1, asset2, asset1, asset2, asset1, asset2] tnothread, _ = mosaic.mosaic_tiler(assets, x, y, z, _read_tile, threads=0) tmulti_threads, _ = mosaic.mosaic_tiler(assets, x, y, z, _read_tile, threads=1) numpy.testing.assert_array_equal(tnothread, tmulti_threads) t, _ = mosaic.mosaic_tiler(assets, x, y, z, _read_tile, threads=0, chunk_size=2) assert t.shape == (3, 256, 256) t, _ = mosaic.mosaic_tiler(assets, x, y, z, _read_tile, threads=2, chunk_size=4) assert t.shape == (3, 256, 256)
def npy_tiles( url: str, z: int, x: int, y: int, scale: int = 1, bands: str = None, expr: str = None, pixel_selection: str = "first", ) -> Tuple[str, str, BinaryIO]: """Handle tile requests.""" if url is None: return ("NOK", "text/plain", "Missing 'URL' parameter") with MosaicBackend(url) as mosaic: assets = mosaic.tile(x, y, z) if not assets: return ("EMPTY", "text/plain", f"No assets found for tile {z}-{x}-{y}") tilesize = 256 * scale pixel_selection = pixSel[pixel_selection] if expr is not None: results = mosaic_tiler( assets, x, y, z, expressionTiler, pixel_selection=pixel_selection(), expr=expr, tilesize=tilesize, ) elif bands is not None: results = mosaic_tiler( assets, x, y, z, landsatTiler, pixel_selection=pixel_selection(), bands=tuple(bands.split(",")), tilesize=tilesize, ) else: return ("NOK", "text/plain", "No bands nor expression given") sio = io.BytesIO() numpy.save(sio, results) sio.seek(0) return ("OK", "application/x-binary", sio.getvalue())
def npy_tiles( mosaicid: str, z: int, x: int, y: int, scale: int = 1, bands: str = None, expr: str = None, pixel_selection: str = "first", ) -> Tuple[str, str, BinaryIO]: """Handle tile requests.""" bucket = os.environ["MOSAIC_DEF_BUCKET"] url = f"s3://{bucket}/mosaics/{mosaicid}.json.gz" assets = get_assets(url, x, y, z) if not assets: return ("EMPTY", "text/plain", f"No assets found for tile {z}-{x}-{y}") tilesize = 256 * scale pixel_selection = pixSel[pixel_selection] if expr is not None: results = mosaic_tiler( assets, x, y, z, expressionTiler, pixel_selection=pixel_selection(), expr=expr, tilesize=tilesize, ) elif bands is not None: results = mosaic_tiler( assets, x, y, z, landsatTiler, pixel_selection=pixel_selection(), bands=tuple(bands.split(",")), tilesize=tilesize, ) else: return ("NOK", "text/plain", "No bands nor expression given") sio = io.BytesIO() numpy.save(sio, results) sio.seek(0) return ("OK", "application/x-binary", sio.getvalue())
def _get_tile(wind): idx, window = wind x = extrema["x"]["min"] + idx[1] y = extrema["y"]["min"] + idx[0] t = mercantile.Tile(x, y, base_zoom) kds = set(find_quadkeys(t, mosaic_quadkey_zoom)) if not mosaic_quadkeys.intersection(kds): return window, None, None assets = mosaic.tile(*t) if not assets: raise Exception( f"No asset for tile {x}-{y}-{base_zoom}") if assets: tile, mask = mosaic_tiler( assets, x, y, base_zoom, cogeo.tile, indexes=info[6], tilesize=tilesize, pixel_selection=defaults.FirstMethod(), ) return window, tile, mask
def _mvt( mosaicid: str = None, z: int = None, x: int = None, y: int = None, url: str = None, tile_size: Union[str, int] = 256, pixel_selection: str = "first", feature_type: str = "point", resampling_method: str = "nearest", ) -> Tuple: """Handle MVT requests.""" from rio_tiler_mvt.mvt import encoder as mvtEncoder # noqa if not mosaicid and not url: return ("NOK", "text/plain", "Missing 'MosaicID or URL' parameter") mosaic_path = _create_mosaic_path(mosaicid) if mosaicid else url with MosaicBackend(mosaic_path) as mosaic: assets = mosaic.tile(x, y, z) if not assets: return ("EMPTY", "text/plain", f"No assets found for tile {z}-{x}-{y}") if tile_size is not None and isinstance(tile_size, str): tile_size = int(tile_size) if pixel_selection == "last": pixel_selection = "first" assets = list(reversed(assets)) with rasterio.Env(aws_session): pixsel_method = PIXSEL_METHODS[pixel_selection] tile, mask = mosaic_tiler( assets, x, y, z, cogeoTiler, tilesize=tile_size, pixel_selection=pixsel_method(), resampling_method=resampling_method, ) if tile is None: return ("EMPTY", "text/plain", "empty tiles") with rasterio.open(assets[0]) as src_dst: band_descriptions = _get_layer_names(src_dst) return ( "OK", "application/x-protobuf", mvtEncoder( tile, mask, band_descriptions, mosaicid or os.path.basename(url), feature_type=feature_type, ), )
def _img( mosaicid: str = None, z: int = None, x: int = None, y: int = None, scale: int = 1, ext: str = None, url: str = None, pixel_selection: str = "first", resampling_method: str = "nearest", ) -> Tuple: """Handle tile requests.""" if not mosaicid and not url: return ("NOK", "text/plain", "Missing 'MosaicID or URL' parameter") mosaic_path = _create_mosaic_path(mosaicid) if mosaicid else url with MosaicBackend(mosaic_path) as mosaic: assets = mosaic.tile(x, y, z) if not assets: return ("EMPTY", "text/plain", f"No assets found for tile {z}-{x}-{y}") tilesize = 256 * scale if pixel_selection == "last": pixel_selection = "first" assets = list(reversed(assets)) with rasterio.Env(aws_session): pixsel_method = PIXSEL_METHODS[pixel_selection] tile, mask = mosaic_tiler( assets, x, y, z, usgs_tiler, tilesize=tilesize, pixel_selection=pixsel_method(), resampling_method=resampling_method, ) if tile is None: return ("EMPTY", "text/plain", "empty tiles") if not ext: ext = "jpg" if mask.all() else "png" driver = "jpeg" if ext == "jpg" else ext options = img_profiles.get(driver, {}) if ext == "tif": ext = "tiff" driver = "GTiff" options = geotiff_options(x, y, z, tilesize) return ( "OK", f"image/{ext}", render(tile, mask, img_format=driver, **options), )
def _mvt( mosaicid: str = None, z: int = None, x: int = None, y: int = None, url: 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 requests.""" if mosaicid: url = _create_path(mosaicid) elif url is None: return ("NOK", "text/plain", "Missing 'URL' parameter") assets = fetch_and_find_assets(url, x, y, z) if not assets: return ("EMPTY", "text/plain", f"No assets found for tile {z}-{x}-{y}") if tile_size is not None and isinstance(tile_size, str): tile_size = int(tile_size) if pixel_selection == "last": pixel_selection = "first" assets = list(reversed(assets)) with rasterio.Env(aws_session): pixsel_method = PIXSEL_METHODS[pixel_selection] tile, mask = mosaic_tiler( assets, x, y, z, cogeoTiler, tilesize=tile_size, pixel_selection=pixsel_method(), resampling_method=resampling_method, ) if tile is None: return ("EMPTY", "text/plain", "empty tiles") with rasterio.open(assets[0]) as src_dst: band_descriptions = _get_layer_names(src_dst) return ( "OK", "application/x-protobuf", mvtEncoder( tile, mask, band_descriptions, os.path.basename(url), feature_type=feature_type, ), )
def test_mosaic_tiler_Stdev(): """Test Stdev mosaic methods.""" tile1, mask1 = cogTiler(assets[0], x, y, z) tile2, mask2 = cogTiler(assets[1], x, y, z) t, m = mosaic.mosaic_tiler( assets, x, y, z, cogTiler, pixel_selection=defaults.StdevMethod() ) assert t.shape == (3, 256, 256) assert m.shape == (256, 256) assert m.all() assert t[0][-1][-1] == numpy.std([tile1[0][-1][-1], tile2[0][-1][-1]]) assert t[1][-1][-1] == numpy.std([tile1[1][-1][-1], tile2[1][-1][-1]]) assert t[2][-1][-1] == numpy.std([tile1[2][-1][-1], tile2[2][-1][-1]])
def load_assets(x, y, z, assets, tile_size, input_format: str = None, output_format: str = None, backfill: bool = False, pixel_selection: str = 'first', resampling_method: str = "nearest"): if input_format == 'terrarium': arrays = [rasterio.open(asset).read() for asset in assets] backfilled = backfill_arrays(*arrays) if output_format == 'terrarium': return backfilled data = decode_ele(backfilled, 'terrarium', backfill=backfill) elif input_format == 'geotiff': arrays = [rasterio.open(asset).read() for asset in assets] data = backfill_arrays(*arrays) else: with rasterio.Env(aws_session): pixsel_method = PIXSEL_METHODS[pixel_selection] data, _ = mosaic_tiler( assets, x, y, z, cogeoTiler, tilesize=tile_size, pixel_selection=pixsel_method(), resampling_method=resampling_method, ) if output_format == 'terrarium': return mapzen_elevation_rgb(data) return data
def _get_tile(wind): idx, window = wind x = extrema["x"]["min"] + idx[1] y = extrema["y"]["min"] + idx[0] assets = list( set(get_assets(mosaic_definition, x, y, base_zoom))) if assets: tile, mask = mosaic_tiler( assets, x, y, base_zoom, cogeoTiler, tilesize=tilesize, pixel_selection=defaults.FirstMethod(), ) if tile is None: raise Exception("Empty") return window, tile, mask
def read_tile( self, z: int, x: int, y: int, tilesize: int = 256, indexes: Tuple[int] = None, resampling_method: str = "bilinear", ) -> [numpy.ndarray, numpy.ndarray]: """Read raster tile data and mask.""" assets = utils.get_assets(self.mosaic, x, y, z) return mosaic_tiler( assets, x, y, z, cogeoTiler, indexes=indexes, tilesize=tilesize, pixel_selection=defaults.FirstMethod(), resampling_method=resampling_method, )
def tiles( mosaicid: str, z: int, x: int, y: int, scale: int = 1, ext: str = "png", bands: str = None, expr: str = None, rescale: str = None, color_ops: str = None, color_map: str = None, pixel_selection: str = "first", ) -> Tuple[str, str, BinaryIO]: """Handle tile requests.""" bucket = os.environ["MOSAIC_DEF_BUCKET"] url = f"s3://{bucket}/mosaics/{mosaicid}.json.gz" assets = get_assets(url, x, y, z) if not assets: return ("EMPTY", "text/plain", f"No assets found for tile {z}-{x}-{y}") tilesize = 256 * scale pixel_selection = pixSel[pixel_selection] if expr is not None: tile, mask = mosaic_tiler( assets, x, y, z, expressionTiler, pixel_selection=pixel_selection(), expr=expr, tilesize=tilesize, ) elif bands is not None: tile, mask = mosaic_tiler( assets, x, y, z, landsatTiler, pixel_selection=pixel_selection(), bands=tuple(bands.split(",")), tilesize=tilesize, ) else: return ("NOK", "text/plain", "No bands nor expression given") if tile is None: return ("EMPTY", "text/plain", "empty tiles") if color_map: color_map = get_colormap(color_map, format="gdal") if ext == "gif": frames = [] options = img_profiles.get("png", {}) for i in range(len(tile)): img = post_process_tile(tile[i].copy(), mask[i].copy(), rescale=rescale, color_formula=color_ops) frames.append( Image.open( io.BytesIO( array_to_image( img, mask[i], img_format="png", color_map=color_map, **options, )))) sio = io.BytesIO() frames[0].save( sio, "gif", save_all=True, append_images=frames[1:], duration=300, loop=0, optimize=True, ) sio.seek(0) return ("OK", f"image/{ext}", sio.getvalue()) rtile = post_process_tile(tile, mask, rescale=rescale, color_formula=color_ops) driver = "jpeg" if ext == "jpg" else ext options = img_profiles.get(driver, {}) if ext == "tif": ext = "tiff" driver = "GTiff" tile_bounds = mercantile.xy_bounds(mercantile.Tile(x=x, y=y, z=z)) options = dict( crs={"init": "EPSG:3857"}, transform=from_bounds(*tile_bounds, tilesize, tilesize), ) return ( "OK", f"image/{ext}", array_to_image(rtile, mask, img_format=driver, color_map=color_map, **options), )
def mosaic_tiles( z, x, y, scale=1, ext="png", urls=None, nodata=None, indexes=None, rescale=None, color_ops=None, color_map=None, pixel_selection: str = "first", resampling_method: str = "bilinear", ): """ Handle Raster /mosaics requests. Note: All the querystring parameters are translated to function keywords and passed as string value by lambda_proxy Attributes ---------- z : int, required Mercator tile ZOOM level. x : int, required Mercator tile X index. y : int, required Mercator tile Y index. scale : int Output scale factor (default: 1). ext : str Image format to return (default: png). urls : str, required Dataset urls to read from. indexes : str, optional, (defaults: None) Comma separated band index number (e.g "1,2,3"). nodata, str, optional Custom nodata value if not preset in dataset. rescale : str, optional Min and Max data bounds to rescale data from. color_ops : str, optional rio-color compatible color formula color_map : str, optional Rio-tiler compatible colormap name ("cfastie" or "schwarzwald") pixel_selection : str, optional rio-tiler-mosaic pixel selection method (default: first) resampling_method : str, optional Resampling method to use (default: bilinear) Returns ------- status : str Status of the request (e.g. OK, NOK). MIME type : str response body MIME type (e.g. image/jpeg). body : bytes Image body. """ if not urls: raise TilerError("Missing 'urls' parameter") if indexes: indexes = tuple(int(s) for s in re.findall(r"\d+", indexes)) if nodata is not None and isinstance(nodata, str): nodata = numpy.nan if nodata == "nan" else float(nodata) tilesize = 256 * scale tile, mask = mosaic_tiler( urls.split(","), x, y, z, main.tile, indexes=indexes, tilesize=tilesize, nodata=nodata, pixel_selection=pixel_selection, resampling_method=resampling_method, ) if tile is None: return ("EMPTY", "text/plain", "empty tiles") rtile, rmask = _postprocess_tile(tile, mask, rescale=rescale, color_ops=color_ops) if color_map: color_map = get_colormap(color_map, format="gdal") driver = "jpeg" if ext == "jpg" else ext options = img_profiles.get(driver, {}) return ( "OK", f"image/{ext}", array_to_image(rtile, rmask, img_format=driver, color_map=color_map, **options), )
def mosaic_tiles_mvt( z, x, y, scale=1, urls=None, nodata=None, pixel_selection: str = "first", resampling_method: str = "bilinear", feature_type="point", ): """ Handle Raster /mosaics requests. Note: All the querystring parameters are translated to function keywords and passed as string value by lambda_proxy Attributes ---------- z : int, required Mercator tile ZOOM level. x : int, required Mercator tile X index. y : int, required Mercator tile Y index. scale : int Output scale factor (default: 1). urls : str, required Dataset urls to read from. nodata, str, optional Custom nodata value if not preset in dataset. pixel_selection : str, optional rio-tiler-mosaic pixel selection method (default: first) resampling_method : str, optional Resampling method to use (default: bilinear) feature_type : str, optional Output feature type (default: point) Returns ------- status : str Status of the request (e.g. OK, NOK). MIME type : str response body MIME type (e.g. application/x-protobuf). body : bytes VT body. """ if not urls: raise TilerError("Missing 'urls' parameter") if nodata is not None and isinstance(nodata, str): nodata = numpy.nan if nodata == "nan" else float(nodata) tilesize = 256 * scale tile, mask = mosaic_tiler( urls.split(","), x, y, z, main.tile, tilesize=tilesize, nodata=nodata, pixel_selection=pixel_selection, resampling_method=resampling_method, ) if tile is None: return ("EMPTY", "text/plain", "empty tiles") band_descriptions = _get_layer_names(urls.split(",")[0]) return ( "OK", "application/x-protobuf", mvtEncoder( tile, mask, band_descriptions, "mosaic", feature_type=feature_type, ), )
def _img( mosaicid: str = None, z: int = None, x: int = None, y: int = None, scale: int = 1, ext: str = None, url: str = None, indexes: Optional[Sequence[int]] = None, rescale: str = None, color_ops: str = None, color_map: str = None, pixel_selection: str = "first", resampling_method: str = "nearest", ) -> Tuple: """Handle tile requests.""" if not mosaicid and not url: return ("NOK", "text/plain", "Missing 'MosaicID or URL' parameter") mosaic_path = _create_mosaic_path(mosaicid) if mosaicid else url with MosaicBackend(mosaic_path) as mosaic: assets = mosaic.tile(x, y, z) if not assets: return ("EMPTY", "text/plain", f"No assets found for tile {z}-{x}-{y}") if indexes is not None and isinstance(indexes, str): indexes = list(map(int, indexes.split(","))) tilesize = 256 * scale if pixel_selection == "last": pixel_selection = "first" assets = list(reversed(assets)) with rasterio.Env(aws_session): pixsel_method = PIXSEL_METHODS[pixel_selection] tile, mask = mosaic_tiler( assets, x, y, z, cogeoTiler, indexes=indexes, tilesize=tilesize, pixel_selection=pixsel_method(), resampling_method=resampling_method, ) if tile is None: return ("EMPTY", "text/plain", "empty tiles") rtile = _postprocess(tile, mask, rescale=rescale, color_formula=color_ops) if not ext: ext = "jpg" if mask.all() else "png" driver = "jpeg" if ext == "jpg" else ext options = img_profiles.get(driver, {}) if ext == "tif": ext = "tiff" driver = "GTiff" options = geotiff_options(x, y, z, tilesize) if color_map: options["colormap"] = cmap.get(color_map) return ( "OK", f"image/{ext}", render(rtile, mask, img_format=driver, **options), )
def read_tile(threads, asset_list): """Benchmark rio-tiler.utils._tile_read.""" with rasterio.Env( GDAL_CACHEMAX=0, GDAL_DISABLE_READDIR_ON_OPEN="EMPTY_DIR", ): return mosaic.mosaic_tiler(asset_list, 150, 180, 9, _tiler, threads=threads)
def tiles( url: str, z: int, x: int, y: int, scale: int = 1, ext: str = "png", bands: str = None, expr: str = None, rescale: str = None, color_ops: str = None, color_map: str = None, pan: bool = False, pixel_selection: str = "first", ) -> Tuple[str, str, BinaryIO]: """Handle tile requests.""" with MosaicBackend(url) as mosaic: assets = mosaic.tile(x, y, z) if not assets: return ("EMPTY", "text/plain", f"No assets found for tile {z}-{x}-{y}") tilesize = 256 * scale pixel_selection = pixSel[pixel_selection] if expr is not None: tile, mask = mosaic_tiler( assets, x, y, z, expressionTiler, pixel_selection=pixel_selection(), expr=expr, tilesize=tilesize, pan=pan, ) elif bands is not None: tile, mask = mosaic_tiler( assets, x, y, z, landsatTiler, pixel_selection=pixel_selection(), bands=tuple(bands.split(",")), tilesize=tilesize, pan=pan, ) else: return ("NOK", "text/plain", "No bands nor expression given") if tile is None: return ("EMPTY", "text/plain", "empty tiles") if color_map: color_map = get_colormap(color_map, format="gdal") assets_str = json.dumps(assets, separators=(",", ":")) return_kwargs = {"custom_headers": {"X-ASSETS": assets_str}} if ext == "gif": frames = [] options = img_profiles.get("png", {}) for i in range(len(tile)): img = post_process_tile(tile[i].copy(), mask[i].copy(), rescale=rescale, color_formula=color_ops) frames.append( Image.open( io.BytesIO( render( img, mask[i], img_format="png", colormap=color_map, **options, )))) sio = io.BytesIO() frames[0].save( sio, "gif", save_all=True, append_images=frames[1:], duration=300, loop=0, optimize=True, ) sio.seek(0) return ("OK", f"image/{ext}", sio.getvalue(), return_kwargs) rtile = post_process_tile(tile, mask, rescale=rescale, color_formula=color_ops) if ext == "bin": # Flatten in Row-major order buf = rtile.tobytes(order='C') return ("OK", "application/x-binary", buf, return_kwargs) driver = "jpeg" if ext == "jpg" else ext options = img_profiles.get(driver, {}) if ext == "tif": ext = "tiff" driver = "GTiff" tile_bounds = mercantile.xy_bounds(mercantile.Tile(x=x, y=y, z=z)) options = dict( crs={"init": "EPSG:3857"}, transform=from_bounds(*tile_bounds, tilesize, tilesize), ) return ( "OK", f"image/{ext}", render(rtile, mask, img_format=driver, colormap=color_map, **options), return_kwargs, )
def test_mosaic_tiler(): """Test mosaic tiler.""" # test with default and full covered tile and default options t, m = mosaic.mosaic_tiler(assets, x, y, z, cogTiler) assert t.shape == (3, 256, 256) assert m.shape == (256, 256) assert m.all() assert t[0][-1][-1] == 8000 # Test last pixel selection assetsr = list(reversed(assets)) t, m = mosaic.mosaic_tiler(assetsr, x, y, z, cogTiler) assert t.shape == (3, 256, 256) assert m.shape == (256, 256) assert m.all() assert t[0][-1][-1] == 7645 t, m = mosaic.mosaic_tiler(assets, x, y, z, cogTiler, indexes=1) assert t.shape == (1, 256, 256) assert m.shape == (256, 256) assert t.all() assert m.all() assert t[0][-1][-1] == 8000 # Test darkest pixel selection t, m = mosaic.mosaic_tiler( assets, x, y, z, cogTiler, pixel_selection=defaults.LowestMethod() ) assert m.all() assert t[0][-1][-1] == 7645 to, mo = mosaic.mosaic_tiler( assets_order, x, y, z, cogTiler, pixel_selection=defaults.LowestMethod() ) numpy.testing.assert_array_equal(t[0, m], to[0, mo]) # Test brightest pixel selection t, m = mosaic.mosaic_tiler( assets, x, y, z, cogTiler, pixel_selection=defaults.HighestMethod() ) assert m.all() assert t[0][-1][-1] == 8000 to, mo = mosaic.mosaic_tiler( assets_order, x, y, z, cogTiler, pixel_selection=defaults.HighestMethod() ) numpy.testing.assert_array_equal(to, t) numpy.testing.assert_array_equal(mo, m) # test with default and partially covered tile t, m = mosaic.mosaic_tiler( assets, xp, yp, zp, cogTiler, pixel_selection=defaults.HighestMethod() ) assert t.any() assert not m.all() # test when tiler raise errors (outside bounds) t, m = mosaic.mosaic_tiler(assets, 150, 300, 9, cogTiler) assert not t assert not m # Test mean pixel selection t, m = mosaic.mosaic_tiler( assets, x, y, z, cogTiler, pixel_selection=defaults.MeanMethod() ) assert t.shape == (3, 256, 256) assert m.shape == (256, 256) assert m.all() assert t[0][-1][-1] == 7822 # Test mean pixel selection t, m = mosaic.mosaic_tiler( assets, x, y, z, cogTiler, pixel_selection=defaults.MeanMethod(enforce_data_type=False), ) assert m.all() assert t[0][-1][-1] == 7822.5 # Test median pixel selection t, m = mosaic.mosaic_tiler( assets, x, y, z, cogTiler, pixel_selection=defaults.MedianMethod() ) assert t.shape == (3, 256, 256) assert m.shape == (256, 256) assert m.all() assert t[0][-1][-1] == 7822 # Test median pixel selection t, m = mosaic.mosaic_tiler( assets, x, y, z, cogTiler, pixel_selection=defaults.MedianMethod(enforce_data_type=False), ) assert m.all() assert t[0][-1][-1] == 7822.5 # Test invalid Pixel Selection class with pytest.raises(Exception): class aClass(object): pass mosaic.mosaic_tiler(assets, x, y, z, cogTiler, pixel_selection=aClass())
def _img( mosaicid: str = None, z: int = None, x: int = None, y: int = None, scale: int = 1, ext: str = None, url: str = None, indexes: str = None, rescale: str = None, color_ops: str = None, color_map: str = None, pixel_selection: str = "first", resampling_method: str = "nearest", ) -> Tuple[str, str, BinaryIO]: """Handle tile requests.""" if mosaicid: url = _create_path(mosaicid) elif url is None: return ("NOK", "text/plain", "Missing 'URL' parameter") assets = fetch_and_find_assets(url, x, y, z) if not assets: return ("EMPTY", "text/plain", f"No assets found for tile {z}-{x}-{y}") if indexes: indexes = list(map(int, indexes.split(","))) tilesize = 256 * scale if pixel_selection == "last": pixel_selection = "first" assets = list(reversed(assets)) with rasterio.Env(aws_session): pixsel_method = PIXSEL_METHODS[pixel_selection] tile, mask = mosaic_tiler( assets, x, y, z, cogeoTiler, indexes=indexes, tilesize=tilesize, pixel_selection=pixsel_method(), resampling_method=resampling_method, ) if tile is None: return ("EMPTY", "text/plain", "empty tiles") rtile = _postprocess(tile, mask, rescale=rescale, color_formula=color_ops) if color_map: if color_map.startswith("custom_"): color_map = get_custom_cmap(color_map) else: color_map = get_colormap(color_map, format="gdal") if not ext: ext = "jpg" if mask.all() else "png" driver = "jpeg" if ext == "jpg" else ext options = img_profiles.get(driver, {}) if ext == "tif": ext = "tiff" driver = "GTiff" tile_bounds = mercantile.xy_bounds(mercantile.Tile(x=x, y=y, z=z)) options = dict( crs={"init": "EPSG:3857"}, transform=from_bounds(*tile_bounds, tilesize, tilesize), ) return ( "OK", f"image/{ext}", array_to_image(rtile, mask, img_format=driver, color_map=color_map, **options), )