diff --git a/CHANGES.md b/CHANGES.md index 269d6d3c3..ee5667a93 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,10 @@ # Release Notes +## Next Release + +* Allow a default `color_formula` parameter to be set via a dependency (author @samn, https://github.com/developmentseed/titiler/pull/707) + + ## 0.15.0 (2023-09-28) ### titiler.core diff --git a/src/titiler/core/tests/test_factories.py b/src/titiler/core/tests/test_factories.py index 02a42e39c..e649b04d4 100644 --- a/src/titiler/core/tests/test_factories.py +++ b/src/titiler/core/tests/test_factories.py @@ -1648,3 +1648,34 @@ def test_dst_crs_option(): ) meta = parse_img(response.content) assert meta["crs"] == CRS.from_epsg(32621) + + +def test_color_formula_dependency(): + """Ensure that we can set default color formulae via the color_formula_dependency""" + + def custom_color_formula_params() -> Optional[str]: + return "sigmoidal R 7 0.4" + + cog = TilerFactory() + cog_custom_color_formula = TilerFactory( + color_formula_dependency=custom_color_formula_params + ) + + app = FastAPI() + app.include_router(cog.router, prefix="/cog") + app.include_router(cog_custom_color_formula.router, prefix="/cog_custom") + + with TestClient(app) as client: + response = client.get( + f"/cog/tiles/8/87/48.npy?url={DATA_DIR}/cog.tif&color_formula=sigmoidal R 10 0.1" + ) + assert response.status_code == 200 + assert response.headers["content-type"] == "application/x-binary" + npy_tile = numpy.load(BytesIO(response.content)) + assert npy_tile.shape == (2, 256, 256) # mask + data + + response = client.get(f"/cog_custom/tiles/8/87/48.npy?url={DATA_DIR}/cog.tif") + assert response.status_code == 200 + assert response.headers["content-type"] == "application/x-binary" + numpy.load(BytesIO(response.content)) + assert npy_tile.shape == (2, 256, 256) # mask + data diff --git a/src/titiler/core/titiler/core/factory.py b/src/titiler/core/titiler/core/factory.py index 099736499..a56dbe77b 100644 --- a/src/titiler/core/titiler/core/factory.py +++ b/src/titiler/core/titiler/core/factory.py @@ -146,6 +146,7 @@ class BaseTilerFactory(metaclass=abc.ABCMeta): # Image rendering Dependencies render_dependency: Type[DefaultDependency] = ImageRenderingParams colormap_dependency: Callable[..., Optional[ColorMapType]] = ColorMapParams + color_formula_dependency: Callable[..., Optional[str]] = ColorFormulaParams rescale_dependency: Callable[..., Optional[RescaleType]] = RescalingParams @@ -539,7 +540,7 @@ def tile( buffer=Depends(BufferParams), post_process=Depends(self.process_dependency), rescale=Depends(self.rescale_dependency), - color_formula=Depends(ColorFormulaParams), + color_formula=Depends(self.color_formula_dependency), colormap=Depends(self.colormap_dependency), render_params=Depends(self.render_dependency), reader_params=Depends(self.reader_dependency), @@ -625,7 +626,7 @@ def tilejson( buffer=Depends(BufferParams), post_process=Depends(self.process_dependency), rescale=Depends(self.rescale_dependency), - color_formula=Depends(ColorFormulaParams), + color_formula=Depends(self.color_formula_dependency), colormap=Depends(self.colormap_dependency), render_params=Depends(self.render_dependency), reader_params=Depends(self.reader_dependency), @@ -705,7 +706,7 @@ def map_viewer( buffer=Depends(BufferParams), post_process=Depends(self.process_dependency), rescale=Depends(self.rescale_dependency), - color_formula=Depends(ColorFormulaParams), + color_formula=Depends(self.color_formula_dependency), colormap=Depends(self.colormap_dependency), render_params=Depends(self.render_dependency), reader_params=Depends(self.reader_dependency), @@ -767,7 +768,7 @@ def wmts( buffer=Depends(BufferParams), post_process=Depends(self.process_dependency), rescale=Depends(self.rescale_dependency), - color_formula=Depends(ColorFormulaParams), + color_formula=Depends(self.color_formula_dependency), colormap=Depends(self.colormap_dependency), render_params=Depends(self.render_dependency), reader_params=Depends(self.reader_dependency), @@ -898,7 +899,7 @@ def preview( image_params=Depends(self.img_preview_dependency), post_process=Depends(self.process_dependency), rescale=Depends(self.rescale_dependency), - color_formula=Depends(ColorFormulaParams), + color_formula=Depends(self.color_formula_dependency), colormap=Depends(self.colormap_dependency), render_params=Depends(self.render_dependency), reader_params=Depends(self.reader_dependency), @@ -965,7 +966,7 @@ def bbox_image( image_params=Depends(self.img_part_dependency), post_process=Depends(self.process_dependency), rescale=Depends(self.rescale_dependency), - color_formula=Depends(ColorFormulaParams), + color_formula=Depends(self.color_formula_dependency), colormap=Depends(self.colormap_dependency), render_params=Depends(self.render_dependency), reader_params=Depends(self.reader_dependency), @@ -1028,7 +1029,7 @@ def feature_image( image_params=Depends(self.img_part_dependency), post_process=Depends(self.process_dependency), rescale=Depends(self.rescale_dependency), - color_formula=Depends(ColorFormulaParams), + color_formula=Depends(self.color_formula_dependency), colormap=Depends(self.colormap_dependency), render_params=Depends(self.render_dependency), reader_params=Depends(self.reader_dependency), diff --git a/src/titiler/mosaic/titiler/mosaic/factory.py b/src/titiler/mosaic/titiler/mosaic/factory.py index fb12e7eb9..fad9104ea 100644 --- a/src/titiler/mosaic/titiler/mosaic/factory.py +++ b/src/titiler/mosaic/titiler/mosaic/factory.py @@ -24,12 +24,7 @@ from starlette.responses import HTMLResponse, Response from typing_extensions import Annotated -from titiler.core.dependencies import ( - BufferParams, - ColorFormulaParams, - CoordCRSParams, - DefaultDependency, -) +from titiler.core.dependencies import BufferParams, CoordCRSParams, DefaultDependency from titiler.core.factory import BaseTilerFactory, img_endpoint_params from titiler.core.models.mapbox import TileJSON from titiler.core.resources.enums import ImageType, MediaType, OptionalHeader @@ -274,7 +269,7 @@ def tile( buffer=Depends(BufferParams), post_process=Depends(self.process_dependency), rescale=Depends(self.rescale_dependency), - color_formula=Depends(ColorFormulaParams), + color_formula=Depends(self.color_formula_dependency), colormap=Depends(self.colormap_dependency), render_params=Depends(self.render_dependency), backend_params=Depends(self.backend_dependency), @@ -393,7 +388,7 @@ def tilejson( buffer=Depends(BufferParams), post_process=Depends(self.process_dependency), rescale=Depends(self.rescale_dependency), - color_formula=Depends(ColorFormulaParams), + color_formula=Depends(self.color_formula_dependency), colormap=Depends(self.colormap_dependency), render_params=Depends(self.render_dependency), backend_params=Depends(self.backend_dependency), @@ -485,7 +480,7 @@ def map_viewer( pixel_selection=Depends(self.pixel_selection_dependency), buffer=Depends(BufferParams), rescale=Depends(self.rescale_dependency), - color_formula=Depends(ColorFormulaParams), + color_formula=Depends(self.color_formula_dependency), colormap=Depends(self.colormap_dependency), render_params=Depends(self.render_dependency), backend_params=Depends(self.backend_dependency), @@ -549,7 +544,7 @@ def wmts( buffer=Depends(BufferParams), post_process=Depends(self.process_dependency), rescale=Depends(self.rescale_dependency), - color_formula=Depends(ColorFormulaParams), + color_formula=Depends(self.color_formula_dependency), colormap=Depends(self.colormap_dependency), render_params=Depends(self.render_dependency), backend_params=Depends(self.backend_dependency),