diff --git a/.gitignore b/.gitignore index b3ca3e5..f49b6f6 100644 --- a/.gitignore +++ b/.gitignore @@ -101,3 +101,7 @@ ENV/ .mypy_cache/ .pytest_cache + +# Jetbrains IDE (PyCharm or other with Python plugin installed) +.idea +*.iml diff --git a/CHANGES.md b/CHANGES.md index 641222f..16d48a1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,31 @@ * remove `is_tiled` rasterio method and add better test for blockshapes for the validation script (author @sgillies, https://github.com/cogeotiff/rio-cogeo/pull/278) +* Deprecate parameter **web_optimized** of `cogeo.cog_translate` Python function (author @alexismanin, https://github.com/cogeotiff/rio-cogeo/pull/279) + + ```python + # before + output_profile = cog_profiles.get(profile) + + tms = morecantile.tms.get("WGS1984Quad") + cog_translate( + "in.tif", + "out.tif", + output_profile, + web_optimzed=True, + tms=tms + ) + + # now + tms = morecantile.tms.get("WGS1984Quad") + cog_translate( + "in.tif", + "out.tif", + output_profile, + tms=tms + ) + ``` + ## 5.1.1 (2024-01-08) * use morecantile `TileMatrixSet.cellSize` property instead of deprecated/private `TileMatrixSet._resolution` method diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0ebc538..b7c5fb0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,10 +31,10 @@ $ cd rio-cogeo $ pip install -e .["docs"] ``` -Hot-reloading docs: +Hot-reloading docs (from repository root): ```bash -$ mkdocs serve +$ mkdocs serve -f docs/mkdocs.yml ``` To manually deploy docs (note you should never need to do this because Github diff --git a/rio_cogeo/cogeo.py b/rio_cogeo/cogeo.py index fdef4ee..4a7cd8f 100644 --- a/rio_cogeo/cogeo.py +++ b/rio_cogeo/cogeo.py @@ -126,18 +126,23 @@ def cog_translate( # noqa: C901 RasterIO Resampling algorithm for overviews web_optimized: bool, optional (default: False) Create web-optimized cogeo. + Deprecated: Behavior changed since 5.1.2. See deprecation warning at the bottom of function doc. tms: morecantile.TileMatrixSet, optional (default: "WebMercatorQuad") TileMatrixSet to use for reprojection, resolution and alignment. zoom_level_strategy: str, optional (default: auto) Strategy to determine zoom level (same as in GDAL 3.2). + Used only when either "web_optimized" argument is True, or `tms` is not None. LOWER will select the zoom level immediately below the theoretical computed non-integral zoom level, leading to subsampling. On the contrary, UPPER will select the immediately above zoom level, leading to oversampling. Defaults to AUTO which selects the closest zoom level. ref: https://gdal.org/drivers/raster/cog.html#raster-cog zoom_level: int, optional. - Zoom level number (starting at 0 for coarsest zoom level). If this option is specified, `--zoom-level-strategy` is ignored. + Zoom level number (starting at 0 for coarsest zoom level). + If this option is specified, `--zoom-level-strategy` is ignored. + In any case, it is used only when either "web_optimized" argument is True, or `tms` is not None. aligned_levels: int, optional. Number of overview levels for which GeoTIFF tile and tiles defined in the tiling scheme match. + Used only when either "web_optimized" argument is True, or `tms` is not None. Default is to use the maximum overview levels. Note: GDAL use number of resolution levels instead of overview levels. resampling : str, optional (default: "nearest") Warp Resampling algorithm. @@ -167,8 +172,20 @@ def cog_translate( # noqa: C901 use_cog_driver: bool, optional (default: False) Use GDAL COG driver if set to True. COG driver is available starting with GDAL 3.1. + .. deprecated:: 5.1.2 + `web_optimized` is deprecated in favor of `tms`. + Previously, `tms` usage was conditioned by `web_optimized` state. + The behaviour has changed to allow setting a tile matrix set without the need of `web_optimized` flag. + `web_optimized` now only serve to activate a default `WebMercatorQuad` tile matrix set. + Set to be removed 6.0. + """ - tms = tms or morecantile.tms.get("WebMercatorQuad") + if web_optimized: + warnings.warn( + "'web_optomized' option is deprecated and will be removed in 6.0. Please use the `tms` option", + DeprecationWarning, + ) + tms = tms or morecantile.tms.get("WebMercatorQuad") dst_kwargs = dst_kwargs.copy() @@ -227,7 +244,7 @@ def cog_translate( # noqa: C901 if alpha: vrt_params.update({"add_alpha": False}) - if web_optimized: + if tms: wo_params = utils.get_web_optimized_params( src_dst, zoom_level_strategy=zoom_level_strategy, @@ -345,7 +362,7 @@ def cog_translate( # noqa: C901 ].name.upper() } ) - if web_optimized: + if tms: default_zoom = tms.zoom_for_res( max(tmp_dst.res), max_z=30, diff --git a/rio_cogeo/scripts/cli.py b/rio_cogeo/scripts/cli.py index 2f91487..df38454 100644 --- a/rio_cogeo/scripts/cli.py +++ b/rio_cogeo/scripts/cli.py @@ -3,8 +3,10 @@ import json import os import typing +from typing import Optional import click +import morecantile import numpy from morecantile import TileMatrixSet from rasterio.rio import options @@ -269,12 +271,13 @@ def create( } ) + tilematrixset: Optional[TileMatrixSet] = None if tms: with open(tms, "r") as f: tilematrixset = TileMatrixSet(**json.load(f)) - else: - tilematrixset = None + elif web_optimized: + tilematrixset = morecantile.tms.get("WebMercatorQuad") cog_translate( input, @@ -286,7 +289,6 @@ def create( add_mask=add_mask, overview_level=overview_level, overview_resampling=overview_resampling, - web_optimized=web_optimized, zoom_level_strategy=zoom_level_strategy, zoom_level=zoom_level, aligned_levels=aligned_levels, diff --git a/tests/test_cogeo.py b/tests/test_cogeo.py index ba60931..2e34e17 100644 --- a/tests/test_cogeo.py +++ b/tests/test_cogeo.py @@ -3,6 +3,7 @@ import os import pathlib +import morecantile import numpy import pytest import rasterio @@ -624,6 +625,7 @@ def test_gdal_cog_compare(runner): def test_gdal_cog_compareWeb(runner): """Test GDAL COG.""" with runner.isolated_filesystem(): + web_tms = morecantile.tms.get("WebMercatorQuad") profile = cog_profiles.get("jpeg") profile["blockxsize"] = 256 profile["blockysize"] = 256 @@ -635,7 +637,7 @@ def test_gdal_cog_compareWeb(runner): profile.copy(), quiet=True, use_cog_driver=True, - web_optimized=True, + tms=web_tms, aligned_levels=1, ) @@ -671,12 +673,13 @@ def test_gdal_cog_web_mask(runner): """Raise a warning for specific mask/compression/web combination.""" with runner.isolated_filesystem(): with pytest.warns(UserWarning): + web_tms = morecantile.tms.get("WebMercatorQuad") cog_translate( raster_path_rgb, "cogeo.tif", cog_profiles.get("deflate"), use_cog_driver=True, - web_optimized=True, + tms=web_tms, add_mask=True, quiet=True, ) diff --git a/tests/test_web.py b/tests/test_web.py index 8c42f3d..08fb63e 100644 --- a/tests/test_web.py +++ b/tests/test_web.py @@ -40,6 +40,7 @@ def test_cog_translate_webZooms(): """ runner = CliRunner() with runner.isolated_filesystem(): + web_tms = morecantile.tms.get("WebMercatorQuad") web_profile = cog_profiles.get("raw") web_profile.update({"blockxsize": 256, "blockysize": 256}) config = {"GDAL_TIFF_OVR_BLOCKSIZE": "256"} @@ -49,7 +50,7 @@ def test_cog_translate_webZooms(): "cogeo.tif", web_profile, quiet=True, - web_optimized=True, + tms=web_tms, config=config, ) with rasterio.open("cogeo.tif") as out_dst: @@ -61,7 +62,7 @@ def test_cog_translate_webZooms(): "cogeo.tif", web_profile, quiet=True, - web_optimized=True, + tms=web_tms, zoom_level_strategy="lower", config=config, ) @@ -91,7 +92,7 @@ def test_cog_translate_web(): "cogeo.tif", web_profile, quiet=True, - web_optimized=True, + tms=tms, config=config, aligned_levels=0, ) @@ -127,7 +128,7 @@ def test_cog_translate_web(): "cogeo.tif", web_profile, quiet=True, - web_optimized=True, + tms=tms, config=config, aligned_levels=4, ) @@ -142,7 +143,7 @@ def test_cog_translate_web(): "cogeo.tif", web_profile, quiet=True, - web_optimized=True, + tms=tms, zoom_level=19, config=config, aligned_levels=4, @@ -180,7 +181,7 @@ def test_cog_translate_Internal(): "cogeo.tif", web_profile, quiet=True, - web_optimized=True, + tms=tms, config=config, aligned_levels=0, ) @@ -261,7 +262,7 @@ def test_cog_translate_web_align(): "cogeo.tif", web_profile, quiet=True, - web_optimized=True, + tms=tms, config=config, aligned_levels=2, ) @@ -282,7 +283,7 @@ def test_cog_translate_web_align(): "cogeo.tif", web_profile, quiet=True, - web_optimized=True, + tms=tms, config=config, aligned_levels=3, ) @@ -309,7 +310,7 @@ def test_cog_translate_web_geos(): """ runner = CliRunner() with runner.isolated_filesystem(): - + web_tms = morecantile.tms.get("WebMercatorQuad") profile = cog_profiles.get("jpeg") profile.update({"blockxsize": 256, "blockysize": 256}) config = {"GDAL_TIFF_OVR_BLOCKSIZE": "256", "GDAL_TIFF_INTERNAL_MASK": True} @@ -319,7 +320,7 @@ def test_cog_translate_web_geos(): "cogeo.tif", profile, quiet=True, - web_optimized=True, + tms=web_tms, config=config, ) cog_translate( @@ -327,7 +328,7 @@ def test_cog_translate_web_geos(): "cogeo_gdal.tif", profile, quiet=True, - web_optimized=True, + tms=web_tms, use_cog_driver=True, config=config, ) @@ -345,6 +346,8 @@ def test_web_align_cogeo_gdal(): runner = CliRunner() with runner.isolated_filesystem(): + web_tms = morecantile.tms.get("WebMercatorQuad") + web_profile = cog_profiles.get("raw") web_profile.update({"blockxsize": 256, "blockysize": 256}) config = {"GDAL_TIFF_OVR_BLOCKSIZE": "256"} @@ -354,7 +357,7 @@ def test_web_align_cogeo_gdal(): "cogeo.tif", web_profile, quiet=True, - web_optimized=True, + tms=web_tms, config=config, ) cog_translate( @@ -362,7 +365,7 @@ def test_web_align_cogeo_gdal(): "cogeo_gdal.tif", web_profile, quiet=True, - web_optimized=True, + tms=web_tms, config=config, use_cog_driver=True, ) @@ -379,7 +382,7 @@ def test_web_align_cogeo_gdal(): "cogeo.tif", web_profile, quiet=True, - web_optimized=True, + tms=web_tms, config=config, aligned_levels=4, ) @@ -388,7 +391,7 @@ def test_web_align_cogeo_gdal(): "cogeo_gdal.tif", web_profile, quiet=True, - web_optimized=True, + tms=web_tms, config=config, aligned_levels=4, use_cog_driver=True, @@ -407,6 +410,7 @@ def test_gdal_zoom_options(): """Test Web-Optimized GDAL with Zoom Options.""" runner = CliRunner() with runner.isolated_filesystem(): + web_tms = morecantile.tms.get("WebMercatorQuad") web_profile = cog_profiles.get("raw") web_profile.update({"blockxsize": 256, "blockysize": 256}) config = {"GDAL_TIFF_OVR_BLOCKSIZE": "256"} @@ -416,7 +420,7 @@ def test_gdal_zoom_options(): "cogeo_gdal.tif", web_profile, quiet=True, - web_optimized=True, + tms=web_tms, config=config, use_cog_driver=True, ) @@ -432,7 +436,7 @@ def test_gdal_zoom_level_options(): """Test Web-Optimized GDAL with Zoom Options.""" runner = CliRunner() with runner.isolated_filesystem(): - + web_tms = morecantile.tms.get("WebMercatorQuad") web_profile = cog_profiles.get("raw") web_profile.update({"blockxsize": 256, "blockysize": 256}) config = {"GDAL_TIFF_OVR_BLOCKSIZE": "256"} @@ -442,7 +446,7 @@ def test_gdal_zoom_level_options(): "cogeo_gdal.tif", web_profile, quiet=True, - web_optimized=True, + tms=web_tms, config=config, use_cog_driver=True, zoom_level=19, @@ -452,3 +456,21 @@ def test_gdal_zoom_level_options(): assert tags["TILING_SCHEME_NAME"] == "WebMercatorQuad" assert tags["TILING_SCHEME_ZOOM_LEVEL"] == "19" assert "TILING_SCHEME_ALIGNED_LEVELS" not in tags + + +def test_web_optimized_arg_warning(): + """Verify a deprecation warning is emitted for `web_optimized` parameter""" + runner = CliRunner() + with runner.isolated_filesystem(): + web_profile = cog_profiles.get("raw") + web_profile.update({"blockxsize": 256, "blockysize": 256}) + with pytest.warns( + DeprecationWarning, match=r"^'web_optomized' option is deprecated.*" + ): + cog_translate( + raster_path_north, + "cogeo.tif", + web_profile, + quiet=True, + web_optimized=True, + )