Example #1
0
def test_create_mosaic():
    """Create mosaic from tiles."""
    tp = BufferedTilePyramid("geodetic")
    # quick return mosaic if there is just one tile
    tile = tp.tile(3, 3, 3)
    data = np.ones(tile.shape)
    mosaic = create_mosaic([(tile, data)])
    assert isinstance(mosaic, ReferencedRaster)
    assert np.array_equal(data, mosaic.data)
    assert tile.affine == mosaic.affine
    zoom = 5
    # multiple tiles on top left corner of tile matrix
    for pixelbuffer in [0, 10]:
        tp = BufferedTilePyramid("geodetic", pixelbuffer=pixelbuffer)
        tiles = [
            (tp.tile(zoom, row, col), np.ones(tp.tile(zoom, row, col).shape))
            for row, col in product(range(4), range(4))
        ]
        # 4x4 top left tiles from zoom 5 equal top left tile from zoom 3
        # also use tile generator
        mosaic = create_mosaic((t for t in tiles))
        assert isinstance(mosaic, ReferencedRaster)
        assert np.all(np.where(mosaic.data == 1, True, False))
        mosaic_bbox = box(
            mosaic.affine[2],
            mosaic.affine[5] + mosaic.data.shape[1] * mosaic.affine[4],
            mosaic.affine[2] + mosaic.data.shape[2] * mosaic.affine[0],
            mosaic.affine[5]
        )
        control_bbox = box(*unary_union([t.bbox for t, _ in tiles]).bounds)
        assert mosaic_bbox.equals(control_bbox)
    # multiple tiles on bottom right corner of tile matrix
    for pixelbuffer in [0, 10]:
        tp = BufferedTilePyramid("geodetic", pixelbuffer=pixelbuffer)
        tiles = [
            (tp.tile(zoom, row, col), np.ones(tp.tile(zoom, row, col).shape))
            for row, col in product(
                range(tp.matrix_height(zoom) - 4, tp.matrix_height(zoom)),
                range(tp.matrix_width(zoom) - 4, tp.matrix_width(zoom))
            )
        ]
        # 4x4 top left tiles from zoom 5 equal top left tile from zoom 3
        # also use tile generator
        mosaic = create_mosaic((t for t in tiles))
        assert isinstance(mosaic, ReferencedRaster)
        assert np.all(np.where(mosaic.data == 1, True, False))
        mosaic_bbox = box(
            mosaic.affine[2],
            mosaic.affine[5] + mosaic.data.shape[1] * mosaic.affine[4],
            mosaic.affine[2] + mosaic.data.shape[2] * mosaic.affine[0],
            mosaic.affine[5]
        )
        control_bbox = box(*unary_union([t.bbox for t, _ in tiles]).bounds)
        assert mosaic_bbox.equals(control_bbox)
Example #2
0
def test_count_tiles_mercator():
    for metatiling in [1, 2, 4, 8, 16]:
        tp = BufferedTilePyramid("mercator", metatiling=metatiling)
        for zoom in range(13):
            count_by_geom = count_tiles(box(*tp.bounds), tp, zoom, zoom)
            count_by_tp = tp.matrix_width(zoom) * tp.matrix_height(zoom)
            assert count_by_geom == count_by_tp
Example #3
0
def test_create_mosaic_antimeridian():
    """Create mosaic using tiles on opposing antimeridian sides."""
    zoom = 5
    row = 0
    pixelbuffer = 5
    tp = BufferedTilePyramid("geodetic", pixelbuffer=pixelbuffer)
    west = tp.tile(zoom, row, 0)
    east = tp.tile(zoom, row, tp.matrix_width(zoom) - 1)
    for tile in [west, east]:
        tile.data = np.ones(tile.shape)
    mosaic = raster.create_mosaic([west, east])
    assert isinstance(mosaic, raster.ReferencedRaster)
    # Huge array gets initialized because the two tiles are on opposing sides
    # of the projection area. The below test should pass if the tiles are
    # stitched together next to each other.
    assert mosaic.data.shape == (1, west.height,
                                 west.width * 2 - 2 * pixelbuffer)
Example #4
0
def test_shift_required():
    zoom = 11
    row = 711
    tp = BufferedTilePyramid("mercator")
    tiles = [(tp.tile(zoom, row, i), None) for i in range(1, 5)]

    # all tiles are connected without passing the Antimeridian, so no shift is required
    assert not _shift_required(tiles)

    # add one tile connected on the other side of the Antimeridian and a shift is required
    tiles.append((tp.tile(zoom, row, tp.matrix_width(zoom) - 1), None))
    assert _shift_required(tiles)

    # leave one column and add one tile
    tiles = [(tp.tile(zoom, row, i), None) for i in range(2, 5)]
    tiles.append((tp.tile(zoom, row, 6), None))
    tiles.append((tp.tile(zoom, row, 8), None))
    tiles.append((tp.tile(zoom, row, 9), None))
    assert not _shift_required(tiles)
Example #5
0
def test_create_mosaic_antimeridian():
    """Create mosaic using tiles on opposing antimeridian sides."""
    zoom = 5
    row = 0
    pixelbuffer = 5
    tp = BufferedTilePyramid("geodetic", pixelbuffer=pixelbuffer)
    west = tp.tile(zoom, row, 0)
    east = tp.tile(zoom, row, tp.matrix_width(zoom) - 1)
    mosaic = create_mosaic([(west, np.ones(west.shape).astype("uint8")),
                            (east, np.ones(east.shape).astype("uint8") * 2)])
    assert isinstance(mosaic, ReferencedRaster)

    # Huge array gets initialized because the two tiles are on opposing sides of the
    # projection area. The below test should pass if the tiles are stitched together next
    # to each other.
    assert mosaic.data.shape == (1, west.height,
                                 west.width * 2 - 2 * pixelbuffer)
    assert mosaic.data[0][0][0] == 2
    assert mosaic.data[0][0][-1] == 1

    # If tiles from opposing sides from Antimeridian are mosaicked it will happen that the
    # output mosaic exceeds the CRS bounds (obviously). In such a case the mosaicking
    # function shall make sure that the larger part of the output mosaic shall be inside
    # the CRS bounds.

    # (1) mosaic crosses Antimeridian in the West, larger part is on Western hemisphere:
    tiles_ids = [
        # Western hemisphere tiles
        (zoom, row, 0),
        (zoom, row, 1),
        # Eastern hemisphere tile
        (zoom, row, tp.matrix_width(zoom) - 1),
    ]
    tiles = [(tp.tile(*tile_id), np.ones(tp.tile(*tile_id).shape))
             for tile_id in tiles_ids]
    mosaic = create_mosaic(tiles)
    control_bounds = Bounds(
        # Eastern tile has to be shifted
        -(360 - tp.tile(*tiles_ids[2]).left),
        tp.tile(*tiles_ids[2]).bottom,
        tp.tile(*tiles_ids[1]).right,
        tp.tile(*tiles_ids[1]).top,
    )
    assert mosaic.bounds == control_bounds

    # (2) mosaic crosses Antimeridian in the West, larger part is on Eastern hemisphere:
    tiles_ids = [
        # Western hemisphere tile
        (zoom, row, 0),
        # Eastern hemisphere tiles
        (zoom, row, tp.matrix_width(zoom) - 1),
        (zoom, row, tp.matrix_width(zoom) - 2),
    ]
    tiles = [(tp.tile(*tile_id), np.ones(tp.tile(*tile_id).shape))
             for tile_id in tiles_ids]
    mosaic = create_mosaic(tiles)
    control_bounds = Bounds(
        tp.tile(*tiles_ids[2]).left,
        tp.tile(*tiles_ids[2]).bottom,
        # Western tile has to be shifted
        360 + tp.tile(*tiles_ids[0]).right,
        tp.tile(*tiles_ids[0]).top,
    )
    assert mosaic.bounds == control_bounds