Beispiel #1
0
def test_cog_translate_web_align():
    """
    Test Web-Optimized COG.

    - Test COG bounds (thus block) is aligned with Zoom levels

    """
    tms = morecantile.tms.get("WebMercatorQuad")

    runner = CliRunner()
    with runner.isolated_filesystem():

        web_profile = cog_profiles.get("raw")
        web_profile.update({"blockxsize": 256, "blockysize": 256})
        config = dict(GDAL_TIFF_OVR_BLOCKSIZE="256")

        with rasterio.open(raster_path_web) as src_dst:
            _, max_zoom = get_zooms(src_dst)

        cog_translate(
            raster_path_web,
            "cogeo.tif",
            web_profile,
            quiet=True,
            web_optimized=True,
            config=config,
            aligned_levels=2,
        )
        with COGReader(raster_path_web) as src_dst:
            bounds = src_dst.bounds
            with COGReader("cogeo.tif") as cog:
                _, max_zoom = get_zooms(cog.dataset)
                ulTile = tms.xy_bounds(tms.tile(bounds[0], bounds[3], max_zoom - 2))
                assert round(cog.dataset.bounds[0], 5) == round(ulTile.left, 5)
                assert round(cog.dataset.bounds[3], 5) == round(ulTile.top, 5)

                lrTile = tms.xy_bounds(tms.tile(bounds[2], bounds[1], max_zoom - 2))
                assert round(cog.dataset.bounds[2], 5) == round(lrTile.right, 5)
                assert round(cog.dataset.bounds[1], 5) == round(lrTile.bottom, 5)

        cog_translate(
            raster_path_web,
            "cogeo.tif",
            web_profile,
            quiet=True,
            web_optimized=True,
            config=config,
            aligned_levels=3,
        )
        with COGReader(raster_path_web) as src_dst:
            bounds = src_dst.bounds
            with COGReader("cogeo.tif") as cog_dst:
                _, max_zoom = get_zooms(cog_dst.dataset)
                ulTile = tms.xy_bounds(tms.tile(bounds[0], bounds[3], max_zoom - 3))
                assert round(cog_dst.dataset.bounds[0], 5) == round(ulTile.left, 5)
                assert round(cog_dst.dataset.bounds[3], 5) == round(ulTile.top, 5)

                lrTile = tms.xy_bounds(tms.tile(bounds[2], bounds[1], max_zoom - 3))
                assert round(cog_dst.dataset.bounds[2], 5) == round(lrTile.right, 5)
                assert round(cog_dst.dataset.bounds[1], 5) == round(lrTile.bottom, 5)
Beispiel #2
0
def test_COGReader_Options():
    """Set options in reader."""
    with COGReader(COGEO, nodata=1) as cog:
        meta = cog.metadata()
        assert meta["statistics"][1]["pc"] == [2720, 6896]

    with COGReader(COGEO, nodata=1) as cog:
        _, mask = cog.tile(43, 25, 7)
        assert not mask.all()

    with COGReader(COGEO, nodata=1, resampling_method="bilinear") as cog:
        data, _ = cog.tile(43, 25, 7)
        assert data[0, 100, 100] == 3774  # 3776 with nearest

    with COGReader(COG_SCALE, unscale=True) as cog:
        p = cog.point(310000, 4100000, coord_crs=cog.dataset.crs)
        assert round(p[0], 3) == 1000.892

        # passing unscale in method should overwrite the defaults
        p = cog.point(310000,
                      4100000,
                      coord_crs=cog.dataset.crs,
                      unscale=False)
        assert p[0] == 8917

    cutline = "POLYGON ((13 1685, 1010 6, 2650 967, 1630 2655, 13 1685))"
    with COGReader(COGEO, vrt_options={"cutline": cutline}) as cog:
        _, mask = cog.preview()
        assert not mask.all()
Beispiel #3
0
async def test_async():
    dataset = COGReader(COGEO)

    async with AsyncCOGReader(dataset) as cog:
        info = await cog.info()
        assert info == dataset.info()

        meta = cog.spatial_info
        assert meta.minzoom == 4
        assert meta.maxzoom == 8

        assert await cog.stats(5, 95)
        assert await cog.metadata(2, 98)

        data, mask = await cog.tile(43, 24, 7)
        assert data.shape == (1, 256, 256)
        assert mask.all()

        lon = -56.624124590533825
        lat = 73.52687881825946
        pts = await cog.point(lon, lat)
        assert len(pts) == 1

        bbox = (
            -56.624124590533825,
            73.52687881825946,
            -56.530950796449005,
            73.50183615350426,
        )
        data, mask = await cog.part(bbox)
        assert data.shape == (1, 11, 41)

        data, mask = await cog.preview(max_size=128)
        assert data.shape == (1, 128, 128)

        feature = {
            "type": "Feature",
            "properties": {},
            "geometry": {
                "type":
                "Polygon",
                "coordinates": [[
                    [-56.4697265625, 74.17307693616263],
                    [-57.667236328125, 73.53462847039683],
                    [-57.59033203125, 73.13451013251789],
                    [-56.195068359375, 72.94865294642922],
                    [-54.964599609375, 72.96797135377102],
                    [-53.887939453125, 73.84623016391944],
                    [-53.97583007812499, 74.0165183926664],
                    [-54.73388671875, 74.23289305339864],
                    [-55.54687499999999, 74.2269213699517],
                    [-56.129150390625, 74.21497138945001],
                    [-56.2060546875, 74.21198251594369],
                    [-56.4697265625, 74.17307693616263],
                ]],
            },
        }

        img = await cog.feature(feature)
        assert img.data.shape == (1, 349, 1024)
Beispiel #4
0
def test_shapes_encoder():
    """Test MVT encoder."""
    asset = os.path.join(os.path.dirname(__file__), "fixtures",
                         "cog_classes.tif")
    x, y, z = 814, 1750, 12
    with COGReader(asset) as cog:
        tile, mask = cog.tile(x,
                              y,
                              z,
                              resampling_method="nearest",
                              tilesize=256)

    # test with default
    vt = shapes_encoder(tile[0], mask)
    mvt = vector_tile_base.VectorTile(vt)
    assert len(mvt.layers) == 1
    layer = mvt.layers[0]
    assert layer.name == "my_layer"
    assert layer.extent == 4096
    assert layer.version == 2

    with COGReader(asset) as cog:
        tile, mask = cog.tile(x,
                              y,
                              z,
                              resampling_method="nearest",
                              tilesize=4096)
        colormap = cog.colormap
        classes = {0: "none", 1: "grass", 2: "urban", 18: "something"}

    # test with default
    vt = shapes_encoder(tile[0], mask)
    mvt = vector_tile_base.VectorTile(vt)
    assert len(mvt.layers) == 1
    layer = mvt.layers[0]
    assert layer.name == "my_layer"
    assert layer.extent == 4096
    assert layer.version == 2

    feat = layer.features[0]
    assert feat.type == "polygon"
    props = feat.attributes
    assert len(props) == 1
    assert props["value"]

    vt = shapes_encoder(tile[0], mask, colormap=colormap, class_names=classes)
    mvt = vector_tile_base.VectorTile(vt)
    assert len(mvt.layers) == 1
    layer = mvt.layers[0]
    assert layer.name == "my_layer"
    assert layer.extent == 4096
    assert layer.version == 2

    feat = layer.features[0]
    assert feat.type == "polygon"

    props = feat.attributes
    assert len(props) == 2
    assert props["color"] == "#4c70a3"
    assert props["name"] == "something"
Beispiel #5
0
def test_metadata_valid():
    """Get bounds and get stats for all bands."""
    with COGReader(COGEO) as cog:
        meta = cog.metadata()
        assert len(meta["band_descriptions"]) == 1
        assert (1, "band1") == meta["band_descriptions"][0]
        assert len(meta["statistics"].items()) == 1
        assert meta["statistics"][1]["pc"] == [1, 6896]

        meta = cog.stats()
        assert len(meta.items()) == 1
        assert meta[1]["pc"] == [1, 6896]

        meta = cog.metadata(pmin=5,
                            pmax=90,
                            hist_options=dict(bins=20),
                            max_size=128)
        assert len(meta["statistics"].items()) == 1
        assert len(meta["statistics"][1]["histogram"][0]) == 20
        assert meta["statistics"][1]["pc"] == [1, 3776]

    with COGReader(COG_CMAP) as cog:
        assert cog.colormap
        meta = cog.metadata()
        assert meta["statistics"][1]["histogram"][1] == list(range(20))
Beispiel #6
0
def test_mosaic_tiler_with_imageDataClass():
    """Test mosaic tiler."""
    img, _ = mosaic.mosaic_reader(assets, _read_tile, xo, yo, zo)
    assert not img.assets
    assert not img.data
    assert not img.mask

    img, _ = mosaic.mosaic_reader(assets, _read_tile, x, y, z)
    assert img.data.shape == (3, 256, 256)
    assert img.mask.shape == (256, 256)
    assert img.mask.all()
    assert img.data[0][-1][-1] == 8682
    assert len(img.assets) == 1

    assert img.crs == WEB_MERCATOR_TMS.crs
    assert img.bounds == WEB_MERCATOR_TMS.xy_bounds(x, y, z)

    img, assets_used = mosaic.mosaic_reader(
        assets, _read_tile, x, y, z, pixel_selection=defaults.LowestMethod())
    assert assets_used == img.assets == assets
    assert img.crs == WEB_MERCATOR_TMS.crs
    assert img.bounds == WEB_MERCATOR_TMS.xy_bounds(x, y, z)

    img, assets_used = mosaic.mosaic_reader(
        assets,
        _read_preview,
        width=256,
        height=256,
        pixel_selection=defaults.LowestMethod(),
    )
    assert img.data.shape == (3, 256, 256)
    assert img.mask.shape == (256, 256)
    assert assets_used == img.assets == assets
    assert not img.crs
    assert not img.bounds

    bbox = [
        -75.98703377413767, 44.93504283293786, -71.337604723999,
        47.09685599202324
    ]
    with COGReader(assets[0]) as cog:
        crs1 = cog.dataset.crs

    with COGReader(assets[0]) as cog:
        crs2 = cog.dataset.crs

    img, assets_used = mosaic.mosaic_reader(assets,
                                            _read_part,
                                            bbox=bbox,
                                            dst_crs=crs1,
                                            bounds_crs=WGS84_CRS,
                                            max_size=1024)
    assert img.data.shape == (3, 690, 1024)
    assert img.mask.shape == (690, 1024)
    assert img.mask.any()
    assert assets_used == img.assets == assets
    assert img.crs == crs1 == crs2
    assert not img.bounds == bbox
    bbox_in_crs = transform_bounds(WGS84_CRS, crs1, *bbox, densify_pts=21)
    assert img.bounds == bbox_in_crs
Beispiel #7
0
async def test_async():
    dataset = COGReader(COGEO)

    async with AsyncCOGReader(dataset) as cog:
        info = await cog.info()
        assert info == dataset.info()

        meta = cog.spatial_info
        assert meta.minzoom == 4
        assert meta.maxzoom == 8

        assert await cog.stats(5, 95)
        assert await cog.metadata(2, 98)

        data, mask = await cog.tile(43, 24, 7)
        assert data.shape == (1, 256, 256)
        assert mask.all()

        lon = -56.624124590533825
        lat = 73.52687881825946
        pts = await cog.point(lon, lat)
        assert len(pts) == 1

        bbox = (
            -56.624124590533825,
            73.52687881825946,
            -56.530950796449005,
            73.50183615350426,
        )
        data, mask = await cog.part(bbox)
        assert data.shape == (1, 11, 41)

        data, mask = await cog.preview(max_size=128)
        assert data.shape == (1, 128, 128)
def test_metadata_valid():
    """Get bounds and get stats for all bands."""
    with COGReader(COGEO) as cog:
        meta = cog.metadata()
        assert len(meta["band_descriptions"]) == 1
        assert len(meta.band_descriptions) == 1
        assert ("1", "") == meta.band_descriptions[0]

        stats = meta["statistics"]
        assert len(stats.items()) == 1
        assert meta["statistics"]["1"]["percentiles"]
        b1_stats = meta.statistics["1"]
        assert b1_stats.percentiles == [1, 6896]

        stats = cog.stats()
        assert len(stats.items()) == 1
        b1_stats = stats["1"]
        assert b1_stats.percentiles == [1, 6896]

        meta = cog.metadata(pmin=5,
                            pmax=90,
                            hist_options=dict(bins=20),
                            max_size=128)
        stats = meta.statistics
        assert len(stats.items()) == 1
        b1_stats = stats["1"]
        assert len(b1_stats.histogram[0]) == 20
        assert b1_stats.percentiles == [1, 3776]

    with COGReader(COG_CMAP) as cog:
        assert cog.colormap
        b1_stats = cog.metadata().statistics["1"]
        assert b1_stats.histogram[1] == list(range(20))
Beispiel #9
0
def test_tile_valid_default():
    """Should return a 3 bands array and a full valid mask."""
    with COGReader(COG_NODATA) as cog:
        # Full tile
        img = cog.tile(43, 24, 7)
        assert img.data.shape == (1, 256, 256)
        assert img.mask.all()
        assert img.band_names == ["1"]

        # Validate that Tile and Part gives the same result
        tile_bounds = WEB_MERCATOR_TMS.xy_bounds(43, 24, 7)
        data_part, _ = cog.part(
            tile_bounds,
            bounds_crs=WEB_MERCATOR_TMS.crs,
            width=256,
            height=256,
            max_size=None,
        )
        assert numpy.array_equal(img.data, data_part)

        # Partial tile
        data, mask = cog.tile(42, 24, 7)
        assert data.shape == (1, 256, 256)
        assert not mask.all()

        # Expression
        img = cog.tile(43, 24, 7, expression="b1*2,b1-100")
        assert img.data.shape == (2, 256, 256)
        assert img.band_names == ["b1*2", "b1-100"]

        with pytest.warns(ExpressionMixingWarning):
            img = cog.tile(43, 24, 7, indexes=(1, 2, 3), expression="b1*2")
            assert img.data.shape == (1, 256, 256)
        assert img.band_names == ["b1*2"]

        data, mask = cog.tile(43, 24, 7, indexes=1)
        assert data.shape == (1, 256, 256)

        img = cog.tile(
            43,
            24,
            7,
            indexes=(
                1,
                1,
            ),
        )
        assert img.data.shape == (2, 256, 256)
        assert img.band_names == ["1", "1"]

    # We are using a file that is aligned with the grid so no resampling should be involved
    with COGReader(COG_WEB) as cog:
        img = cog.tile(147, 182, 9)
        img_buffer = cog.tile(147, 182, 9, tile_buffer=10)
        assert img_buffer.width == 276
        assert img_buffer.height == 276
        assert not img.bounds == img_buffer.bounds
        assert numpy.array_equal(img.data, img_buffer.data[:, 10:266, 10:266])
Beispiel #10
0
def test_COGReader_Options():
    """Set options in reader."""
    with COGReader(COGEO, nodata=1) as cog:
        assert cog.nodata == 1

    with COGReader(COGEO) as cog:
        assert not cog.nodata
        assert cog.info().nodata_type == "None"

    with COGReader(COGEO, nodata=1) as cog:
        _, mask = cog.tile(43, 25, 7)
        assert not mask.all()

    # read cog using default Nearest
    with COGReader(COGEO, nodata=1) as cog:
        data_default, _ = cog.tile(43, 25, 7)

    # read cog using bilinear
    with COGReader(COGEO, nodata=1, resampling_method="bilinear") as cog:
        data, _ = cog.tile(43, 25, 7)
        assert not numpy.array_equal(data_default, data)

    with COGReader(COG_SCALE, unscale=True) as cog:
        p = cog.point(310000, 4100000, coord_crs=cog.dataset.crs)
        assert round(p[0], 3) == 1000.892

        # passing unscale in method should overwrite the defaults
        p = cog.point(310000,
                      4100000,
                      coord_crs=cog.dataset.crs,
                      unscale=False)
        assert p[0] == 8917

    cutline = "POLYGON ((13 1685, 1010 6, 2650 967, 1630 2655, 13 1685))"
    with COGReader(COGEO, vrt_options={"cutline": cutline}) as cog:
        _, mask = cog.preview()
        assert not mask.all()

    def callback(data, mask):
        mask.fill(255)
        data = data * 2
        return data, mask

    with COGReader(COGEO, nodata=1, post_process=callback) as cog:
        data_init, _ = cog.tile(43, 25, 7, post_process=None)
        data, mask = cog.tile(43, 25, 7)
        assert mask.all()
        assert data[0, 0, 0] == data_init[0, 0, 0] * 2

    lon = -56.624124590533825
    lat = 73.52687881825946
    with COGReader(COG_NODATA, post_process=callback) as cog:
        pts = cog.point(lon, lat)

    with COGReader(COG_NODATA) as cog:
        pts_init = cog.point(lon, lat)
    assert pts[0] == pts_init[0] * 2
Beispiel #11
0
def test_tile_with_int_buffer():
    with COGReader(COGEO) as cog:
        data, mask = cog.tile(43, 24, 7, tile_buffer=1)
    assert data.shape == (1, 258, 258)
    assert mask.all()

    with COGReader(COGEO) as cog:
        data, mask = cog.tile(43, 24, 7, tile_buffer=0)
    assert data.shape == (1, 256, 256)
    assert mask.all()
Beispiel #12
0
def test_tiling_ignores_padding_if_web_friendly_internal_tiles_exist():
    """Ignore Padding when COG is aligned."""
    with COGReader(COG_WEB) as cog:
        img = cog.tile(147, 182, 9, padding=0, resampling_method="bilinear")
        img2 = cog.tile(147, 182, 9, padding=100, resampling_method="bilinear")
        assert numpy.array_equal(img.data, img2.data)

    with COGReader(COGEO) as cog:
        img = cog.tile(43, 24, 7, padding=0, resampling_method="bilinear")
        img2 = cog.tile(43, 24, 7, padding=100, resampling_method="bilinear")
        assert not numpy.array_equal(img.data, img2.data)
Beispiel #13
0
def test_cutline():
    """Test rio_tiler.utils.create_cutline."""
    feat = {
        "type": "Feature",
        "properties": {},
        "geometry": {
            "type":
            "Polygon",
            "coordinates": [[
                [-52.6025390625, 73.86761239709705],
                [-52.6025390625, 73.59679245247814],
                [-51.591796875, 73.60299628304274],
                [-51.591796875, 73.90420357134279],
                [-52.4267578125, 74.0437225981325],
                [-52.6025390625, 73.86761239709705],
            ]],
        },
    }

    feature_bounds = featureBounds(feat)

    with COGReader(COGEO) as cog:
        cutline = utils.create_cutline(cog.dataset,
                                       feat,
                                       geometry_crs="epsg:4326")
        data, mask = cog.part(feature_bounds, vrt_options={"cutline": cutline})
        assert not mask.all()

        cutline = utils.create_cutline(cog.dataset,
                                       feat["geometry"],
                                       geometry_crs="epsg:4326")
        data, mask = cog.part(feature_bounds, vrt_options={"cutline": cutline})
        assert not mask.all()

    feat_line = {
        "type": "Feature",
        "properties": {},
        "geometry": {
            "type":
            "LineString",
            "coordinates": [
                [-55.37109374999999, 74.17607298699065],
                [-53.85498046874999, 75.06734898853098],
                [-54.16259765625, 75.11822201684025],
                [-54.228515625, 75.23066741281573],
            ],
        },
    }

    with COGReader(COGEO) as cog:
        with pytest.raises(RioTilerError):
            utils.create_cutline(cog.dataset,
                                 feat_line,
                                 geometry_crs="epsg:4326")
Beispiel #14
0
def test_fullEarth():
    """Should read tile for COG spanning the whole earth."""
    with COGReader(COG_EARTH) as cog:
        img = cog.tile(1, 42, 7, tilesize=64)
        assert img.data.shape == (1, 64, 64)

        img = cog.tile(127, 42, 7, tilesize=64)
        assert img.data.shape == (1, 64, 64)

    with COGReader(COG_EARTH,
                   tms=morecantile.tms.get("EuropeanETRS89_LAEAQuad")) as cog:
        img = cog.tile(0, 0, 1, tilesize=64)
        assert img.data.shape == (1, 64, 64)
def test_spatial_info_valid():
    """Should work as expected (get spatial info)"""
    with COGReader(COG_NODATA) as cog:
        assert not cog.dataset.closed
        meta = cog.spatial_info
        assert meta["minzoom"] == 4
        assert meta.minzoom == 4
        assert meta.maxzoom == 8
        assert cog.nodata == cog.dataset.nodata
    assert cog.dataset.closed

    cog = COGReader(COG_NODATA)
    assert not cog.dataset.closed
    cog.close()
    assert cog.dataset.closed

    with COGReader(COG_NODATA, minzoom=3) as cog:
        meta = cog.spatial_info
        assert meta.minzoom == 3
        assert meta.maxzoom == 8

    with COGReader(COG_NODATA, maxzoom=12) as cog:
        meta = cog.spatial_info
        assert meta.minzoom == 4
        assert meta.maxzoom == 12

    with COGReader(COG_NODATA, minzoom=3, maxzoom=12) as cog:
        meta = cog.spatial_info
        assert meta.minzoom == 3
        assert meta.maxzoom == 12
Beispiel #16
0
def test_spatial_info_valid():
    """Should work as expected (get spatial info)"""
    with COGReader(COG_NODATA) as cog:
        assert not cog.dataset.closed
        assert cog.bounds
        assert cog.crs
        assert cog.minzoom == 5
        assert cog.maxzoom == 9
        assert cog.nodata == cog.dataset.nodata
    assert cog.dataset.closed

    cog = COGReader(COG_NODATA)
    assert not cog.dataset.closed
    cog.close()
    assert cog.dataset.closed

    with COGReader(COG_NODATA, minzoom=3) as cog:
        assert cog.minzoom == 3
        assert cog.maxzoom == 9

    with COGReader(COG_NODATA, maxzoom=12) as cog:
        assert cog.minzoom == 5
        assert cog.maxzoom == 12

    with COGReader(COG_NODATA, minzoom=3, maxzoom=12) as cog:
        assert cog.minzoom == 3
        assert cog.maxzoom == 12
Beispiel #17
0
def test_nonearthbody():
    """COGReader should work with non-earth dataset."""
    with pytest.warns(UserWarning):
        with COGReader(COG_EUROPA) as cog:
            assert cog.minzoom == 0
            assert cog.maxzoom == 24

    with pytest.warns(None) as warnings:
        with COGReader(COG_EUROPA) as cog:
            assert cog.info()
            assert len(warnings) == 2

            img = cog.read()
            assert numpy.array_equal(img.data, cog.dataset.read(indexes=(1, )))
            assert img.width == cog.dataset.width
            assert img.height == cog.dataset.height
            assert img.count == cog.dataset.count

            img = cog.preview()
            assert img.bounds == cog.bounds

            part = cog.part(cog.bounds, bounds_crs=cog.crs)
            assert part.bounds == cog.bounds

            lon = (cog.bounds[0] + cog.bounds[2]) / 2
            lat = (cog.bounds[1] + cog.bounds[3]) / 2
            assert cog.point(lon, lat, coord_crs=cog.crs)[0] is not None

    europa_crs = CRS.from_authority("ESRI", 104915)
    tms = TileMatrixSet.custom(
        crs=europa_crs,
        extent=europa_crs.area_of_use.bounds,
        matrix_scale=[2, 1],
    )
    with pytest.warns(None) as warnings:
        with COGReader(COG_EUROPA, tms=tms) as cog:
            assert cog.minzoom == 4
            assert cog.maxzoom == 6

            # Get Tile covering the UL corner
            bounds = transform_bounds(cog.crs, tms.rasterio_crs, *cog.bounds)
            t = tms._tile(bounds[0], bounds[1], cog.minzoom)
            img = cog.tile(t.x, t.y, t.z)

            assert img.height == 256
            assert img.width == 256
            assert img.crs == tms.rasterio_crs

            assert len(warnings) == 0
def test_preview_valid():
    """Read preview."""
    with COGReader(COGEO) as cog:
        data, mask = cog.preview(max_size=128)
        assert data.shape == (1, 128, 128)

        data, mask = cog.preview()
        assert data.shape == (1, 1024, 1021)

        data, mask = cog.preview(max_size=128, expression="b1*2,b1-100")
        assert data.shape == (2, 128, 128)

        with pytest.warns(ExpressionMixingWarning):
            data, _ = cog.preview(max_size=128,
                                  indexes=(1, 2, 3),
                                  expression="b1*2")
            assert data.shape == (1, 128, 128)

        data, mask = cog.preview(max_size=128, indexes=1)
        assert data.shape == (1, 128, 128)

        data, mask = cog.preview(max_size=128, indexes=(
            1,
            1,
        ))
        assert data.shape == (2, 128, 128)
def test_area_valid():
    """Read part of an image."""
    bbox = (
        -56.624124590533825,
        73.52687881825946,
        -56.530950796449005,
        73.50183615350426,
    )
    with COGReader(COG_NODATA) as cog:
        data, mask = cog.part(bbox)
        assert data.shape == (1, 11, 41)

        data, mask = cog.part(bbox, dst_crs=cog.dataset.crs)
        assert data.shape == (1, 29, 30)

        data, mask = cog.part(bbox, max_size=30)
        assert data.shape == (1, 9, 30)

        data, mask = cog.part(bbox, expression="b1*2,b1-100")
        assert data.shape == (2, 11, 41)

        with pytest.warns(ExpressionMixingWarning):
            data, _ = cog.part(bbox, indexes=(1, 2, 3), expression="b1*2")
            assert data.shape == (1, 11, 41)

        data, mask = cog.part(bbox, indexes=1)
        assert data.shape == (1, 11, 41)

        data, mask = cog.part(bbox, indexes=(
            1,
            1,
        ))
        assert data.shape == (2, 11, 41)
Beispiel #20
0
def mvt(
        z: int,
        x: int,
        y: int,
        url: str = Query(..., description="COG url"),
        tilesize: int = Query(256, description="TileSize"),
):
    """Handle /mvt requests."""
    timings = []
    headers: Dict[str, str] = {}

    with Timer() as t:
        with COGReader(url) as src_dst:
            tile_data = src_dst.tile(x, y, z, tilesize=tilesize, indexes=1)
            cmap = src_dst.colormap

    timings.append(("cogread", round(t.elapsed * 1000, 2)))

    with Timer() as t:
        content = shapes_encoder(
            tile_data.data[0].astype("uint8"),
            tile_data.mask,
            layer_name="cogeo",
            colormap=cmap,
        )
    timings.append(("mvtencoding", round(t.elapsed * 1000, 2)))

    headers["Server-Timing"] = ", ".join(
        [f"{name};dur={time}" for (name, time) in timings])
    return Response(content,
                    media_type="application/x-protobuf",
                    headers=headers)
Beispiel #21
0
def _bounds(url: str) -> Tuple[str, str, str]:
    """Handle /bounds requests."""
    with rasterio.Env(aws_session):
        with COGReader(url) as cog:
            info = {"address": url, "bounds": cog.bounds}

    return ("OK", "application/json", json.dumps(info))
Beispiel #22
0
    def get(self, request, pk=None, project_pk=None, tile_type=""):
        """
        Get tile.json for this tasks's asset type
        """
        task = self.get_and_check_task(request, pk)

        raster_path = get_raster_path(task, tile_type)
        if not os.path.isfile(raster_path):
            raise exceptions.NotFound()

        with COGReader(raster_path) as src:
            minzoom, maxzoom = get_zoom_safe(src)

        return Response({
            'tilejson':
            '2.1.0',
            'name':
            task.name,
            'version':
            '1.0.0',
            'scheme':
            'xyz',
            'tiles':
            [get_tile_url(task, tile_type, self.request.query_params)],
            'minzoom':
            minzoom - ZOOM_EXTRA_LEVELS,
            'maxzoom':
            maxzoom + ZOOM_EXTRA_LEVELS,
            'bounds':
            get_extent(task, tile_type).extent
        })
Beispiel #23
0
def _tilejson(
    url: str, tile_scale: int = 1, tile_format: str = None, **kwargs: Any
) -> Tuple[str, str, str]:
    """Handle /tilejson.json requests."""
    if tile_scale is not None and isinstance(tile_scale, str):
        tile_scale = int(tile_scale)

    kwargs.update(dict(url=url))
    qs = urllib.parse.urlencode(list(kwargs.items()))
    if tile_format:
        tile_url = f"{app.host}/{{z}}/{{x}}/{{y}}@{tile_scale}x.{tile_format}?{qs}"
    else:
        tile_url = f"{app.host}/{{z}}/{{x}}/{{y}}@{tile_scale}x?{qs}"

    with rasterio.Env(aws_session):
        with COGReader(url) as cog:
            info = cog.spatial_info()

    meta = dict(
        bounds=info["bounds"],
        center=info["center"],
        minzoom=info["minzoom"],
        maxzoom=info["maxzoom"],
        name=os.path.basename(url),
        tilejson="2.1.0",
        tiles=[tile_url],
    )
    return ("OK", "application/json", json.dumps(meta))
Beispiel #24
0
def test_tile_valid_default():
    """Should return a 3 bands array and a full valid mask."""
    with COGReader(COG_NODATA) as cog:
        # Full tile
        data, mask = cog.tile(43, 24, 7)
        assert data.shape == (1, 256, 256)
        assert mask.all()

        tile_bounds = mercantile.xy_bounds(43, 24, 7)
        data_part, _ = cog.part(tile_bounds,
                                bounds_crs="epsg:3857",
                                width=256,
                                height=256,
                                max_size=None)
        assert numpy.array_equal(data, data_part)

        # Partial tile
        data, mask = cog.tile(42, 24, 7)
        assert data.shape == (1, 256, 256)
        assert not mask.all()

        # Expression
        data, mask = cog.tile(43, 24, 7, expression="b1*2,b1-100")
        assert data.shape == (2, 256, 256)

        data, mask = cog.tile(43, 24, 7, indexes=1)
        assert data.shape == (1, 256, 256)

        data, mask = cog.tile(43, 24, 7, indexes=(
            1,
            1,
        ))
        assert data.shape == (2, 256, 256)
Beispiel #25
0
def test_mask_bilinear(cloudoptimized_geotiff):
    """Test mask read with bilinear resampling"""
    src_path = cloudoptimized_geotiff(cog_path,
                                      **equator,
                                      dtype="uint8",
                                      nodata_type="mask")
    with COGReader(src_path) as cog:
        data, mask = cog.tile(
            535,
            498,
            10,
            tilesize=256,
            resampling_method="bilinear",
            force_binary_mask=True,
        )
        masknodata = (data[0] != 0).astype(numpy.uint8) * 255
        numpy.testing.assert_array_equal(mask, masknodata)

        data, mask = cog.tile(
            535,
            498,
            10,
            tilesize=256,
            resampling_method="bilinear",
            force_binary_mask=False,
        )
        masknodata = (data[0] != 0).astype(numpy.uint8) * 255
        assert not numpy.array_equal(mask, masknodata)
Beispiel #26
0
def test_point_valid():
    """Read point."""
    lon = -56.624124590533825
    lat = 73.52687881825946
    with COGReader(COG_NODATA) as cog:
        pts = cog.point(lon, lat)
        assert len(pts) == 1

        pts = cog.point(lon, lat, expression="b1*2,b1-100")
        assert len(pts) == 2

        with pytest.warns(ExpressionMixingWarning):
            pts = cog.point(lon, lat, indexes=(1, 2, 3), expression="b1*2")
            assert len(pts) == 1

        pts = cog.point(lon, lat, indexes=1)
        assert len(pts) == 1

        pts = cog.point(
            lon,
            lat,
            indexes=(
                1,
                1,
            ),
        )
        assert len(pts) == 2
Beispiel #27
0
def test_preview_valid():
    """Read preview."""
    with COGReader(COGEO) as cog:
        img = cog.preview(max_size=128)
        assert img.data.shape == (1, 128, 128)
        assert img.band_names == ["1"]

        data, mask = cog.preview()
        assert data.shape == (1, 1024, 1021)

        img = cog.preview(max_size=128, expression="b1*2,b1-100")
        assert img.data.shape == (2, 128, 128)
        assert img.band_names == ["b1*2", "b1-100"]

        with pytest.warns(ExpressionMixingWarning):
            img = cog.preview(max_size=128,
                              indexes=(1, 2, 3),
                              expression="b1*2")
            assert img.data.shape == (1, 128, 128)
            assert img.band_names == ["b1*2"]

        data, mask = cog.preview(max_size=128, indexes=1)
        assert data.shape == (1, 128, 128)

        img = cog.preview(
            max_size=128,
            indexes=(
                1,
                1,
            ),
        )
        assert img.data.shape == (2, 128, 128)
        assert img.band_names == ["1", "1"]
Beispiel #28
0
def get_elevation_tiles(elevation, url, x, y, z, tilesize, nodata, resampling, padding):
    tile = np.full((tilesize * 3, tilesize * 3), nodata, dtype=elevation.dtype)
    with COGReader(url) as src:
        try:
            left, _ = src.tile(x - 1, y, z, indexes=1, tilesize=tilesize, nodata=nodata,
                               resampling_method=resampling, padding=padding)
            tile[tilesize:tilesize * 2, 0:tilesize] = left
        except TileOutsideBounds:
            pass

        try:
            right, _ = src.tile(x + 1, y, z, indexes=1, tilesize=tilesize, nodata=nodata,
                                resampling_method=resampling, padding=padding)
            tile[tilesize:tilesize * 2, tilesize * 2:tilesize * 3] = right
        except TileOutsideBounds:
            pass
        try:
            bottom, _ = src.tile(x, y + 1, z, indexes=1, tilesize=tilesize, nodata=nodata,
                                 resampling_method=resampling, padding=padding)
            tile[tilesize * 2:tilesize * 3, tilesize:tilesize * 2] = bottom
        except TileOutsideBounds:
            pass
        try:
            top, _ = src.tile(x, y - 1, z, indexes=1, tilesize=tilesize, nodata=nodata,
                              resampling_method=resampling, padding=padding)
            tile[0:tilesize, tilesize:tilesize * 2] = top
        except TileOutsideBounds:
            pass
    tile[tilesize:tilesize * 2, tilesize:tilesize * 2] = elevation
    return tile
Beispiel #29
0
def get_dataset_info(src_path: str) -> Dict:
    """Get rasterio dataset meta."""
    with COGReader(src_path) as cog:
        bounds = cog.bounds
        return {
            "geometry": {
                "type":
                "Polygon",
                "coordinates": [[
                    [bounds[0], bounds[3]],
                    [bounds[0], bounds[1]],
                    [bounds[2], bounds[1]],
                    [bounds[2], bounds[3]],
                    [bounds[0], bounds[3]],
                ]],
            },
            "properties": {
                "path": src_path,
                "bounds": cog.bounds,
                "minzoom": cog.minzoom,
                "maxzoom": cog.maxzoom,
                "datatype": cog.dataset.meta["dtype"],
            },
            "type": "Feature",
        }
Beispiel #30
0
def profile(input, tile, tilesize, zoom, add_kernels, add_stdout, config):
    """Profile COGReader Mercator Tile read."""
    if not tile:
        with COGReader(input) as cog:
            if zoom is None:
                zoom = randint(cog.minzoom, cog.maxzoom)
            extrema = tile_extrema(cog.bounds, zoom)

        tile_x = sample(range(extrema["x"]["min"], extrema["x"]["max"]), 1)[0]
        tile_y = sample(range(extrema["y"]["min"], extrema["y"]["max"]), 1)[0]
        tile_z = zoom
        log.debug(f"reading tile: {tile_z}-{tile_x}-{tile_y}")
    else:
        tile_z, tile_x, tile_y = list(map(int, tile.split("-")))

    @profiler(
        kernels=add_kernels,
        quiet=True,
        add_to_return=True,
        raw=add_stdout,
        config=config,
    )
    def _read_tile(src_path: str, x: int, y: int, z: int, tilesize: int = 256):
        with COGReader(src_path) as cog:
            return cog.tile(x, y, z, tilesize=tilesize)

    (_, _), stats = _read_tile(input, tile_x, tile_y, tile_z, tilesize)

    click.echo(json.dumps(stats))