Esempio n. 1
0
def test_feature():
    """TileSchema.feature should create proper geojson feature."""
    tms = morecantile.tms.get("WebMercatorQuad")
    feat = tms.feature(morecantile.Tile(1, 0, 1))
    assert feat["bbox"]
    assert feat["id"]
    assert feat["geometry"]
    assert len(feat["properties"].keys()) == 3

    feat = tms.feature(
        morecantile.Tile(1, 0, 1),
        buffer=-10,
        precision=4,
        fid="1",
        props={"some": "thing"},
    )
    assert feat["bbox"]
    assert feat["id"] == "1"
    assert feat["geometry"]
    assert len(feat["properties"].keys()) == 4

    with pytest.warns(UserWarning):
        feat = tms.feature(
            morecantile.Tile(1, 0, 1), projected=True, fid="1", props={"some": "thing"}
        )
    assert feat["bbox"]
    assert feat["id"] == "1"
    assert feat["geometry"]
    assert len(feat["properties"].keys()) == 4
Esempio n. 2
0
def test_tiles():
    """Test tiles from bbox."""
    tms = morecantile.tms.get("WebMercatorQuad")

    # replicate mercantile tests
    # https://github.com/mapbox/mercantile/blob/master/tests/test_funcs.py#L115-L178
    bounds = (-105, 39.99, -104.99, 40)
    tiles = list(tms.tiles(*bounds, zooms=[14]))
    expect = [
        morecantile.Tile(x=3413, y=6202, z=14),
        morecantile.Tile(x=3413, y=6203, z=14),
    ]
    assert sorted(tiles) == sorted(expect)

    # Single zoom
    bounds = (-105, 39.99, -104.99, 40)
    tiles = list(tms.tiles(*bounds, zooms=14))
    expect = [
        morecantile.Tile(x=3413, y=6202, z=14),
        morecantile.Tile(x=3413, y=6203, z=14),
    ]
    assert sorted(tiles) == sorted(expect)

    # Input is truncated
    assert list(tms.tiles(-181.0, 0.0, -170.0, 10.0, zooms=[2],
                          truncate=True)) == list(
                              tms.tiles(-180.0, 0.0, -170.0, 10.0, zooms=[2]))

    # Antimeridian-crossing bounding boxes are handled
    bounds = (175.0, 5.0, -175.0, 10.0)
    assert len(list(tms.tiles(*bounds, zooms=[2]))) == 2
Esempio n. 3
0
def test_children():
    """test children."""
    tms = morecantile.tms.get("WebMercatorQuad")

    x, y, z = 243, 166, 9
    children = tms.children(x, y, z)
    assert len(children) == 4
    assert morecantile.Tile(2 * x, 2 * y, z + 1) in children
    assert morecantile.Tile(2 * x + 1, 2 * y, z + 1) in children
    assert morecantile.Tile(2 * x + 1, 2 * y + 1, z + 1) in children
    assert morecantile.Tile(2 * x, 2 * y + 1, z + 1) in children
Esempio n. 4
0
 async def tile(
     self,
     x: int,
     y: int,
     z: int,
     tile_size: int = 256,
     tms: TileMatrixSet = DEFAULT_TMS,
     resample_method: int = Image.NEAREST,
 ) -> np.ndarray:
     tile = morecantile.Tile(x=x, y=y, z=z)
     tile_bounds = tms.xy_bounds(tile)
     width = height = tile_size
     if self.cog.epsg != tms.crs:
         arr = await self._warped_read(
             tile_bounds,
             width,
             height,
             bounds_crs=tms.crs,
             resample_method=resample_method,
         )
     else:
         arr = await self.cog.read(tile_bounds,
                                   shape=(width, height),
                                   resample_method=resample_method)
     return arr
Esempio n. 5
0
async def TileParams(
        z: int = Path(..., ge=0, le=30, description="Tiles's zoom level"),
        x: int = Path(..., description="Tiles's column"),
        y: int = Path(..., description="Tiles's row"),
) -> morecantile.Tile:
    """Tile parameters."""
    return morecantile.Tile(x, y, z)
Esempio n. 6
0
def get_web_optimized_params(
    src_dst,
    zoom_level_strategy: str = "auto",
    zoom_level: Optional[int] = None,
    aligned_levels: Optional[int] = None,
    tms: morecantile.TileMatrixSet = morecantile.tms.get("WebMercatorQuad"),
) -> Dict:
    """Return VRT parameters for a WebOptimized COG."""
    if src_dst.crs != tms.rasterio_crs:
        with WarpedVRT(src_dst, crs=tms.rasterio_crs) as vrt:
            bounds = vrt.bounds
            aff = list(vrt.transform)
    else:
        bounds = src_dst.bounds
        aff = list(src_dst.transform)

    resolution = max(abs(aff[0]), abs(aff[4]))

    if zoom_level is None:
        # find max zoom (closest to the raster resolution)
        max_zoom = tms.zoom_for_res(
            resolution,
            max_z=30,
            zoom_level_strategy=zoom_level_strategy,
        )
    else:
        max_zoom = zoom_level

    # defined the zoom level we want to align the raster
    aligned_levels = aligned_levels or 0
    base_zoom = max_zoom - aligned_levels

    # find new raster bounds (bounds of UL tile / LR tile)
    ul_tile = tms._tile(bounds[0], bounds[3], base_zoom)
    w, _, _, n = tms.xy_bounds(ul_tile)

    # The output resolution should match the TMS resolution at MaxZoom
    vrt_res = tms._resolution(tms.matrix(max_zoom))

    # Output transform is built from the origin (UL tile) and output resolution
    vrt_transform = Affine(vrt_res, 0, w, 0, -vrt_res, n)

    lr_tile = tms._tile(bounds[2], bounds[1], base_zoom)
    e, _, _, s = tms.xy_bounds(
        morecantile.Tile(lr_tile.x + 1, lr_tile.y + 1, lr_tile.z)
    )

    vrt_width = max(1, round((e - w) / vrt_transform.a))
    vrt_height = max(1, round((s - n) / vrt_transform.e))

    return dict(
        crs=tms.rasterio_crs,
        transform=vrt_transform,
        width=vrt_width,
        height=vrt_height,
    )
Esempio n. 7
0
def test_bounds(zoom: int):
    """Make sure mercantile and morecantile returns the same thing."""
    # get random x,y index
    x = sample(range(0, tms.matrix(zoom).matrixWidth), 1)[0]
    y = sample(range(0, tms.matrix(zoom).matrixHeight), 1)[0]

    for a, b in zip(
        mercantile.xy_bounds(x, y, zoom), tms.xy_bounds(morecantile.Tile(x, y, zoom))
    ):
        assert round(a - b, 7) == 0
Esempio n. 8
0
def test_parent():
    """test parent"""
    tms = morecantile.tms.get("WebMercatorQuad")
    parent = tms.parent(486, 332, 10)
    assert parent[0] == morecantile.Tile(243, 166, 9)

    with pytest.raises(InvalidZoomError):
        tms.parent(486, 332, 10, zoom=11)

    assert tms.parent(0, 0, 0) == []
def test_tiles():
    """Test tiles from bbox."""
    tms = morecantile.tms.get("WebMercatorQuad")

    # replicate mercantile tests
    # https://github.com/mapbox/mercantile/blob/master/tests/test_funcs.py#L115-L178
    bounds = (-105, 39.99, -104.99, 40)
    tiles = list(tms.tiles(*bounds, zooms=[14]))
    expect = [
        morecantile.Tile(x=3413, y=6202, z=14),
        morecantile.Tile(x=3413, y=6203, z=14),
    ]
    assert sorted(tiles) == sorted(expect)

    # Single zoom
    bounds = (-105, 39.99, -104.99, 40)
    tiles = list(tms.tiles(*bounds, zooms=14))
    expect = [
        morecantile.Tile(x=3413, y=6202, z=14),
        morecantile.Tile(x=3413, y=6203, z=14),
    ]
    assert sorted(tiles) == sorted(expect)

    # Input is truncated
    assert list(tms.tiles(-181.0, 0.0, -170.0, 10.0, zooms=[2],
                          truncate=True)) == list(
                              tms.tiles(-180.0, 0.0, -170.0, 10.0, zooms=[2]))

    # Antimeridian-crossing bounding boxes are handled
    bounds = (175.0, 5.0, -175.0, 10.0)
    assert len(list(tms.tiles(*bounds, zooms=[2]))) == 2

    # Y is clamped to (0, 2 ** zoom - 1)
    tiles = list(tms.tiles(-180, -90, 180, 90, [1]))
    assert len(tiles) == 4
    assert min(t.y for t in tiles) == 0
    assert max(t.y for t in tiles) == 1

    # tiles(bounds(tile)) gives the tile's children
    t = morecantile.Tile(x=3413, y=6202, z=14)
    res = list(tms.tiles(*tms.bounds(t), zooms=[15]))
    assert len(res) == 4
Esempio n. 10
0
def test_tile_coordinates():
    """Test coordinates to tile index utils."""
    tms = morecantile.tms.get("WebMercatorQuad")
    assert tms.tile(-179, 85, 5) == (0, 0, 5)

    # Check equivalence between mercantile and morecantile
    # wlon, wlat = mercantile.xy(20.0, 15.0)
    assert tms.tile(20.0, 15.0, 5) == mercantile.tile(20.0, 15.0, 5)

    tms = morecantile.tms.get("WorldCRS84Quad")
    assert tms.tile(-39.8, 74.2, 4) == morecantile.Tile(12, 1, 4)
Esempio n. 11
0
def geotiff_options(
    x: int,
    y: int,
    z: int,
    tilesize: int = 256,
    tms: morecantile.TileMatrixSet = default_tms,
) -> Dict:
    """GeoTIFF options."""
    bounds = tms.xy_bounds(morecantile.Tile(x=x, y=y, z=z))
    dst_transform = from_bounds(*bounds, tilesize, tilesize)
    return dict(crs=tms.crs, transform=dst_transform)
Esempio n. 12
0
def test_InvertedLatLonGrids():
    """Check Inverted LatLon grids."""
    tms = morecantile.tms.get("NZTM2000")
    bound = tms.xy_bounds(morecantile.Tile(1, 2, 0))
    assert bound == (1293760.0, 3118720.0, 3587520.0, 5412480.0)
    assert tms.xy_bbox == (274000.0, 3087000.0, 3327000.0, 7173000.0)

    tms = morecantile.tms.get("LINZAntarticaMapTilegrid")
    assert tms.xy_bbox == (
        -918457.73,
        -22441670.269999996,
        28441670.269999996,
        6918457.73,
    )
Esempio n. 13
0
def test_reader_tiles(rio):
    """Test STACReader.tile."""
    rio.open = mock_rasterio_open

    tile = morecantile.Tile(z=9, x=289, y=207)

    with STACReader(STAC_PATH) as stac:
        with pytest.raises(InvalidAssetName):
            stac.tile(*tile, assets="B1")

        with pytest.raises(MissingAssets):
            stac.tile(*tile)

        data, mask = stac.tile(*tile, assets="B01")
        assert data.shape == (1, 256, 256)
        assert mask.shape == (256, 256)

    with STACReader(STAC_PATH) as stac:
        data, mask = stac.tile(*tile, expression="B01/B02")
        assert data.shape == (1, 256, 256)
        assert mask.shape == (256, 256)

    with STACReader(STAC_PATH) as stac:
        data, mask = stac.tile(*tile, assets=["B01", "B02"])
        assert data.shape == (2, 256, 256)
        assert mask.shape == (256, 256)

    # This is possible but user should not to it ;-)
    # We are reading B01 and B02 and telling rasterio to return twice bidx 1.
    with STACReader(STAC_PATH) as stac:
        data, mask = stac.tile(*tile, assets=["B01", "B02"], indexes=(1, 1))
        assert data.shape == (4, 256, 256)
        assert mask.shape == (256, 256)

    # Power User might use expression for each assets
    with STACReader(STAC_PATH) as stac:
        data, mask = stac.tile(*tile,
                               assets=["B01", "B02"],
                               asset_expression="b1/2")
        assert data.shape == (2, 256, 256)
        assert mask.shape == (256, 256)

    with STACReader(STAC_PATH,
                    tms=morecantile.tms.get("WorldCRS84Quad")) as stac:
        data, mask = stac.tile(4, 1, 2, assets="B01")
        assert data.shape == (1, 256, 256)
        assert mask.shape == (256, 256)
Esempio n. 14
0
    def tile(
        self,
        tile_x: int,
        tile_y: int,
        tile_z: int,
        tilesize: int = 256,
        indexes: Optional[Sequence] = None,
        expression: Optional[str] = "",
        **kwargs: Any,
    ) -> Tuple[numpy.ndarray, numpy.ndarray]:
        """Read a TMS map tile from a COG."""
        kwargs = {**self._kwargs, **kwargs}

        if isinstance(indexes, int):
            indexes = (indexes, )

        if expression:
            indexes = parse_expression(expression)

        tile = morecantile.Tile(x=tile_x, y=tile_y, z=tile_z)
        if not self._tile_exists(tile):
            raise TileOutsideBounds(
                "Tile {}/{}/{} is outside image bounds".format(
                    tile_z, tile_x, tile_y))

        tile_bounds = self.tms.xy_bounds(*tile)
        tile, mask = reader.part(
            self.dataset,
            tile_bounds,
            tilesize,
            tilesize,
            dst_crs=self.tms.crs,
            indexes=indexes,
            **kwargs,
        )
        if expression:
            blocks = expression.lower().split(",")
            bands = [f"b{bidx}" for bidx in indexes]
            tile = apply_expression(blocks, bands, tile)

        return tile, mask
Esempio n. 15
0
    async def tile(
        self,
        tile_x: int,
        tile_y: int,
        tile_z: int,
        tilesize: int = 256,
        indexes: Optional[Union[int, Sequence]] = None,
        expression: Optional[str] = "",  # placeholder
        resampling_method: str = "nearest",
    ) -> TileResponse:
        """tile"""

        if isinstance(indexes, int):
            indexes = (indexes,)

        tile = morecantile.Tile(x=tile_x, y=tile_y, z=tile_z)
        tile_bounds = self.tms.xy_bounds(tile)

        # resampling_method -> resample_method
        resample_method = RESAMPLING[resampling_method]

        width = height = tilesize
        if self.epsg != self.tms.crs.to_epsg():
            arr = await self._warped_read(
                tile_bounds,
                width,
                height,
                bounds_crs=self.tms.crs,
                resample_method=resample_method,
            )
        else:
            arr = await self.read(
                tile_bounds, shape=(width, height), resample_method=resample_method
            )

        # should be handled at read level
        if indexes:
            arr = arr[[r - 1 for r in indexes]]

        return TileResponse.from_array(arr)
Esempio n. 16
0
def test_parent_multi():
    """test parent"""
    tms = morecantile.tms.get("WebMercatorQuad")
    parent = tms.parent(486, 332, 10, zoom=8)
    assert parent[0] == morecantile.Tile(121, 83, 8)
Esempio n. 17
0
def test_tiles_roundtrip_children():
    """tiles(bounds(tile)) gives the tile's children"""
    tms = morecantile.tms.get("WebMercatorQuad")
    t = morecantile.Tile(x=3413, y=6202, z=14)
    res = list(tms.tiles(*tms.bounds(t), zooms=[15]))
    assert len(res) == 4
Esempio n. 18
0
"""test masks."""

import os

import morecantile
import numpy
import pytest
from rasterio.coords import BoundingBox
from rasterio.crs import CRS

from rio_tiler.io import COGReader

tiles = {
    "masked": morecantile.Tile(x=535, y=498, z=10),
    "boundless": morecantile.Tile(x=540, y=497, z=10),
}
equator = {
    "name":
    "equator",
    "bounds":
    BoundingBox(left=382792.5, bottom=362992.5, right=610507.5, top=595207.5),
    "crs":
    CRS.from_epsg(32632),
}

dataset = [
    dict(equator, dtype="uint8", nodata_type="alpha"),
    dict(equator, dtype="uint8", nodata_type="nodata"),
    dict(equator, dtype="uint8", nodata_type="mask"),
    dict(equator, dtype="int8", nodata_type="alpha"),
    dict(equator, dtype="int8", nodata_type="nodata"),
Esempio n. 19
0
    assert tms.minzoom == 0
    assert tms.maxzoom == 24


def test_tile_coordinates():
    """Test coordinates to tile index utils."""
    tms = morecantile.tms.get("WebMercatorQuad")
    assert tms.tile(-179, 85, 5) == (0, 0, 5)

    # Check equivalence between mercantile and morecantile
    # wlon, wlat = mercantile.xy(20.0, 15.0)
    assert tms.tile(20.0, 15.0, 5) == mercantile.tile(20.0, 15.0, 5)


@pytest.mark.parametrize(
    "args", [(486, 332, 10), [(486, 332, 10)], [morecantile.Tile(486, 332, 10)]]
)
def test_bounds(args):
    """
    TileMatrixSet.bounds should return the correct coordinates.

    test form https://github.com/mapbox/mercantile/blob/master/tests/test_funcs.py
    """
    expected = (-9.140625, 53.12040528310657, -8.7890625, 53.33087298301705)
    tms = morecantile.tms.get("WebMercatorQuad")
    bbox = tms.bounds(*args)
    for a, b in zip(expected, bbox):
        assert round(a - b, 7) == 0
    assert bbox.left == bbox[0]
    assert bbox.bottom == bbox[1]
    assert bbox.right == bbox[2]
Esempio n. 20
0
def test_tile_coordinates():
    """Test coordinates to tile index utils."""
    tms = morecantile.tms.get("WebMercatorQuad")
    assert tms.tile(-179, 85, 5) == (0, 0, 5)

    # Check equivalence between mercantile and morecantile
    # wlon, wlat = mercantile.xy(20.0, 15.0)
    assert tms.tile(20.0, 15.0, 5) == mercantile.tile(20.0, 15.0, 5)

    tms = morecantile.tms.get("WorldCRS84Quad")
    assert tms.tile(-39.8, 74.2, 4) == morecantile.Tile(12, 1, 4)


@pytest.mark.parametrize(
    "args",
    [(486, 332, 10), [(486, 332, 10)], [morecantile.Tile(486, 332, 10)]])
def test_bounds(args):
    """
    TileMatrixSet.bounds should return the correct coordinates.

    test form https://github.com/mapbox/mercantile/blob/master/tests/test_funcs.py
    """
    expected = (-9.140625, 53.12040528310657, -8.7890625, 53.33087298301705)
    tms = morecantile.tms.get("WebMercatorQuad")
    bbox = tms.bounds(*args)
    for a, b in zip(expected, bbox):
        assert round(a - b, 7) == 0
    assert bbox.left == bbox[0]
    assert bbox.bottom == bbox[1]
    assert bbox.right == bbox[2]
    assert bbox.top == bbox[3]
Esempio n. 21
0
 async def tile(self, tile_x: int, tile_y: int, tile_z: int,
                columns: str) -> bytes:
     """read vector tile"""
     tile = morecantile.Tile(tile_x, tile_y, tile_z)
     bbox = self.tms.xy_bounds(tile)
     return await self._tile_from_bbox(bbox, columns)
Esempio n. 22
0
def test_nztm_quad_is_quad():
    tms = morecantile.tms.get("NZTM2000Quad")
    bound = tms.xy_bounds(morecantile.Tile(0, 0, 0))
    expected = (-3260586.7284, 419435.9938, 6758167.443, 10438190.1652)
    for a, b in zip(expected, bound):
        assert round(a - b, 4) == 0
Esempio n. 23
0
def test_projtile():
    """TileSchema._tile should return the correct tile."""
    tms = morecantile.tms.get("WebMercatorQuad")
    assert tms._tile(1000, 1000, 1) == morecantile.Tile(1, 0, 1)
Esempio n. 24
0
"""rio-tiler.tests.benchmarks."""

import morecantile
from rasterio.coords import BoundingBox
from rasterio.crs import CRS

benchmark_tiles = {
    "north": {
        "full": morecantile.Tile(x=70, y=17, z=7),
        "masked": morecantile.Tile(x=69, y=16, z=7),
        "boundless": morecantile.Tile(x=68, y=17, z=7),
    },
    "south": {
        "full": morecantile.Tile(x=124, y=108, z=7),
        "masked": morecantile.Tile(x=125, y=109, z=7),
        "boundless": morecantile.Tile(x=122, y=107, z=7),
    },
    "equator": {
        "full": morecantile.Tile(x=537, y=499, z=10),
        "masked": morecantile.Tile(x=535, y=498, z=10),
        "boundless": morecantile.Tile(x=540, y=497, z=10),
    },
    "dateline": {
        "full": morecantile.Tile(x=510, y=169, z=10),
        "masked": morecantile.Tile(x=510, y=168, z=10),
        "boundless": morecantile.Tile(x=509, y=171, z=10),
    },
}

# LC08_L1TP_212004_20190816_20190902_01_T1
north = {