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, )
def get_web_optimized_params( src_dst, tilesize=256, warp_resampling: str = "nearest", zoom_level_strategy: str = "auto", aligned_levels: Optional[int] = None, tms: morecantile.TileMatrixSet = morecantile.tms.get("WebMercatorQuad"), ) -> Dict: """Return VRT parameters for a WebOptimized COG.""" bounds = list( transform_bounds(src_dst.crs, CRS.from_epsg(4326), *src_dst.bounds, densify_pts=21)) min_zoom, max_zoom = get_zooms( src_dst, tilesize=tilesize, tms=tms, zoom_level_strategy=zoom_level_strategy, ) if aligned_levels is not None: min_zoom = max_zoom - aligned_levels ul_tile = tms.tile(bounds[0], bounds[3], min_zoom) left, _, _, top = tms.xy_bounds(ul_tile.x, ul_tile.y, ul_tile.z) vrt_res = tms._resolution(tms.matrix(max_zoom)) vrt_transform = Affine(vrt_res, 0, left, 0, -vrt_res, top) lr_tile = tms.tile(bounds[2], bounds[1], min_zoom) extrema = { "x": { "min": ul_tile.x, "max": lr_tile.x + 1 }, "y": { "min": ul_tile.y, "max": lr_tile.y + 1 }, } vrt_width = ((extrema["x"]["max"] - extrema["x"]["min"]) * tilesize * 2**(max_zoom - min_zoom)) vrt_height = ((extrema["y"]["max"] - extrema["y"]["min"]) * tilesize * 2**(max_zoom - min_zoom)) return dict( crs=tms.crs, transform=vrt_transform, width=vrt_width, height=vrt_height, resampling=ResamplingEnums[warp_resampling], )