Skip to content

Commit c3a9155

Browse files
Merge pull request #25 from developmentseed/feature/new-rio-tiler
Feature/new rio tiler
2 parents 2dae78b + 35a051c commit c3a9155

File tree

5 files changed

+177
-62
lines changed

5 files changed

+177
-62
lines changed

.bumpversion.cfg

Lines changed: 0 additions & 9 deletions
This file was deleted.

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.13.0 (2024-10-23)
2+
3+
* update rio-tiler dependency to `>=7.0,<8.0`
4+
* add `reader-params` options in CLI
5+
16
## 0.12.1 (2024-04-18)
27

38
* fix GET range parsing

pyproject.toml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ dependencies = [
2525
"jinja2>=3.0,<4.0.0",
2626
"loguru",
2727
"rasterio>=1.3.8",
28-
"rio-tiler>=6.0,<7.0",
28+
"rio-tiler>=7.0,<8.0",
2929
"uvicorn[standard]",
3030
]
3131

@@ -38,6 +38,7 @@ test = [
3838
]
3939
dev = [
4040
"pre-commit",
41+
"bump-my-version",
4142
]
4243

4344
[project.urls]
@@ -112,3 +113,18 @@ ignore = [
112113

113114
[tool.ruff.lint.mccabe]
114115
max-complexity = 14
116+
117+
118+
[tool.bumpversion]
119+
current_version = "0.12.1"
120+
search = "{current_version}"
121+
replace = "{new_version}"
122+
regex = false
123+
tag = true
124+
commit = true
125+
tag_name = "{new_version}"
126+
127+
[[tool.bumpversion.files]]
128+
filename = "tilebench/__init__.py"
129+
search = '__version__ = "{current_version}"'
130+
replace = '__version__ = "{new_version}"'

tilebench/scripts/cli.py

Lines changed: 89 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,42 @@
1111
from loguru import logger as log
1212
from rasterio._path import _parse_path as parse_path
1313
from rasterio.rio import options
14-
from rio_tiler.io import BaseReader, COGReader, MultiBandReader, MultiBaseReader
14+
from rio_tiler.io import BaseReader, MultiBandReader, MultiBaseReader, Reader
1515

1616
from tilebench import profile as profiler
1717
from tilebench.viz import TileDebug
1818

1919
default_tms = morecantile.tms.get("WebMercatorQuad")
2020

2121

22+
def options_to_dict(ctx, param, value):
23+
"""
24+
click callback to validate `--opt KEY1=VAL1 --opt KEY2=VAL2` and collect
25+
in a dictionary like the one below, which is what the CLI function receives.
26+
If no value or `None` is received then an empty dictionary is returned.
27+
28+
{
29+
'KEY1': 'VAL1',
30+
'KEY2': 'VAL2'
31+
}
32+
33+
Note: `==VAL` breaks this as `str.split('=', 1)` is used.
34+
"""
35+
36+
if not value:
37+
return {}
38+
else:
39+
out = {}
40+
for pair in value:
41+
if "=" not in pair:
42+
raise click.BadParameter(f"Invalid syntax for KEY=VAL arg: {pair}")
43+
else:
44+
k, v = pair.split("=", 1)
45+
out[k] = v
46+
47+
return out
48+
49+
2250
# The CLI command group.
2351
@click.group(help="Command line interface for the tilebench Python package.")
2452
def cli():
@@ -51,7 +79,7 @@ def cli():
5179
@click.option(
5280
"--reader",
5381
type=str,
54-
help="rio-tiler Reader (BaseReader). Default is `rio_tiler.io.COGReader`",
82+
help="rio-tiler Reader (BaseReader). Default is `rio_tiler.io.Reader`",
5583
)
5684
@click.option(
5785
"--tms",
@@ -66,6 +94,15 @@ def cli():
6694
callback=options._cb_key_val,
6795
help="GDAL configuration options.",
6896
)
97+
@click.option(
98+
"--reader-params",
99+
"-p",
100+
"reader_params",
101+
metavar="NAME=VALUE",
102+
multiple=True,
103+
callback=options_to_dict,
104+
help="Reader Options.",
105+
)
69106
def profile(
70107
input,
71108
tile,
@@ -77,8 +114,9 @@ def profile(
77114
reader,
78115
tms,
79116
config,
117+
reader_params,
80118
):
81-
"""Profile COGReader Mercator Tile read."""
119+
"""Profile Reader Tile read."""
82120
tilematrixset = default_tms
83121
if tms:
84122
with open(tms, "r") as f:
@@ -90,15 +128,17 @@ def profile(
90128
if not issubclass(reader, (BaseReader, MultiBandReader, MultiBaseReader)):
91129
warnings.warn(f"Invalid reader type: {type(reader)}", stacklevel=1)
92130

93-
Reader = reader or COGReader
131+
DstReader = reader or Reader
94132

95133
if not tile:
96134
with rasterio.Env(CPL_VSIL_CURL_NON_CACHED=parse_path(input).as_vsi()):
97-
with Reader(input, tms=tilematrixset) as cog:
135+
with Reader(input, tms=tilematrixset, **reader_params) as cog:
98136
if zoom is None:
99137
zoom = randint(cog.minzoom, cog.maxzoom)
100138

101-
w, s, e, n = cog.geographic_bounds
139+
w, s, e, n = cog.get_geographic_bounds(
140+
tilematrixset.rasterio_geographic_crs
141+
)
102142
# Truncate BBox to the TMS bounds
103143
w = max(tilematrixset.bbox.left, w)
104144
s = max(tilematrixset.bbox.bottom, s)
@@ -128,7 +168,7 @@ def profile(
128168
config=config,
129169
)
130170
def _read_tile(src_path: str, x: int, y: int, z: int, tilesize: int = 256):
131-
with Reader(src_path, tms=tilematrixset) as cog:
171+
with DstReader(src_path, tms=tilematrixset, **reader_params) as cog:
132172
return cog.tile(x, y, z, tilesize=tilesize)
133173

134174
(_, _), stats = _read_tile(input, tile_x, tile_y, tile_z, tilesize)
@@ -141,14 +181,23 @@ def _read_tile(src_path: str, x: int, y: int, z: int, tilesize: int = 256):
141181
@click.option(
142182
"--reader",
143183
type=str,
144-
help="rio-tiler Reader (BaseReader). Default is `rio_tiler.io.COGReader`",
184+
help="rio-tiler Reader (BaseReader). Default is `rio_tiler.io.Reader`",
145185
)
146186
@click.option(
147187
"--tms",
148188
help="Path to TileMatrixSet JSON file.",
149189
type=click.Path(),
150190
)
151-
def get_zooms(input, reader, tms):
191+
@click.option(
192+
"--reader-params",
193+
"-p",
194+
"reader_params",
195+
metavar="NAME=VALUE",
196+
multiple=True,
197+
callback=options_to_dict,
198+
help="Reader Options.",
199+
)
200+
def get_zooms(input, reader, tms, reader_params):
152201
"""Get Mercator Zoom levels."""
153202
tilematrixset = default_tms
154203
if tms:
@@ -161,9 +210,9 @@ def get_zooms(input, reader, tms):
161210
if not issubclass(reader, (BaseReader, MultiBandReader, MultiBaseReader)):
162211
warnings.warn(f"Invalid reader type: {type(reader)}", stacklevel=1)
163212

164-
Reader = reader or COGReader
213+
DstReader = reader or Reader
165214

166-
with Reader(input, tms=tilematrixset) as cog:
215+
with DstReader(input, tms=tilematrixset, **reader_params) as cog:
167216
click.echo(json.dumps({"minzoom": cog.minzoom, "maxzoom": cog.maxzoom}))
168217

169218

@@ -173,14 +222,23 @@ def get_zooms(input, reader, tms):
173222
@click.option(
174223
"--reader",
175224
type=str,
176-
help="rio-tiler Reader (BaseReader). Default is `rio_tiler.io.COGReader`",
225+
help="rio-tiler Reader (BaseReader). Default is `rio_tiler.io.Reader`",
177226
)
178227
@click.option(
179228
"--tms",
180229
help="Path to TileMatrixSet JSON file.",
181230
type=click.Path(),
182231
)
183-
def random(input, zoom, reader, tms):
232+
@click.option(
233+
"--reader-params",
234+
"-p",
235+
"reader_params",
236+
metavar="NAME=VALUE",
237+
multiple=True,
238+
callback=options_to_dict,
239+
help="Reader Options.",
240+
)
241+
def random(input, zoom, reader, tms, reader_params):
184242
"""Get random tile."""
185243
tilematrixset = default_tms
186244
if tms:
@@ -193,12 +251,12 @@ def random(input, zoom, reader, tms):
193251
if not issubclass(reader, (BaseReader, MultiBandReader, MultiBaseReader)):
194252
warnings.warn(f"Invalid reader type: {type(reader)}", stacklevel=1)
195253

196-
Reader = reader or COGReader
254+
DstReader = reader or Reader
197255

198-
with Reader(input, tms=tilematrixset) as cog:
256+
with DstReader(input, tms=tilematrixset, **reader_params) as cog:
199257
if zoom is None:
200258
zoom = randint(cog.minzoom, cog.maxzoom)
201-
w, s, e, n = cog.geographic_bounds
259+
w, s, e, n = cog.get_geographic_bounds(tilematrixset.rasterio_geographic_crs)
202260

203261
# Truncate BBox to the TMS bounds
204262
w = max(tilematrixset.bbox.left, w)
@@ -237,7 +295,7 @@ def random(input, zoom, reader, tms):
237295
@click.option(
238296
"--reader",
239297
type=str,
240-
help="rio-tiler Reader (BaseReader). Default is `rio_tiler.io.COGReader`",
298+
help="rio-tiler Reader (BaseReader). Default is `rio_tiler.io.Reader`",
241299
)
242300
@click.option(
243301
"--config",
@@ -247,21 +305,31 @@ def random(input, zoom, reader, tms):
247305
callback=options._cb_key_val,
248306
help="GDAL configuration options.",
249307
)
250-
def viz(src_path, port, host, server_only, reader, config):
308+
@click.option(
309+
"--reader-params",
310+
"-p",
311+
"reader_params",
312+
metavar="NAME=VALUE",
313+
multiple=True,
314+
callback=options_to_dict,
315+
help="Reader Options.",
316+
)
317+
def viz(src_path, port, host, server_only, reader, config, reader_params):
251318
"""WEB UI to visualize VSI statistics for a web mercator tile requests."""
252319
if reader:
253320
module, classname = reader.rsplit(".", 1)
254321
reader = getattr(importlib.import_module(module), classname) # noqa
255-
if not issubclass(reader, (BaseReader)):
322+
if not issubclass(reader, (BaseReader, MultiBandReader, MultiBaseReader)):
256323
warnings.warn(f"Invalid reader type: {type(reader)}", stacklevel=1)
257324

258-
Reader = reader or COGReader
325+
DstReader = reader or Reader
259326

260327
config = config or {}
261328

262329
application = TileDebug(
263330
src_path=src_path,
264-
reader=Reader,
331+
reader=DstReader,
332+
reader_params=reader_params,
265333
port=port,
266334
host=host,
267335
config=config,

0 commit comments

Comments
 (0)