rio-tiler 6.8.0__py3-none-any.whl → 7.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
rio_tiler/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """rio-tiler."""
2
2
 
3
- __version__ = "6.8.0"
3
+ __version__ = "7.0.0"
4
4
 
5
5
  from . import ( # noqa
6
6
  colormap,
rio_tiler/colormap.py CHANGED
@@ -1,5 +1,6 @@
1
1
  """rio-tiler colormap functions and classes."""
2
2
 
3
+ import json
3
4
  import os
4
5
  import pathlib
5
6
  import re
@@ -22,23 +23,30 @@ from rio_tiler.types import (
22
23
  )
23
24
 
24
25
  try:
25
- from importlib.resources import files as resources_files # type: ignore
26
+ from importlib.resources import as_file
27
+ from importlib.resources import files as resources_files
26
28
  except ImportError:
27
29
  # Try backported to PY<39 `importlib_resources`.
30
+ from importlib_resources import as_file # type: ignore
28
31
  from importlib_resources import files as resources_files # type: ignore
29
32
 
30
33
 
31
34
  EMPTY_COLORMAP: GDALColorMapType = {i: (0, 0, 0, 0) for i in range(256)}
32
35
 
33
- DEFAULT_CMAPS_FILES = {
34
- f.stem: str(f)
35
- for f in (resources_files(__package__) / "cmap_data").glob("*.npy") # type: ignore
36
- }
36
+ _RIO_CMAP_DIR = resources_files(__package__) / "cmap_data"
37
+ with as_file(_RIO_CMAP_DIR) as p:
38
+ DEFAULT_CMAPS_FILES = {
39
+ f.stem: f for f in p.glob("**/*") if f.suffix in {".npy", ".json"}
40
+ }
37
41
 
38
42
  USER_CMAPS_DIR = os.environ.get("COLORMAP_DIRECTORY", None)
39
43
  if USER_CMAPS_DIR:
40
44
  DEFAULT_CMAPS_FILES.update(
41
- {f.stem: str(f) for f in pathlib.Path(USER_CMAPS_DIR).glob("*.npy")}
45
+ {
46
+ f.stem: f
47
+ for f in pathlib.Path(USER_CMAPS_DIR).glob("**/*")
48
+ if f.suffix in {".npy", ".json"}
49
+ }
42
50
  )
43
51
 
44
52
 
@@ -129,7 +137,7 @@ def apply_discrete_cmap(data: numpy.ndarray, colormap: GDALColorMapType) -> Data
129
137
 
130
138
  Args:
131
139
  data (numpy.ndarray): 1D image array to translate to RGB.
132
- color_map (dict): Discrete ColorMap dictionary.
140
+ colormap (GDALColorMapType): Discrete ColorMap dictionary.
133
141
 
134
142
  Returns:
135
143
  tuple: Data (numpy.ndarray) and Alpha band (numpy.ndarray).
@@ -168,7 +176,7 @@ def apply_intervals_cmap(
168
176
 
169
177
  Args:
170
178
  data (numpy.ndarray): 1D image array to translate to RGB.
171
- color_map (Sequence): Sequence of intervals and color in form of [([min, max], [r, g, b, a]), ...].
179
+ colormap (IntervalColorMapType): Sequence of intervals and color in form of [([min, max], [r, g, b, a]), ...].
172
180
 
173
181
  Returns:
174
182
  tuple: Data (numpy.ndarray) and Alpha band (numpy.ndarray).
@@ -274,7 +282,7 @@ class ColorMaps:
274
282
 
275
283
  """
276
284
 
277
- data: Dict[str, Union[str, ColorMapType]] = attr.ib(
285
+ data: Dict[str, Union[str, pathlib.Path, ColorMapType]] = attr.ib(
278
286
  default=attr.Factory(lambda: DEFAULT_CMAPS_FILES)
279
287
  )
280
288
 
@@ -288,17 +296,45 @@ class ColorMaps:
288
296
  dict: colormap dictionary.
289
297
 
290
298
  """
291
- cmap = self.data.get(name.lower(), None)
299
+ cmap = self.data.get(name, None)
292
300
  if cmap is None:
293
301
  raise InvalidColorMapName(f"Invalid colormap name: {name}")
294
302
 
295
- if isinstance(cmap, str):
296
- colormap = numpy.load(cmap)
297
- assert colormap.shape == (256, 4)
298
- assert colormap.dtype == numpy.uint8
299
- return {idx: tuple(value) for idx, value in enumerate(colormap)} # type: ignore
300
- else:
301
- return cmap
303
+ if isinstance(cmap, (pathlib.Path, str)):
304
+ if isinstance(cmap, str):
305
+ cmap = pathlib.Path(cmap)
306
+
307
+ if cmap.suffix == ".npy":
308
+ colormap = numpy.load(cmap)
309
+ assert colormap.shape == (256, 4)
310
+ assert colormap.dtype == numpy.uint8
311
+ cmap_data = {idx: tuple(value) for idx, value in enumerate(colormap)}
312
+
313
+ elif cmap.suffix == ".json":
314
+ with cmap.open() as f:
315
+ cmap_data = json.load(
316
+ f,
317
+ object_hook=lambda x: {
318
+ int(k): parse_color(v) for k, v in x.items()
319
+ },
320
+ )
321
+
322
+ # Make sure to match colormap type
323
+ if isinstance(cmap_data, Sequence):
324
+ cmap_data = [
325
+ (tuple(inter), parse_color(v)) # type: ignore
326
+ for (inter, v) in cmap_data
327
+ ]
328
+
329
+ else:
330
+ raise ValueError(f"Not supported {cmap.suffix} extension for ColorMap")
331
+
332
+ # save the numpy array / dict / sequence in the data dict
333
+ # avoiding the need to re-load the data
334
+ self.data[name] = cmap_data
335
+ return cmap_data
336
+
337
+ return cmap
302
338
 
303
339
  def list(self) -> List[str]:
304
340
  """List registered Colormaps.
@@ -311,7 +347,7 @@ class ColorMaps:
311
347
 
312
348
  def register(
313
349
  self,
314
- custom_cmap: Dict[str, Union[str, ColorMapType]],
350
+ custom_cmap: Dict[str, Union[str, pathlib.Path, ColorMapType]],
315
351
  overwrite: bool = False,
316
352
  ) -> "ColorMaps":
317
353
  """Register a custom colormap.