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)
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()
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)
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"
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))
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
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))
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])
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
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()
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)
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")
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
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
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)
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)
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))
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 })
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))
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)
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)
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
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"]
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
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", }
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))