def test_bad_tiff_tile(tiff): reader = FileReader(tiff) cog = COGTiff(reader.read) with pytest.raises(TIFFError) as err: cog.get_tile(10, 10, 0) with pytest.raises(TIFFError) as err: cog.get_tile(10, 10, 10)
def test_tiff_tile(tiff): reader = FileReader(tiff) cog = COGTiff(reader.read) mime_type, tile = cog.get_tile(0, 0, 0) assert 1 == len(cog._image_ifds[0]['offsets']) assert 1 == len(cog._image_ifds[0]['byte_counts']) assert 'jpeg_tables' in cog._image_ifds[0] assert 73 == len(cog._image_ifds[0]['jpeg_tables']) assert mime_type == 'image/jpeg'
def test_bigtiff_tile(bigtiff): reader = FileReader(bigtiff) cog = COGTiff(reader.read) mime_type, tile = cog.get_tile(0, 0, 0) assert 1 == len(cog._image_ifds[0]['offsets']) assert 1 == len(cog._image_ifds[0]['byte_counts']) assert 'jpeg_tables' in cog._image_ifds[0] assert cog._image_ifds[0]['jpeg_tables'] is None assert mime_type == 'application/octet-stream'
def test_tiff_tile_env(tiff, monkeypatch): monkeypatch.setenv("COG_INGESTED_BYTES_AT_OPEN", "1024") reader = FileReader(tiff) cog = COGTiff(reader.read) mime_type, tile = cog.get_tile(0, 0, 0) assert 1 == len(cog._image_ifds[0]['offsets']) assert 1 == len(cog._image_ifds[0]['byte_counts']) assert 'jpeg_tables' in cog._image_ifds[0] assert 73 == len(cog._image_ifds[0]['jpeg_tables']) assert mime_type == 'image/jpeg'
def dump(server, path, resource, output, xyz=None): """Command line entry for COG tile dumping.""" reader = Reader(server, path, resource) cog = COGTiff(reader.read) mime_type, tile = cog.get_tile(*xyz) if output is None: ext = mimetypes.guess_extension(mime_type) # work around a bug with mimetypes if ext == '.jpe': ext = '.jpg' output = f'http_{xyz[0]}_{xyz[1]}_{xyz[2]}{ext}' with open(output, 'wb') as dst: dst.write(tile)
def http(server, path, resource, output, xyz, verbose): """Read web hosted dataset.""" if verbose: logging.basicConfig(level=logging.INFO) reader = HTTPReader(server, path, resource) cog = COGTiff(reader.read) mime_type, tile = cog.get_tile(*xyz) if output is None: ext = mimetypes.guess_extension(mime_type) # work around a bug with mimetypes if ext == '.jpe': ext = '.jpg' output = f'http_{xyz[0]}_{xyz[1]}_{xyz[2]}{ext}' with open(output, 'wb') as dst: dst.write(tile)
def s3(bucket, key, output, xyz, verbose): """Read AWS S3 hosted dataset.""" if verbose: logging.basicConfig(level=logging.INFO) reader = S3Reader(bucket, key) cog = COGTiff(reader.read) mime_type, tile = cog.get_tile(*xyz) if output is None: ext = mimetypes.guess_extension(mime_type) # work around a bug with mimetypes if ext == '.jpe': ext = '.jpg' output = f's3_{xyz[0]}_{xyz[1]}_{xyz[2]}{ext}' with open(output, 'wb') as dst: dst.write(tile)
def file(file, output, xyz, verbose): """Read local dataset.""" if verbose: logging.basicConfig(level=logging.INFO) with open(file, 'rb') as src: reader = FileReader(src) cog = COGTiff(reader.read) mime_type, tile = cog.get_tile(*xyz) if output is None: ext = mimetypes.guess_extension(mime_type) # work around a bug with mimetypes if ext == '.jpe': ext = '.jpg' output = f'file_{xyz[0]}_{xyz[1]}_{xyz[2]}{ext}' with open(output, 'wb') as dst: dst.write(tile)
def test_cog_translate_Internal(): """ Test Web-Optimized COG. - Test COG size is a multiple of 256 (mercator tile size) - Test COG bounds are aligned with mercator grid at max zoom - Test high resolution internal tiles are equal to mercator tile using cogdumper and rio-tiler - Test overview internal tiles are equal to mercator tile using cogdumper and rio-tiler """ from cogdumper.cog_tiles import COGTiff from cogdumper.filedumper import Reader as FileReader 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="128") cog_translate( raster_path_web, "cogeo.tif", web_profile, quiet=True, web_optimized=True, config=config, ) with rasterio.open(raster_path_web) as src_dst: with rasterio.open("cogeo.tif") as out_dst: blocks = list(set(out_dst.block_shapes)) assert len(blocks) == 1 ts = blocks[0][0] assert not out_dst.width % ts assert not out_dst.height % ts max_zoom = get_max_zoom(out_dst) bounds = list( transform_bounds( *[src_dst.crs, "epsg:4326"] + list(src_dst.bounds), densify_pts=21 ) ) leftTile = mercantile.tile(bounds[0], bounds[3], max_zoom) tbounds = mercantile.xy_bounds(leftTile) west, north = tbounds.left, tbounds.top assert out_dst.transform.xoff == west assert out_dst.transform.yoff == north rightTile = mercantile.tile(bounds[2], bounds[1], max_zoom) tbounds = mercantile.xy_bounds(rightTile) east, south = tbounds.right, tbounds.bottom lrx = round( out_dst.transform.xoff + out_dst.transform.a * out_dst.width, 6 ) lry = round( out_dst.transform.yoff + out_dst.transform.e * out_dst.height, 6 ) assert lrx == round(east, 6) assert lry == round(south, 6) with open("cogeo.tif", "rb") as out_body: reader = FileReader(out_body) cog = COGTiff(reader.read) # High resolution # Top Left tile mime_type, tile = cog.get_tile(0, 0, 0) tile_length = 256 * 256 * 3 t = struct.unpack_from("{}b".format(tile_length), tile) arr = numpy.array(t).reshape(256, 256, 3).astype(numpy.uint8) arr = numpy.transpose(arr, [2, 0, 1]) tbounds = mercantile.xy_bounds(leftTile) data, mask = tile_read( "cogeo.tif", tbounds, 256, resampling_method="nearest" ) numpy.testing.assert_array_equal(data, arr) # Bottom right tile mime_type, tile = cog.get_tile(4, 3, 0) tile_length = 256 * 256 * 3 t = struct.unpack_from("{}b".format(tile_length), tile) arr = numpy.array(t).reshape(256, 256, 3).astype(numpy.uint8) arr = numpy.transpose(arr, [2, 0, 1]) tbounds = mercantile.xy_bounds(rightTile) data, mask = tile_read( "cogeo.tif", tbounds, 256, resampling_method="nearest" ) numpy.testing.assert_array_equal(data, arr) # Low resolution (overview 1) # Top Left tile # NOTE: overview internal tile size is 128px # We need to stack two internal tiles to compare with # the 256px mercator tile fetched by rio-tiler # ref: https://github.com/cogeotiff/rio-cogeo/issues/60 mime_type, tile = cog.get_tile(1, 0, 1) tile_length = 128 * 128 * 3 t = struct.unpack_from("{}b".format(tile_length), tile) arr1 = numpy.array(t).reshape(128, 128, 3).astype(numpy.uint8) arr1 = numpy.transpose(arr1, [2, 0, 1]) mime_type, tile = cog.get_tile(2, 0, 1) tile_length = 128 * 128 * 3 t = struct.unpack_from("{}b".format(tile_length), tile) arr2 = numpy.array(t).reshape(128, 128, 3).astype(numpy.uint8) arr2 = numpy.transpose(arr2, [2, 0, 1]) arr = numpy.dstack((arr1, arr2)) lowTile = mercantile.Tile(118594, 60034, 17) tbounds = mercantile.xy_bounds(lowTile) data, mask = tile_read( "cogeo.tif", tbounds, 256, resampling_method="nearest" ) data = data[:, 128:, :] numpy.testing.assert_array_equal(data, arr)
def test_cog_translate_Internal(): """ Test Web-Optimized COG. - Test COG size is a multiple of 256 (mercator tile size) - Test COG bounds are aligned with mercator grid at max zoom - Test high resolution internal tiles are equal to mercator tile using cogdumper and rio-tiler - Test overview internal tiles are equal to mercator tile using cogdumper and rio-tiler """ 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") cog_translate( raster_path_web, "cogeo.tif", web_profile, quiet=True, web_optimized=True, config=config, aligned_levels=0, ) with rasterio.open(raster_path_web) as src_dst: with rasterio.open("cogeo.tif") as out_dst: blocks = list(set(out_dst.block_shapes)) assert len(blocks) == 1 ts = blocks[0][0] assert not out_dst.width % ts assert not out_dst.height % ts _, max_zoom = get_zooms(out_dst) bounds = list( transform_bounds(src_dst.crs, "epsg:4326", *src_dst.bounds, densify_pts=21)) minimumTile = tms.tile(bounds[0], bounds[3], max_zoom) maximumTile = tms.tile(bounds[2], bounds[1], max_zoom) with open("cogeo.tif", "rb") as out_body: reader = FileReader(out_body) cog = COGTiff(reader.read) # High resolution # Top Left tile _, tile = cog.get_tile(0, 0, 0) tile_length = 256 * 256 * 3 t = struct.unpack_from("{}b".format(tile_length), tile) arr = numpy.array(t).reshape(256, 256, 3).astype(numpy.uint8) arr = numpy.transpose(arr, [2, 0, 1]) with rasterio.open("cogeo.tif") as src_dst: w = from_bounds(*tms.xy_bounds(minimumTile), src_dst.transform) data = src_dst.read(window=w, out_shape=(src_dst.count, 256, 256)) numpy.testing.assert_array_equal(data, arr) # Bottom right tile _, tile = cog.get_tile(4, 3, 0) tile_length = 256 * 256 * 3 t = struct.unpack_from("{}b".format(tile_length), tile) arr = numpy.array(t).reshape(256, 256, 3).astype(numpy.uint8) arr = numpy.transpose(arr, [2, 0, 1]) with rasterio.open("cogeo.tif") as src_dst: w = from_bounds(*tms.xy_bounds(maximumTile), src_dst.transform) data = src_dst.read(window=w, out_shape=(src_dst.count, 256, 256)) numpy.testing.assert_array_equal(data, arr)