11
11
from loguru import logger as log
12
12
from rasterio ._path import _parse_path as parse_path
13
13
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
15
15
16
16
from tilebench import profile as profiler
17
17
from tilebench .viz import TileDebug
18
18
19
19
default_tms = morecantile .tms .get ("WebMercatorQuad" )
20
20
21
21
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
+
22
50
# The CLI command group.
23
51
@click .group (help = "Command line interface for the tilebench Python package." )
24
52
def cli ():
@@ -51,7 +79,7 @@ def cli():
51
79
@click .option (
52
80
"--reader" ,
53
81
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 `" ,
55
83
)
56
84
@click .option (
57
85
"--tms" ,
@@ -66,6 +94,15 @@ def cli():
66
94
callback = options ._cb_key_val ,
67
95
help = "GDAL configuration options." ,
68
96
)
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
+ )
69
106
def profile (
70
107
input ,
71
108
tile ,
@@ -77,8 +114,9 @@ def profile(
77
114
reader ,
78
115
tms ,
79
116
config ,
117
+ reader_params ,
80
118
):
81
- """Profile COGReader Mercator Tile read."""
119
+ """Profile Reader Tile read."""
82
120
tilematrixset = default_tms
83
121
if tms :
84
122
with open (tms , "r" ) as f :
@@ -90,15 +128,17 @@ def profile(
90
128
if not issubclass (reader , (BaseReader , MultiBandReader , MultiBaseReader )):
91
129
warnings .warn (f"Invalid reader type: { type (reader )} " , stacklevel = 1 )
92
130
93
- Reader = reader or COGReader
131
+ DstReader = reader or Reader
94
132
95
133
if not tile :
96
134
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 :
98
136
if zoom is None :
99
137
zoom = randint (cog .minzoom , cog .maxzoom )
100
138
101
- w , s , e , n = cog .geographic_bounds
139
+ w , s , e , n = cog .get_geographic_bounds (
140
+ tilematrixset .rasterio_geographic_crs
141
+ )
102
142
# Truncate BBox to the TMS bounds
103
143
w = max (tilematrixset .bbox .left , w )
104
144
s = max (tilematrixset .bbox .bottom , s )
@@ -128,7 +168,7 @@ def profile(
128
168
config = config ,
129
169
)
130
170
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 :
132
172
return cog .tile (x , y , z , tilesize = tilesize )
133
173
134
174
(_ , _ ), 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):
141
181
@click .option (
142
182
"--reader" ,
143
183
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 `" ,
145
185
)
146
186
@click .option (
147
187
"--tms" ,
148
188
help = "Path to TileMatrixSet JSON file." ,
149
189
type = click .Path (),
150
190
)
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 ):
152
201
"""Get Mercator Zoom levels."""
153
202
tilematrixset = default_tms
154
203
if tms :
@@ -161,9 +210,9 @@ def get_zooms(input, reader, tms):
161
210
if not issubclass (reader , (BaseReader , MultiBandReader , MultiBaseReader )):
162
211
warnings .warn (f"Invalid reader type: { type (reader )} " , stacklevel = 1 )
163
212
164
- Reader = reader or COGReader
213
+ DstReader = reader or Reader
165
214
166
- with Reader (input , tms = tilematrixset ) as cog :
215
+ with DstReader (input , tms = tilematrixset , ** reader_params ) as cog :
167
216
click .echo (json .dumps ({"minzoom" : cog .minzoom , "maxzoom" : cog .maxzoom }))
168
217
169
218
@@ -173,14 +222,23 @@ def get_zooms(input, reader, tms):
173
222
@click .option (
174
223
"--reader" ,
175
224
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 `" ,
177
226
)
178
227
@click .option (
179
228
"--tms" ,
180
229
help = "Path to TileMatrixSet JSON file." ,
181
230
type = click .Path (),
182
231
)
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 ):
184
242
"""Get random tile."""
185
243
tilematrixset = default_tms
186
244
if tms :
@@ -193,12 +251,12 @@ def random(input, zoom, reader, tms):
193
251
if not issubclass (reader , (BaseReader , MultiBandReader , MultiBaseReader )):
194
252
warnings .warn (f"Invalid reader type: { type (reader )} " , stacklevel = 1 )
195
253
196
- Reader = reader or COGReader
254
+ DstReader = reader or Reader
197
255
198
- with Reader (input , tms = tilematrixset ) as cog :
256
+ with DstReader (input , tms = tilematrixset , ** reader_params ) as cog :
199
257
if zoom is None :
200
258
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 )
202
260
203
261
# Truncate BBox to the TMS bounds
204
262
w = max (tilematrixset .bbox .left , w )
@@ -237,7 +295,7 @@ def random(input, zoom, reader, tms):
237
295
@click .option (
238
296
"--reader" ,
239
297
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 `" ,
241
299
)
242
300
@click .option (
243
301
"--config" ,
@@ -247,21 +305,31 @@ def random(input, zoom, reader, tms):
247
305
callback = options ._cb_key_val ,
248
306
help = "GDAL configuration options." ,
249
307
)
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 ):
251
318
"""WEB UI to visualize VSI statistics for a web mercator tile requests."""
252
319
if reader :
253
320
module , classname = reader .rsplit ("." , 1 )
254
321
reader = getattr (importlib .import_module (module ), classname ) # noqa
255
- if not issubclass (reader , (BaseReader )):
322
+ if not issubclass (reader , (BaseReader , MultiBandReader , MultiBaseReader )):
256
323
warnings .warn (f"Invalid reader type: { type (reader )} " , stacklevel = 1 )
257
324
258
- Reader = reader or COGReader
325
+ DstReader = reader or Reader
259
326
260
327
config = config or {}
261
328
262
329
application = TileDebug (
263
330
src_path = src_path ,
264
- reader = Reader ,
331
+ reader = DstReader ,
332
+ reader_params = reader_params ,
265
333
port = port ,
266
334
host = host ,
267
335
config = config ,
0 commit comments