Skip to content

Commit

Permalink
Merge pull request #283 from cogeotiff/features/refactor-blocksize-de…
Browse files Browse the repository at this point in the history
…finition-in-cli

change how blocksize is defined in create CLI
  • Loading branch information
vincentsarago authored Feb 16, 2024
2 parents 77b9036 + a168bc0 commit 65b1ab9
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 36 deletions.
8 changes: 8 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@

* fix COG validation for SPARSE dataset (author @mpadillaruiz, https://github.com/cogeotiff/rio-cogeo/issues/281)

#### CLI

* remove default (*128*) for `--overview-blocksize` option in the CLI. Now defaults to GDAL behaviour.

* change how `blocksize` for overviews is defined when using `tms` or `web-optimized` options

* `blocksize` is now defined from the tilematrixset's `tileWidth` and `tileHeight` when `--blocksize` is not provided

## 5.1.1 (2024-01-08)

* use morecantile `TileMatrixSet.cellSize` property instead of deprecated/private `TileMatrixSet._resolution` method
Expand Down
51 changes: 34 additions & 17 deletions rio_cogeo/scripts/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,8 @@ def cogeo():
)
@click.option(
"--overview-blocksize",
default=lambda: os.environ.get("GDAL_TIFF_OVR_BLOCKSIZE", 128),
help="Overview's internal tile size (default defined by "
"GDAL_TIFF_OVR_BLOCKSIZE env or 128)",
show_default=True,
help="Overview's internal tile size (default can be defined by "
"GDAL_TIFF_OVR_BLOCKSIZE env). The default is 128, or starting with GDAL 3.1 to use the same block size as the full-resolution dataset if possible).",
)
@click.option(
"--web-optimized", "-w", is_flag=True, help="Create COGEO optimized for Web."
Expand Down Expand Up @@ -251,26 +249,18 @@ def create(
quiet,
):
"""Create Cloud Optimized Geotiff."""
output_profile = cog_profiles.get(cogeo_profile)
output_profile.update({"BIGTIFF": os.environ.get("BIGTIFF", "IF_SAFER")})
if creation_options:
output_profile.update(creation_options)

if blocksize:
output_profile["blockxsize"] = blocksize
output_profile["blockysize"] = blocksize

if web_optimized:
overview_blocksize = blocksize or 512

config.update(
{
"GDAL_NUM_THREADS": threads,
"GDAL_TIFF_INTERNAL_MASK": os.environ.get("GDAL_TIFF_INTERNAL_MASK", True),
"GDAL_TIFF_OVR_BLOCKSIZE": str(overview_blocksize),
}
)

output_profile = cog_profiles.get(cogeo_profile)
output_profile.update({"BIGTIFF": os.environ.get("BIGTIFF", "IF_SAFER")})
if creation_options:
output_profile.update(creation_options)

tilematrixset: Optional[TileMatrixSet] = None
if tms:
with open(tms, "r") as f:
Expand All @@ -279,6 +269,33 @@ def create(
elif web_optimized:
tilematrixset = morecantile.tms.get("WebMercatorQuad")

if tilematrixset:
if not blocksize:
click.secho(
f"Defining `blocksize` from {tilematrixset.id} TileMatrixSet `tileWidth` and `tileHeight`",
fg="yellow",
)

blocksize = min(
tilematrixset.matrix(tilematrixset.minzoom).tileHeight,
tilematrixset.matrix(tilematrixset.minzoom).tileWidth,
)

if not overview_blocksize:
click.secho(
f"Defining overview's `blocksize` to match the high resolution `blocksize`: {blocksize}",
fg="yellow",
)
overview_blocksize = blocksize

if blocksize:
output_profile["blockxsize"] = blocksize
output_profile["blockysize"] = blocksize

overview_blocksize = overview_blocksize or os.environ.get("GDAL_TIFF_OVR_BLOCKSIZE")
if overview_blocksize:
config.update({"GDAL_TIFF_OVR_BLOCKSIZE": str(overview_blocksize)})

cog_translate(
input,
output,
Expand Down
133 changes: 114 additions & 19 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import os

import morecantile
import pytest
import rasterio

Expand Down Expand Up @@ -513,30 +514,23 @@ def test_cogeo_validUpercaseProfile(monkeypatch, runner):
assert src.compression.value == "DEFLATE"


def test_cogeo_info(runner):
@pytest.mark.parametrize(
"src_path",
[
raster_path_rgb,
raster_invalid_cog,
raster_band_tags,
raster_path_gcps,
],
)
def test_cogeo_info(src_path, runner):
"""Should work as expected."""
with runner.isolated_filesystem():
result = runner.invoke(cogeo, ["info", raster_path_rgb])
assert not result.exception
assert result.exit_code == 0

result = runner.invoke(cogeo, ["info", raster_path_rgb, "--json"])
assert not result.exception
assert result.exit_code == 0

result = runner.invoke(cogeo, ["info", raster_invalid_cog])
assert not result.exception
assert result.exit_code == 0

result = runner.invoke(cogeo, ["info", raster_path_gcps])
result = runner.invoke(cogeo, ["info", src_path])
assert not result.exception
assert result.exit_code == 0

result = runner.invoke(cogeo, ["info", raster_band_tags, "--json"])
assert not result.exception
assert result.exit_code == 0

result = runner.invoke(cogeo, ["info", raster_band_tags])
result = runner.invoke(cogeo, ["info", src_path, "--json"])
assert not result.exception
assert result.exit_code == 0

Expand Down Expand Up @@ -577,3 +571,104 @@ def test_cogeo_zoom_level(runner):
with rasterio.open("output.tif") as src:
_, max_zoom = get_zooms(src)
assert max_zoom == 19


def test_create_web_tms(runner):
"""Should work as expected."""
with runner.isolated_filesystem():
result = runner.invoke(
cogeo,
[
"create",
raster_path_rgb,
"output.tif",
"--web-optimized",
"--aligned-levels",
2,
],
)
assert not result.exception
assert result.exit_code == 0
with rasterio.open("output.tif") as src:
meta = src.profile

with rasterio.open("output.tif", OVERVIEW_LEVEL=0) as src:
meta_ovr = src.profile
assert meta_ovr["blockysize"] == meta["blockysize"]

with open("webmercator.json", "w") as f:
tms = morecantile.tms.get("WebMercatorQuad")
f.write(tms.model_dump_json())

result = runner.invoke(
cogeo,
[
"create",
raster_path_rgb,
"output.tif",
"--aligned-levels",
"2",
"--tms",
"webmercator.json",
],
)
assert not result.exception
assert result.exit_code == 0
with rasterio.open("output.tif") as src:
meta_tms = src.profile

assert meta_tms["crs"] == meta["crs"]
assert meta_tms["transform"] == meta["transform"]
assert meta_tms["blockysize"] == meta["blockysize"] == 256
assert meta_tms["width"] == meta["width"]
assert meta_tms["height"] == meta["height"]

with rasterio.open("output.tif", OVERVIEW_LEVEL=0) as src:
meta_ovr = src.profile
assert meta_ovr["blockysize"] == meta_tms["blockysize"] == 256

result = runner.invoke(
cogeo,
[
"create",
raster_path_rgb,
"output.tif",
"--aligned-levels",
"2",
"--blocksize",
512,
"--tms",
"webmercator.json",
],
)
assert not result.exception
assert result.exit_code == 0
with rasterio.open("output.tif") as src:
meta_tms = src.profile

with rasterio.open("output.tif", OVERVIEW_LEVEL=0) as src:
meta_ovr = src.profile
assert meta_ovr["blockysize"] == meta_tms["blockysize"] == 512

result = runner.invoke(
cogeo,
[
"create",
raster_path_rgb,
"output.tif",
"--aligned-levels",
"2",
"--blocksize",
512,
"--overview-blocksize",
128,
"--tms",
"webmercator.json",
],
)
assert not result.exception
assert result.exit_code == 0

with rasterio.open("output.tif", OVERVIEW_LEVEL=0) as src:
meta_ovr = src.profile
assert meta_ovr["blockysize"] == 128

0 comments on commit 65b1ab9

Please sign in to comment.