Skip to content

Commit 738be8a

Browse files
authored
Allow a default rescale parameter to be set via a dependency (#619)
This lets us define a default rescale value from a separate config without needing to include it in the query params for every request.
1 parent f828445 commit 738be8a

File tree

5 files changed

+56
-26
lines changed

5 files changed

+56
-26
lines changed

CHANGES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Release Notes
22

3+
## Next
4+
5+
* Allow a default `rescale` parameter to be set via a dependency (author @samn, https://github.com/developmentseed/titiler/pull/619)
6+
37
## 0.11.5 (2023-03-22)
48

59
* fix `TerrainRGB` (change interval from `1.0` to `0.1`)

src/titiler/core/tests/test_factories.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from dataclasses import dataclass
77
from enum import Enum
88
from io import BytesIO
9-
from typing import Dict, Type
9+
from typing import Dict, Optional, Type
1010
from unittest.mock import patch
1111
from urllib.parse import urlencode
1212

@@ -21,6 +21,7 @@
2121
from starlette.requests import Request
2222
from starlette.testclient import TestClient
2323

24+
from titiler.core.dependencies import RescaleType
2425
from titiler.core.errors import DEFAULT_STATUS_CODES, add_exception_handlers
2526
from titiler.core.factory import (
2627
AlgorithmFactory,
@@ -1513,3 +1514,34 @@ def test_AutoFormat_Colormap():
15131514
0,
15141515
] # when creating a PNG, GDAL will set masked value to 0
15151516
assert img[:, 500, 500].tolist() == [255, 0, 0, 255]
1517+
1518+
1519+
def test_rescale_dependency():
1520+
"""Ensure that we can set default rescale values via the rescale_dependency"""
1521+
1522+
def custom_rescale_params() -> Optional[RescaleType]:
1523+
return [(0, 100)]
1524+
1525+
cog = TilerFactory()
1526+
cog_custom_range = TilerFactory(rescale_dependency=custom_rescale_params)
1527+
1528+
app = FastAPI()
1529+
app.include_router(cog.router, prefix="/cog")
1530+
app.include_router(cog_custom_range.router, prefix="/cog_custom")
1531+
1532+
with TestClient(app) as client:
1533+
response = client.get(
1534+
f"/cog/tiles/8/87/48.npy?url={DATA_DIR}/cog.tif&rescale=0,1000"
1535+
)
1536+
assert response.status_code == 200
1537+
assert response.headers["content-type"] == "application/x-binary"
1538+
npy_tile = numpy.load(BytesIO(response.content))
1539+
assert npy_tile.shape == (2, 256, 256) # mask + data
1540+
1541+
response = client.get(
1542+
f"/cog_custom/tiles/8/87/48.npy?url={DATA_DIR}/cog.tif&rescale=0,1000"
1543+
)
1544+
assert response.status_code == 200
1545+
assert response.headers["content-type"] == "application/x-binary"
1546+
npy_tile_custom = numpy.load(BytesIO(response.content))
1547+
assert npy_tile.shape == (2, 256, 256) # mask + data

src/titiler/core/titiler/core/dependencies.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,14 +350,17 @@ class ImageRenderingParams(DefaultDependency):
350350
)
351351

352352

353+
RescaleType = List[Tuple[float, ...]]
354+
355+
353356
def RescalingParams(
354357
rescale: Optional[List[str]] = Query(
355358
None,
356359
title="Min/Max data Rescaling",
357360
description="comma (',') delimited Min,Max range. Can set multiple time for multiple bands.",
358361
example=["0,2000", "0,1000", "0,10000"], # band 1 # band 2 # band 3
359362
)
360-
) -> Optional[List[Tuple[float, ...]]]:
363+
) -> Optional[RescaleType]:
361364
"""Min/Max data Rescaling"""
362365
if rescale:
363366
return [tuple(map(float, r.replace(" ", "").split(","))) for r in rescale]

src/titiler/core/titiler/core/factory.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
HistogramParams,
4242
ImageParams,
4343
ImageRenderingParams,
44+
RescaleType,
4445
RescalingParams,
4546
StatisticsParams,
4647
)
@@ -141,6 +142,8 @@ class BaseTilerFactory(metaclass=abc.ABCMeta):
141142
render_dependency: Type[DefaultDependency] = ImageRenderingParams
142143
colormap_dependency: Callable[..., Optional[ColorMapType]] = ColorMapParams
143144

145+
rescale_dependency: Callable[..., Optional[RescaleType]] = RescalingParams
146+
144147
# Post Processing Dependencies (algorithm)
145148
process_dependency: Callable[
146149
..., Optional[BaseAlgorithm]
@@ -512,7 +515,7 @@ def tile(
512515
description="Buffer on each side of the given tile. It must be a multiple of `0.5`. Output **tilesize** will be expanded to `tilesize + 2 * buffer` (e.g 0.5 = 257x257, 1.0 = 258x258).",
513516
),
514517
post_process=Depends(self.process_dependency),
515-
rescale: Optional[List[Tuple[float, ...]]] = Depends(RescalingParams),
518+
rescale=Depends(self.rescale_dependency),
516519
color_formula: Optional[str] = Query(
517520
None,
518521
title="Color Formula",
@@ -604,9 +607,7 @@ def tilejson(
604607
description="Buffer on each side of the given tile. It must be a multiple of `0.5`. Output **tilesize** will be expanded to `tilesize + 2 * buffer` (e.g 0.5 = 257x257, 1.0 = 258x258).",
605608
),
606609
post_process=Depends(self.process_dependency), # noqa
607-
rescale: Optional[List[Tuple[float, ...]]] = Depends(
608-
RescalingParams
609-
), # noqa
610+
rescale=Depends(self.rescale_dependency), # noqa
610611
color_formula: Optional[str] = Query( # noqa
611612
None,
612613
title="Color Formula",
@@ -687,9 +688,7 @@ def map_viewer(
687688
description="Buffer on each side of the given tile. It must be a multiple of `0.5`. Output **tilesize** will be expanded to `tilesize + 2 * buffer` (e.g 0.5 = 257x257, 1.0 = 258x258).",
688689
),
689690
post_process=Depends(self.process_dependency), # noqa
690-
rescale: Optional[List[Tuple[float, ...]]] = Depends(
691-
RescalingParams
692-
), # noqa
691+
rescale=Depends(self.rescale_dependency), # noqa
693692
color_formula: Optional[str] = Query( # noqa
694693
None,
695694
title="Color Formula",
@@ -754,9 +753,7 @@ def wmts(
754753
description="Buffer on each side of the given tile. It must be a multiple of `0.5`. Output **tilesize** will be expanded to `tilesize + 2 * buffer` (e.g 0.5 = 257x257, 1.0 = 258x258).",
755754
),
756755
post_process=Depends(self.process_dependency), # noqa
757-
rescale: Optional[List[Tuple[float, ...]]] = Depends(
758-
RescalingParams
759-
), # noqa
756+
rescale=Depends(self.rescale_dependency), # noqa
760757
color_formula: Optional[str] = Query( # noqa
761758
None,
762759
title="Color Formula",
@@ -886,7 +883,7 @@ def preview(
886883
dataset_params=Depends(self.dataset_dependency),
887884
img_params=Depends(self.img_dependency),
888885
post_process=Depends(self.process_dependency),
889-
rescale: Optional[List[Tuple[float, ...]]] = Depends(RescalingParams),
886+
rescale=Depends(self.rescale_dependency), # noqa
890887
color_formula: Optional[str] = Query(
891888
None,
892889
title="Color Formula",
@@ -956,7 +953,7 @@ def part(
956953
dataset_params=Depends(self.dataset_dependency),
957954
image_params=Depends(self.img_dependency),
958955
post_process=Depends(self.process_dependency),
959-
rescale: Optional[List[Tuple[float, ...]]] = Depends(RescalingParams),
956+
rescale=Depends(self.rescale_dependency),
960957
color_formula: Optional[str] = Query(
961958
None,
962959
title="Color Formula",
@@ -1021,7 +1018,7 @@ def geojson_crop(
10211018
dataset_params=Depends(self.dataset_dependency),
10221019
image_params=Depends(self.img_dependency),
10231020
post_process=Depends(self.process_dependency),
1024-
rescale: Optional[List[Tuple[float, ...]]] = Depends(RescalingParams),
1021+
rescale=Depends(self.rescale_dependency),
10251022
color_formula: Optional[str] = Query(
10261023
None,
10271024
title="Color Formula",

src/titiler/mosaic/titiler/mosaic/factory.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from starlette.requests import Request
2222
from starlette.responses import HTMLResponse, Response
2323

24-
from titiler.core.dependencies import DefaultDependency, RescalingParams
24+
from titiler.core.dependencies import DefaultDependency
2525
from titiler.core.factory import BaseTilerFactory, img_endpoint_params, templates
2626
from titiler.core.models.mapbox import TileJSON
2727
from titiler.core.resources.enums import ImageType, MediaType, OptionalHeader
@@ -254,7 +254,7 @@ def tile(
254254
description="Buffer on each side of the given tile. It must be a multiple of `0.5`. Output **tilesize** will be expanded to `tilesize + 2 * tile_buffer` (e.g 0.5 = 257x257, 1.0 = 258x258).",
255255
),
256256
post_process=Depends(self.process_dependency),
257-
rescale: Optional[List[Tuple[float, ...]]] = Depends(RescalingParams),
257+
rescale=Depends(self.rescale_dependency),
258258
color_formula: Optional[str] = Query(
259259
None,
260260
title="Color Formula",
@@ -371,9 +371,7 @@ def tilejson(
371371
description="Buffer on each side of the given tile. It must be a multiple of `0.5`. Output **tilesize** will be expanded to `tilesize + 2 * tile_buffer` (e.g 0.5 = 257x257, 1.0 = 258x258).",
372372
),
373373
post_process=Depends(self.process_dependency), # noqa
374-
rescale: Optional[List[Tuple[float, ...]]] = Depends(
375-
RescalingParams
376-
), # noqa
374+
rescale=Depends(self.rescale_dependency), # noqa
377375
color_formula: Optional[str] = Query( # noqa
378376
None,
379377
title="Color Formula",
@@ -463,9 +461,7 @@ def map_viewer(
463461
title="Tile buffer.",
464462
description="Buffer on each side of the given tile. It must be a multiple of `0.5`. Output **tilesize** will be expanded to `tilesize + 2 * tile_buffer` (e.g 0.5 = 257x257, 1.0 = 258x258).",
465463
),
466-
rescale: Optional[List[Tuple[float, ...]]] = Depends(
467-
RescalingParams
468-
), # noqa
464+
rescale=Depends(self.rescale_dependency), # noqa
469465
color_formula: Optional[str] = Query( # noqa
470466
None,
471467
title="Color Formula",
@@ -532,9 +528,7 @@ def wmts(
532528
description="Buffer on each side of the given tile. It must be a multiple of `0.5`. Output **tilesize** will be expanded to `tilesize + 2 * tile_buffer` (e.g 0.5 = 257x257, 1.0 = 258x258).",
533529
),
534530
post_process=Depends(self.process_dependency), # noqa
535-
rescale: Optional[List[Tuple[float, ...]]] = Depends(
536-
RescalingParams
537-
), # noqa
531+
rescale=Depends(self.rescale_dependency), # noqa
538532
color_formula: Optional[str] = Query( # noqa
539533
None,
540534
title="Color Formula",

0 commit comments

Comments
 (0)