Example #1
0
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)
Example #2
0
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())
Example #3
0
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())
Example #4
0
                        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
Example #5
0
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,
            ),
        )
Example #6
0
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),
    )
Example #7
0
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]])
Example #9
0
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
Example #10
0
                    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
Example #11
0
 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,
     )
Example #12
0
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),
    )
Example #13
0
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),
    )
Example #14
0
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,
        ),
    )
Example #15
0
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)
Example #17
0
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())
Example #19
0
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),
    )