diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/404.html b/404.html new file mode 100644 index 000000000..a8a3f6890 --- /dev/null +++ b/404.html @@ -0,0 +1,1520 @@ + + + +
+ + + + + + + + + + + + + +Important
+This has been deprecated. You can now pass environment_dependency=lambda: {"GDAL_DISABLE_READDIR_ON_OPEN":"FALSE"}
to the Tiler Factory. This will be passed to a rasterio.Env()
context manager on top of all gdal related blocks.
from titiler.core.factory import TilerFactory
+cog = TilerFactory(
+ reader=COGReader,
+ router_prefix="cog",
+ environment_dependency=lambda: {"GDAL_DISABLE_READDIR_ON_OPEN":"FALSE"},
+)
+
Sometimes, specifically when using GDAL, it can be useful to have environment variables set for certain endpoints
+(e.g. when using Landsat data on AWS you need GDAL_DISABLE_READDIR_ON_OPEN=FALSE
but you don't want this environment variable set for other endpoints). To be able to do this
+we created a custom APIRoute class which wraps classic fastapi APIRoute with a rasterio.Env()
block: github.com/developmentseed/titiler/blob/8a7127ca56631c2c327713d99e80285048c3aa6c/titiler/custom/routing.py#L13-L41
Example: +
from fastapi import FastAPI, APIRouter
+from rasterio._env import get_gdal_config
+from titiler.core.routing import apiroute_factory
+from titiler.core.factory import TilerFactory
+
+app = FastAPI()
+route_class = apiroute_factory({"GDAL_DISABLE_READDIR_ON_OPEN": "FALSE"})
+router = APIRouter(route_class=route_class)
+
+tiler = TilerFactory(router=router)
+
+@router.get("/simple")
+def simple():
+ """should return FALSE."""
+ res = get_gdal_config("GDAL_DISABLE_READDIR_ON_OPEN")
+ return {"env": res}
+
+app.include_router(router)
+
Important
+This has only be tested for python 3.6 and 3.7.
+Starting with titiler>=0.8
, we added the possibility to apply custom algorithms on Image outputs from tile
, crop
or preview
endpoints.
The algorithms are meant to overcome the limitation of expression
(using numexpr) by allowing more complex operations.
We added a set of custom algorithms:
+hillshade
: Create hillshade from elevation datasetcontours
: Create contours lines (raster) from elevation datasetterrarium
: Mapzen's format to encode elevation value in RGB values (github.com/tilezen/joerd/blob/master/docs/formats.md#terrarium)terrainrgb
: Mapbox's format to encode elevation value in RGB values (docs.mapbox.com/data/tilesets/guides/access-elevation-data/)normalizedIndex
: Normalized Difference Index (e.g NDVI)# return a
+httpx.get(
+ "http://127.0.0.1:8081/cog/tiles/16/34059/23335",
+ params={
+ "url": "https://data.geo.admin.ch/ch.swisstopo.swissalti3d/swissalti3d_2019_2573-1085/swissalti3d_2019_2573-1085_0.5_2056_5728.tif",
+ "buffer": 3, # By default hillshade will crop the output with a 3pixel buffer, so we need to apply a buffer on the tile
+ "algorithm": "hillshade",
+ },
+)
+
# Pass algorithm parameter as a json string
+httpx.get(
+ "http://127.0.0.1:8081/cog/preview",
+ params={
+ "url": "https://data.geo.admin.ch/ch.swisstopo.swissalti3d/swissalti3d_2019_2573-1085/swissalti3d_2019_2573-1085_0.5_2056_5728.tif",
+ "algorithm": "contour",
+ "algorithm_params": json.dumps({"minz": 1600, "maxz": 2100}) # algorithm params HAVE TO be provided as a JSON string
+ },
+)
+
A titiler'w Algorithm
must be defined using titiler.core.algorithm.BaseAlgorithm
base class.
class BaseAlgorithm(BaseModel, metaclass=abc.ABCMeta):
+ """Algorithm baseclass.
+
+ Note: attribute starting with `input_` or `output_` are considered as metadata
+
+ """
+
+ # metadata
+ input_nbands: int
+ output_nbands: int
+ output_dtype: str
+ output_min: Optional[Sequence]
+ output_max: Optional[Sequence]
+
+ @abc.abstractmethod
+ def __call__(self, img: ImageData) -> ImageData:
+ """Apply algorithm"""
+ ...
+
+ class Config:
+ """Config for model."""
+
+ extra = "allow"
+
This base class defines that algorithm:
+HAVE TO implement an __call__
method which takes an ImageData as input and return an ImageData. Using __call__
let us use the object as a callable (e.g Algorithm(**kwargs)(image)
).
can have input/output metadata (informative)
+can haveparameters
(enabled by extra = "allow"
pydantic config)
Here is a simple example of a custom Algorithm:
+from titiler.core.algorithm import BaseAlgorithm
+from rio_tiler.models import ImageData
+
+class Multiply(BaseAlgorithm):
+
+ # Parameters
+ factor: int # There is no default, which means calls to this algorithm without any parameter will fail
+
+ # We don't set any metadata for this Algorithm
+
+ def __call__(self, img: ImageData) -> ImageData:
+ # Multiply image data bcy factor
+ data = img.data * self.factor
+
+ # Create output ImageData
+ return ImageData(
+ data,
+ img.mask,
+ assets=img.assets,
+ crs=img.crs,
+ bounds=img.bounds,
+ )
+
Using a Pydantic's BaseModel
class to construct the custom algorithm enables two things parametrization and type casting/validation.
If we look at the Multiply
algorithm, we can see it needs a factor
parameter. In Titiler (in the post_process dependency) we will pass this parameter via query string (e.g /preview.png?algo=multiply&algo_parameter={"factor":3}
) and pydantic will make sure we use the right types/values.
# Available algorithm
+algo = {"multiply": Multiply}
+
+def post_process_dependency(
+ algorithm: Literal[tuple(algo.keys())] = Query(None, description="Algorithm name"),
+ algorithm_params: str = Query(None, description="Algorithm parameter"),
+) -> Optional[BaseAlgorithm]:
+ """Data Post-Processing dependency."""
+ # Parse `algorithm_params` JSON parameters
+ kwargs = json.loads(algorithm_params) if algorithm_params else {}
+ if algorithm:
+ # Here we construct the Algorithm Object with the kwargs from the `algo_params` query-parameter
+ return algo[algorithm](**kwargs)
+
+ return None
+
To be able to use your own algorithm in titiler's endpoint you need to create a Dependency
to tell the application what algorithm are available.
To ease the dependency creation, we added a dependency
property in the titiler.core.algorithm.Algorithms
class, which will return a FastAPI dependency to be added to the endpoints.
Note: The Algorithms
class is a store for the algorithm that can be extented using the .register()
method.
from typing import Callable
+from titiler.core.algorithm import algorithms as default_algorithms
+from titiler.core.algorithm import Algorithms
+from titiler.core.factory import TilerFactory
+
+# Add the `Multiply` algorithm to the default ones
+algorithms: Algorithms = default_algorithms.register({"multiply": Multiply})
+
+# Create a PostProcessParams dependency
+PostProcessParams: Callable = algorithms.dependency
+
+endpoints = TilerFactory(process_dependency=PostProcessParams)
+
When creating a map tile (or other images), we will fist apply the algorithm
then the rescaling
and finally the color_formula
.
with reader(url as src_dst:
+ image = src_dst.tile(
+ x,
+ y,
+ z,
+ )
+ dst_colormap = getattr(src_dst, "colormap", None)
+
+# Apply algorithm
+if post_process:
+ image = post_process(image)
+
+# Apply data rescaling
+if rescale:
+ image.rescale(rescale)
+
+# Apply color-formula
+if color_formula:
+ image.apply_color_formula(color_formula)
+
+# Determine the format
+if not format:
+ format = ImageType.jpeg if image.mask.all() else ImageType.png
+
+# Image Rendering
+return image.render(
+ img_format=format.driver,
+ colormap=colormap or dst_colormap,
+ **format.profile,
+)
+
Starting with titiler>=0.11
, we added a new titiler package titiler.extensions
which aim to ease the addition of optional
endpoints to factories.
In titiler.core.factory.BaseTilerFactory
class, we've added a new attribute: extensions: List[FactoryExtension] = field(default_factory=list)
. The list
of extension will then be used in the post-init
step such as:
def __post_init__(self):
+ """Post Init: register route and configure specific options."""
+ # Register endpoints
+ self.register_routes()
+
+ # Register Extensions
+ for ext in self.extensions:
+ ext.register(self)
+
+ # Update endpoints dependencies
+ for scopes, dependencies in self.route_dependencies:
+ self.add_route_dependencies(scopes=scopes, dependencies=dependencies)
+
We defined extension using an Abstract Base Class to make sure they implement a register
method:
@dataclass
+class FactoryExtension(metaclass=abc.ABCMeta):
+ """Factory Extension."""
+
+ @abc.abstractmethod
+ def register(self, factory: "BaseTilerFactory"):
+ """Register extension to the factory."""
+ ...
+
/validate
endpoint which return the content of rio-cogeo info
methodtitiler.extensions["cogeo"]
(installs rio-cogeo
)/viewer
endpoint which return an HTML viewer for simple COGs/viewer
endpoint which return an HTML viewer for STAC item/stac
endpoint which return an HTML viewer for STAC itemtitiler.extensions["stac"]
(installs rio-stac
)/wms
endpoint to support OGC WMS specification (GetCapabilities
and GetMap
)Extensions must be set at TilerFactory's creation using the extensions=
options.
from fastapi import FastAPI
+from titiler.core.factory import TilerFactory
+from titiler.extensions import cogValidateExtension
+
+# Create a FastAPI application
+app = FastAPI(description="A lightweight Cloud Optimized GeoTIFF tile server")
+
+# Create a set of endpoints using TiTiler TilerFactory
+tiler = TilerFactory(
+ router_prefix="/cog",
+ extensions=[
+ cogValidateExtension() # the cogeoExtension will add a rio-cogeo /validate endpoint
+ ]
+)
+
+# Register endpoints to the application
+app.include_router(tiler.router, prefix="/cog")
+
See titiler.application for a full example.
+from dataclasses import dataclass, field
+from typing import Tuple, List, Optional
+
+import rasterio
+from starlette.responses import Response
+from fastapi import Depends, FastAPI, Query
+from titiler.core.factory import BaseTilerFactory, FactoryExtension, TilerFactory
+from titiler.core.dependencies import RescalingParams
+from titiler.core.factory import TilerFactory
+from titiler.core.resources.enums import ImageType
+
+
+@dataclass
+class thumbnailExtension(FactoryExtension):
+ """Add endpoint to a TilerFactory."""
+
+ # Set some options
+ max_size: int = field(default=128)
+
+ # Register method is mandatory and must take a BaseTilerFactory object as input
+ def register(self, factory: BaseTilerFactory):
+ """Register endpoint to the tiler factory."""
+
+ # register an endpoint to the factory's router
+ @factory.router.get(
+ "/thumbnail",
+ responses={
+ 200: {
+ "content": {
+ "image/png": {},
+ "image/jpeg": {},
+ },
+ "description": "Return an image.",
+ }
+ },
+ response_class=Response,
+ )
+ def thumbnail(
+ # we can reuse the factory dependency
+ src_path: str = Depends(factory.path_dependency),
+ layer_params=Depends(factory.layer_dependency),
+ dataset_params=Depends(factory.dataset_dependency),
+ post_process=Depends(factory.process_dependency),
+ rescale: Optional[List[Tuple[float, ...]]] = Depends(RescalingParams),
+ color_formula: Optional[str] = Query(
+ None,
+ title="Color Formula",
+ description="rio-color formula (info: https://github.com/mapbox/rio-color)",
+ ),
+ colormap=Depends(factory.colormap_dependency),
+ render_params=Depends(factory.render_dependency),
+ reader_params=Depends(factory.reader_dependency),
+ env=Depends(factory.environment_dependency),
+ ):
+ with rasterio.Env(**env):
+ with factory.reader(src_path, **reader_params) as src:
+ image = src.preview(
+ max_size=self.max_size,
+ **layer_params,
+ **dataset_params,
+ )
+
+ if post_process:
+ image = post_process(image)
+
+ if rescale:
+ image.rescale(rescale)
+
+ if color_formula:
+ image.apply_color_formula(color_formula)
+
+ format = ImageType.jpeg if image.mask.all() else ImageType.png
+
+ content = image.render(
+ img_format=format.driver,
+ colormap=colormap,
+ **format.profile,
+ **render_params,
+ )
+
+ return Response(content, media_type=format.mediatype)
+
+# Use it
+app = FastAPI()
+tiler = TilerFactory(
+ extensions=[
+ thumbnailExtension(max_size=64)
+ ]
+)
+app.include_router(tiler.router)
+
TiTiler
is designed to help user customize input/output for each endpoint. This section goes over some simple customization examples.
reader_dependency
¶One common customization could be to create your own path_dependency
. This dependency is used on all endpoint and pass inputs to the Readers (MosaicBackend, COGReader, STACReader...).
Here an example which allow a mosaic to be passed by a mosaic name
instead of a full S3 url.
import os
+import re
+
+from fastapi import FastAPI, HTTPException, Query
+
+from titiler.core.dependencies import DefaultDependency
+from titiler.mosaic.factory import MosaicTilerFactory
+
+
+MOSAIC_BACKEND = os.getenv("TITILER_MOSAIC_BACKEND")
+MOSAIC_HOST = os.getenv("TITILER_MOSAIC_HOST")
+
+
+def MosaicPathParams(
+ mosaic: str = Query(..., description="mosaic name")
+) -> str:
+ """Create dataset path from args"""
+ # mosaic name should be in form of `{user}.{layername}`
+ if not re.match(self.mosaic, r"^[a-zA-Z0-9-_]{1,32}\.[a-zA-Z0-9-_]{1,32}$"):
+ raise HTTPException(
+ status_code=400,
+ detail=f"Invalid mosaic name {self.input}.",
+ )
+
+ return f"{MOSAIC_BACKEND}{MOSAIC_HOST}/{self.input}.json.gz"
+
+
+app = FastAPI()
+mosaic = MosaicTilerFactory(path_dependency=MosaicPathParams)
+app.include_router(mosaic.router)
+
The endpoint url will now look like: {endpoint}/mosaic/tilejson.json?mosaic=vincent.mosaic
from morecantile import tms, TileMatrixSet
+from pyproj import CRS
+
+from titiler.core.factory import TilerFactory
+
+# 1. Create Custom TMS
+EPSG6933 = TileMatrixSet.custom(
+ (-17357881.81713629, -7324184.56362408, 17357881.81713629, 7324184.56362408),
+ CRS.from_epsg(6933),
+ identifier="EPSG6933",
+ matrix_scale=[1, 1],
+)
+
+# 2. Register TMS
+tms = tms.register([EPSG6933])
+
+# 3. Create Tiler
+COGTilerWithCustomTMS = TilerFactory(supported_tms=tms)
+
from dataclasses import dataclass
+from typing import List, Optional
+
+from titiler.mosaic.factory import MosaicTilerFactory
+from titiler.core.errors import BadRequestError
+from cogeo_mosaic.mosaic import MosaicJSON
+from cogeo_mosaic.utils import get_footprints
+import rasterio
+
+from pydantic import BaseModel
+
+
+# Models from POST/PUT Body
+class CreateMosaicJSON(BaseModel):
+ """Request body for MosaicJSON creation"""
+
+ files: List[str] # Files to add to the mosaic
+ url: str # path where to save the mosaicJSON
+ minzoom: Optional[int] = None
+ maxzoom: Optional[int] = None
+ max_threads: int = 20
+ overwrite: bool = False
+
+
+class UpdateMosaicJSON(BaseModel):
+ """Request body for updating an existing MosaicJSON"""
+
+ files: List[str] # Files to add to the mosaic
+ url: str # path where to save the mosaicJSON
+ max_threads: int = 20
+ add_first: bool = True
+
+
+@dataclass
+class CustomMosaicFactory(MosaicTilerFactory):
+
+ def register_routes(self):
+ """Update the class method to add create/update"""
+ super().register_routes()
+ # new methods/endpoint
+ self.create()
+ self.update()
+
+ def create(self):
+ """Register / (POST) Create endpoint."""
+
+ @self.router.post(
+ "", response_model=MosaicJSON, response_model_exclude_none=True
+ )
+ def create(
+ body: CreateMosaicJSON,
+ env=Depends(self.environment_dependency),
+ ):
+ """Create a MosaicJSON"""
+ # Write can write to either a local path, a S3 path...
+ # See https://developmentseed.org/cogeo-mosaic/advanced/backends/ for the list of supported backends
+
+ # Create a MosaicJSON file from a list of URL
+ mosaic = MosaicJSON.from_urls(
+ body.files,
+ minzoom=body.minzoom,
+ maxzoom=body.maxzoom,
+ max_threads=body.max_threads,
+ )
+
+ # Write the MosaicJSON using a cogeo-mosaic backend
+ with rasterio.Env(**env):
+ with self.reader(
+ body.url, mosaic_def=mosaic, reader=self.dataset_reader
+ ) as mosaic:
+ try:
+ mosaic.write(overwrite=body.overwrite)
+ except NotImplementedError:
+ raise BadRequestError(
+ f"{mosaic.__class__.__name__} does not support write operations"
+ )
+ return mosaic.mosaic_def
+
+ def update(self):
+ """Register / (PUST) Update endpoint."""
+
+ @self.router.put(
+ "", response_model=MosaicJSON, response_model_exclude_none=True
+ )
+ def update_mosaicjson(
+ body: UpdateMosaicJSON,
+ env=Depends(self.environment_dependency),
+ ):
+ """Update an existing MosaicJSON"""
+ with rasterio.Env(**env):
+ with self.reader(body.url, reader=self.dataset_reader) as mosaic:
+ features = get_footprints(body.files, max_threads=body.max_threads)
+ try:
+ mosaic.update(features, add_first=body.add_first, quiet=True)
+ except NotImplementedError:
+ raise BadRequestError(
+ f"{mosaic.__class__.__name__} does not support update operations"
+ )
+ return mosaic.mosaic_def
+
If you are new to the concept of Dependency Injection, please read this awesome tutorial: fastapi.tiangolo.com/tutorial/dependencies/
+In titiler Factories
, we use the dependencies to define the inputs for each endpoint (and thus the OpenAPI documentation).
Example: +
# Custom Dependency
+
+from dataclasses import dataclass
+from typing import Optional
+
+from fastapi import Depends, FastAPI, Query
+from titiler.core.dependencies import DefaultDependency
+
+from rio_tiler.io import COGReader
+
+@dataclass
+class ImageParams(DefaultDependency):
+ """Common Preview/Crop parameters."""
+
+ max_size: Optional[int] = Query(
+ 1024, description="Maximum image size to read onto."
+ )
+ height: Optional[int] = Query(None, description="Force output image height.")
+ width: Optional[int] = Query(None, description="Force output image width.")
+
+ def __post_init__(self):
+ """Post Init."""
+ if self.width and self.height:
+ self.max_size = None
+
+
+app = FastAPI()
+
+# Simple preview endpoint
+@app.get("/preview.png")
+def preview(
+ url: str = Query(..., description="data set URL"),
+ params: ImageParams = Depends(),
+):
+
+ with COGReader(url) as cog:
+ img = cog.preview(**params) # classes built with `DefaultDependency` can be unpacked
+ # or
+ img = cog.preview(
+ max_size=params.max_size,
+ height=params.height,
+ width=params.width,
+ )
+ ...
+
Important
+In the example above, we create a custom ImageParams
dependency which will then be injected to the preview
endpoint to add max_size, height and width query string parameters.
Using titiler.core.dependencies.DefaultDependency
, we can unpack
the class as if it was a dictionary, which helps with customization.
The factories
allow users to set multiple default dependencies. Here is the list of common dependencies and their default values.
Set dataset path (url).
+def DatasetPathParams(
+ url: str = Query(..., description="Dataset URL")
+) -> str:
+ """Create dataset path from args"""
+ return url
+
Define band indexes or expression
+@dataclass
+class BidxParams(DefaultDependency):
+ """Band Indexes parameters."""
+
+ indexes: Optional[List[int]] = Query(
+ None,
+ title="Band indexes",
+ alias="bidx",
+ description="Dataset band indexes",
+ examples={"one-band": {"value": [1]}, "multi-bands": {"value": [1, 2, 3]}},
+ )
+
+@dataclass
+class ExpressionParams(DefaultDependency):
+ """Expression parameters."""
+
+ expression: Optional[str] = Query(
+ None,
+ title="Band Math expression",
+ description="rio-tiler's band math expression",
+ examples={
+ "simple": {"description": "Simple band math.", "value": "b1/b2"},
+ "multi-bands": {
+ "description": "Semicolon (;) delimited expressions (band1: b1/b2, band2: b2+b3).",
+ "value": "b1/b2;b2+b3",
+ },
+ },
+ )
+
+@dataclass
+class BidxExprParams(ExpressionParams, BidxParams):
+ """Band Indexes and Expression parameters."""
+
+ pass
+
Overwrite nodata value, apply rescaling or change default resampling.
+@dataclass
+class DatasetParams(DefaultDependency):
+ """Low level WarpedVRT Optional parameters."""
+
+ nodata: Optional[Union[str, int, float]] = Query(
+ None, title="Nodata value", description="Overwrite internal Nodata value"
+ )
+ unscale: Optional[bool] = Query(
+ False,
+ title="Apply internal Scale/Offset",
+ description="Apply internal Scale/Offset",
+ )
+ resampling_method: ResamplingName = Query(
+ ResamplingName.nearest, # type: ignore
+ alias="resampling",
+ description="Resampling method.",
+ )
+
+ def __post_init__(self):
+ """Post Init."""
+ if self.nodata is not None:
+ self.nodata = numpy.nan if self.nodata == "nan" else float(self.nodata)
+ self.resampling_method = self.resampling_method.value # type: ignore
+
Image rendering options.
+@dataclass
+class ImageRenderingParams(DefaultDependency):
+ """Image Rendering options."""
+
+ add_mask: bool = Query(
+ True, alias="return_mask", description="Add mask to the output data."
+ )
+
Colormap options.
+def ColorMapParams(
+ colormap_name: ColorMapName = Query(None, description="Colormap name"),
+ colormap: str = Query(None, description="JSON encoded custom Colormap"),
+) -> Optional[Union[Dict, Sequence]]:
+ """Colormap Dependency."""
+ if colormap_name:
+ return cmap.get(colormap_name.value)
+
+ if colormap:
+ try:
+ return json.loads(
+ colormap,
+ object_hook=lambda x: {int(k): parse_color(v) for k, v in x.items()},
+ )
+ except json.JSONDecodeError:
+ raise HTTPException(
+ status_code=400, detail="Could not parse the colormap value."
+ )
+
+ return None
+
Additional reader options. Defaults to DefaultDependency
(empty).
The TMS dependency sets the available TMS for a tile endpoint.
+# Allow all morecantile TMS
+from morecantile import tms as default_tms
+
+tiler = TilerFactory(supported_tms=default_tms)
+
+
+# Restrict the TMS to `WebMercatorQuad` only
+from morecantile import tms
+from morecantile.defaults import TileMatrixSets
+
+# Construct a TileMatrixSets object with only the `WebMercatorQuad` tms
+default_tms = TileMatrixSets({"WebMercatorQuad": tms.get("WebMercatorQuad")})
+tiler = TilerFactory(supported_tms=default_tms)
+
Set the default's TMS Identifier (default to WebMercatorQuad
).
# Create a Tile with it's default TMS being `WGS1984Quad`
+tiler = TilerFactory(default_tms="WGS1984Quad")
+
The TilerFactory
inherits dependency from BaseTilerFactory
.
rio_tiler.io.BaseReader.metadata()
methods options.
@dataclass
+class MetadataParams(DefaultDependency):
+ """Common Metadada parameters."""
+
+ # Required params
+ pmin: float = Query(2.0, description="Minimum percentile")
+ pmax: float = Query(98.0, description="Maximum percentile")
+
+ # Optional params
+ max_size: Optional[int] = Query(
+ None, description="Maximum image size to read onto."
+ )
+ histogram_bins: Optional[int] = Query(None, description="Histogram bins.")
+ histogram_range: Optional[str] = Query(
+ None, description="comma (',') delimited Min,Max histogram bounds"
+ )
+ bounds: Optional[str] = Query(
+ None,
+ descriptions="comma (',') delimited Bounding box coordinates from which to calculate image statistics.",
+ )
+
+ def __post_init__(self):
+ """Post Init."""
+ if self.max_size is not None:
+ self.kwargs["max_size"] = self.max_size
+
+ if self.bounds:
+ self.kwargs["bounds"] = tuple(map(float, self.bounds.split(",")))
+
+ hist_options = {}
+ if self.histogram_bins:
+ hist_options.update(dict(bins=self.histogram_bins))
+ if self.histogram_range:
+ hist_options.update(
+ dict(range=list(map(float, self.histogram_range.split(","))))
+ )
+ if hist_options:
+ self.kwargs["hist_options"] = hist_options
+
Used in Crop/Preview to define size of the output image.
+@dataclass
+class ImageParams(DefaultDependency):
+ """Common Preview/Crop parameters."""
+
+ max_size: Optional[int] = Query(
+ 1024, description="Maximum image size to read onto."
+ )
+ height: Optional[int] = Query(None, description="Force output image height.")
+ width: Optional[int] = Query(None, description="Force output image width.")
+
+ def __post_init__(self):
+ """Post Init."""
+ if self.width and self.height:
+ self.max_size = None
+
The MultiBaseTilerFactory
inherits dependency from TilerFactory
and BaseTilerFactory
.
Define assets
.
@dataclass
+class AssetsParams(DefaultDependency):
+ """Assets parameters."""
+
+ assets: List[str] = Query(
+ None,
+ title="Asset names",
+ description="Asset's names.",
+ examples={
+ "one-asset": {
+ "description": "Return results for asset `data`.",
+ "value": ["data"],
+ },
+ "multi-assets": {
+ "description": "Return results for assets `data` and `cog`.",
+ "value": ["data", "cog"],
+ },
+ },
+ )
+
The MultiBaseTilerFactory
inherits dependency from TilerFactory
and BaseTilerFactory
.
Define bands
.
@dataclass
+class BandsParams(DefaultDependency):
+ """Band names parameters."""
+
+ bands: List[str] = Query(
+ None,
+ title="Band names",
+ description="Band's names.",
+ examples={
+ "one-band": {
+ "description": "Return results for band `B01`.",
+ "value": ["B01"],
+ },
+ "multi-bands": {
+ "description": "Return results for bands `B01` and `B02`.",
+ "value": ["B01", "B02"],
+ },
+ },
+ )
+
The MultiBaseTilerFactory
inherits dependency from BaseTilerFactory
.
Additional backend options. Defaults to DefaultDependency
(empty).
Titiler makes use of several great underlying libraries, including GDAL +and Python bindings to GDAL. An effective deployment of titiler +generally requires tweaking GDAL configuration settings. This document provides +an overview of relevant settings. Full documentation from GDAL is available +here.
+GDAL configuration is modified using environment variables. Thus in order to +change a setting you'll need to set environment variables through your +deployment mechanism. For example, in order to test locally you'd set an +environment variable in bash:
+export GDAL_HTTP_MULTIPLEX=YES
+
GDAL_HTTP_MERGE_CONSECUTIVE_RANGES
¶When set to YES
, this tells GDAL to merge adjacent range requests. Instead of
+making two requests for byte ranges 1-5
and 6-10
, it would make a single
+request for 1-10
. This should always be set to YES
.
GDAL_DISABLE_READDIR_ON_OPEN
¶This is a very important setting to control the number of requests GDAL makes.
+This setting has two options: FALSE
and EMPTY_DIR
. FALSE
(the default)
+causes GDAL to try to establish a list of all the available files in the
+directory. EMPTY_DIR
tells GDAL to imagine that the directory is empty except
+for the requested file.
When reading datasets with necessary external sidecar files, it's imperative to
+set FALSE
. For example, the landsat-pds
bucket on AWS S3 contains GeoTIFF
+images where overviews are in external .ovr
files. If set to EMPTY_DIR
, GDAL
+won't find the .ovr
files.
However, in all other cases, it's much better to set EMPTY_DIR
because this
+prevents GDAL from making a LIST
request.
This setting also has cost implications for reading data from requester-pays
+buckets. When set to FALSE
, GDAL makes a LIST
request every time it opens a
+file. Since LIST
requests are much more expensive than GET
requests, this
+can bring unexpected costs.
CPL_VSIL_CURL_ALLOWED_EXTENSIONS
¶A list of file extensions that GDAL is allowed to open. For example if set to
+.tif
, then GDAL would only open files with a .tif
extension. For example, it
+would fail on JPEG2000 files with a .jp2
extension, but also wouldn't open
+GeoTIFFs exposed through an API endpoint that don't have a .tif
suffix.
Note that you also need to include extensions of external overview files. For
+example, the landsat-pds
bucket on AWS S3 has external overviews in .ovr
+files, so if you wished to read this data, you'd want
GDAL_INGESTED_BYTES_AT_OPEN
¶Gives the number of initial bytes GDAL should read when opening a file and +inspecting its metadata.
+Titiler works best with Cloud-Optimized GeoTIFFs (COGs) because they have a +tiled internal structure that supports efficient random reads. These files have +an initial metadata section that describes the location (byte range) within the +file of each internal tile. The more internal tiles the COG has, the more data +the header needs to contain.
+GDAL needs to read the entire header before it can read any other portion of the +file. By default GDAL reads the first 16KB of the file, then if that doesn't +contain the entire metadata, it makes one more request for the rest of the +metadata.
+In environments where latency is relatively high (at least compared to +bandwidth), such as AWS S3, it may be beneficial to increase this value +depending on the data you expect to read.
+There isn't currently a way to get the number of header bytes using GDAL, but
+alternative GeoTIFF readers such as aiocogeo
can. Using its cli
+you can find the image's header size:
export AWS_REQUEST_PAYER="requester"
+aiocogeo info s3://usgs-landsat/collection02/level-2/standard/oli-tirs/2020/072/076/LC08_L2SR_072076_20201203_20210313_02_T2/LC08_L2SR_072076_20201203_20210313_02_T2_SR_B1.TIF
+
+ PROFILE
+ ...
+ Header size: 32770
+
It's wise to inspect the header sizes of your data sources, and set
+GDAL_INGESTED_BYTES_AT_OPEN
appropriately. Beware, however, that the given
+number of bytes will be read for every image, so you don't want to make the
+value too large.
GDAL_CACHEMAX
¶Default GDAL block cache. The value can be either in Mb, bytes or percent of the physical RAM
+Recommended: 200 (200Mb)
+CPL_VSIL_CURL_CACHE_SIZE
¶A global least-recently-used cache shared among all downloaded content and may be reused after a file handle has been closed and reopen
+Recommended: 200000000 (200Mb)
+VSI_CACHE
¶Setting this to TRUE
enables GDAL to use an internal caching mechanism. It's
Recommended (Strongly): TRUE.
+VSI_CACHE_SIZE
¶The size of the above VSI cache in bytes per-file handle. If you open a VRT with 10 files and your VSI_CACHE_SIZE is 10 bytes, the total cache memory usage would be 100 bytes. +The cache is RAM based and the content of the cache is discarded when the file handle is closed.
+Recommended: 5000000 (5Mb per file handle)
+GDAL_BAND_BLOCK_CACHE
¶GDAL Block Cache type: ARRAY
or HASHSET
. See gdal.org/development/rfc/rfc26_blockcache.html
PROJ_NETWORK
¶Introduced with GDAL 3 and PROJ>7, the PROJ library can fetch more precise transformation grids hosted on the cloud.
+Values: ON/OFF
+Ref: proj.org/usage/network.html
+GDAL_HTTP_MULTIPLEX
¶When set to YES
, this attempts to download multiple range requests in
+parallel, reusing the same TCP connection. Note this is only possible when the
+server supports HTTP2, which many servers don't yet support. There's no
+downside to setting YES
here.
GDAL_DATA
¶The GDAL_DATA
variable tells rasterio/GDAL where the GDAL C libraries have been installed. When using rasterio wheels, GDAL_DATA must be unset.
PROJ_LIB
¶The PROJ_LIB
variable tells rasterio/GDAL where the PROJ C libraries have been installed. When using rasterio wheels, PROJ_LIB must be unset.
AWS_REQUEST_PAYER
¶CPL_VSIL_CURL_ALLOWED_EXTENSIONS=".tif,.TIF,.tiff"
In addition to GDAL_DISABLE_READDIR_ON_OPEN
, we set the allowed extensions to .tif
to only enable tif files. (OPTIONAL)
GDAL_CACHEMAX="200"
200 Mb Cache.
+CPL_VSIL_CURL_CACHE_SIZE="200000000
200 Mb VSI Cache.
+GDAL_BAND_BLOCK_CACHE="HASHSET"
GDAL_DISABLE_READDIR_ON_OPEN="EMPTY_DIR"
Maybe the most important variable. Setting it to EMPTY_DIR
reduce the number of GET/LIST requests.
GDAL_HTTP_MERGE_CONSECUTIVE_RANGES="YES"
Tells GDAL to merge consecutive range GET requests.
+GDAL_HTTP_MULTIPLEX="YES"
GDAL_HTTP_VERSION="2"
Both Multiplex and HTTP_VERSION will only have impact if the files are stored in an environment which support HTTP 2 (e.g cloudfront).
+VSI_CACHE="TRUE"
VSI_CACHE_SIZE="5000000"
5Mb cache per file handle.
+ + + + + + + +When using Titiler to visualize imagery, there are some helper options that change how the data appears on the screen. You can:
+Color maps are arrays of colors, used to map pixel values to specific colors. For example, it is possible to map a single band DEM, where pixel values denote height, to a color map which shows higher values as white:
+ +Titiler supports both default colormaps (each with a name) and custom color maps.
+Default colormaps pre-made, each with a given name. These maps come from the rio-tiler
library, which has taken colormaps packaged with Matplotlib and has added others that are commonly used with raster data.
A list of available color maps can be found in Titiler's Swagger docs, or in the rio-tiler documentation.
+To use a default colormap, simply use the parameter colormap_name
:
import requests
+
+resp = requests.get("titiler.xyz/cog/preview", params={
+ "url": "<YOUR COG HERE>",
+ "colormap_name": "<YOUR COLORMAP NAME HERE>" # e.g. autumn_r
+})
+
You can take any of the colormaps listed on rio-tiler
, and add _r
to reverse it.
If you'd like to specify your own colormap, you can specify your own using an encoded JSON:
+import requests
+
+response = requests.get(
+ f"titiler.xyz/cog/preview",
+ params={
+ "url": "<YOUR COG HERE>",
+ "bidx": "1",
+ "colormap": {
+ "0": "#e5f5f9",
+ "10": "#99d8c9",
+ "255": "#2ca25f",
+ }
+ }
+)
+
Titiler supports colormaps that are both discrete (where pixels will be one of the colors that you specify) and linear (where pixel colors will blend between the given colors).
+For more information, please check out rio-tiler's docs.
+It is also possible to add a colormap dependency to automatically apply +a default colormap.
+Color formulae are simple commands that apply color corrections to images. This is useful for reducing artefacts like atmospheric haze, dark shadows, or muted colors.
+Titiler supports color formulae as defined in Mapbox's rio-color
plugin. These include the operations (taken from the rio-color
docs):
Gamma adjustment adjusts RGB values according to a power law, effectively brightening or darkening the midtones. It can be very effective in satellite imagery for reducing atmospheric haze in the blue and green bands.
+Sigmoidal contrast adjustment can alter the contrast and brightness of an image in a way that matches human's non-linear visual perception. It works well to increase contrast without blowing out the very dark shadows or already-bright parts of the image.
+Saturation can be thought of as the "colorfulness" of a pixel. Highly saturated colors are intense and almost cartoon-like, low saturation is more muted, closer to black and white. You can adjust saturation independently of brightness and hue but the data must be transformed into a different color space.
+In Titiler, color_formulae are applied through the color_formula
parameter as a string. An example of this option in action:
import requests
+
+response = requests.get(
+ f"titiler.xyz/cog/preview",
+ params={
+ "url": "<YOUR COG HERE>",
+ "color_formula": "gamma rg 1.3, sigmoidal rgb 22 0.1, saturation 1.5"
+ }
+)
+
Rescaling is the act of adjusting the minimum and maximum values when rendering an image. In an image with a single band, the rescaled minimum value will be set to black, and the rescaled maximum value will be set to white. This is useful if you want to accentuate features that only appear at a certain pixel value (e.g. you have a DEM, but you want to highlight how the terrain changes between sea level and 100m).
+Titiler supports rescaling on a per-band basis, using the rescaling
parameter. The input is a list of comma-delimited min-max ranges (e.g. ["0,100", "100,200", "0,1000]).
import requests
+
+response = requests.get(
+ f"titiler.xyz/cog/preview",
+ params={
+ "url": "<YOUR COG HERE>",
+ "rescaling": ["0,100", "0,1000", "0,10000"]
+ }
+)
+
By default, Titiler will rescale the bands using the min/max values of the input datatype. For example, PNG images 8- or 16-bit unsigned pixels, +giving a possible range of 0 to 255 or 0 to 65,536, so Titiler will use these ranges to rescale to the output format.
+For certain datasets (e.g. DEMs) this default behaviour can make the image seem washed out (or even entirely one color), +so if you see this happen look into rescaling your images to something that makes sense for your data.
+It is also possible to add a rescaling dependency to automatically apply +a default rescale.
+ + + + + + + +Tiler factories are helper functions that let users create a FastAPI router (fastapi.APIRouter
) with a minimal set of endpoints.
titiler.core.factory.TilerFactory
¶from fastapi import FastAPI
+
+from titiler.core.factory import TilerFactory
+
+app = FastAPI(description="A lightweight Cloud Optimized GeoTIFF tile server")
+cog = TilerFactory()
+app.include_router(cog.router, tags=["Cloud Optimized GeoTIFF"])
+
Method | +URL | +Output | +Description | +
---|---|---|---|
GET |
+/bounds |
+JSON (Bounds) | +return dataset's bounds | +
GET |
+/info |
+JSON (Info) | +return dataset's basic info | +
GET |
+/info.geojson |
+GeoJSON (InfoGeoJSON) | +return dataset's basic info as a GeoJSON feature | +
GET |
+/statistics |
+JSON (Statistics) | +return dataset's statistics | +
POST |
+/statistics |
+GeoJSON (Statistics) | +return dataset's statistics for a GeoJSON | +
GET |
+/tiles[/{tileMatrixSetId}]/{z}/{x}/{y}[@{scale}x][.{format}] |
+image/bin | +create a web map tile image from a dataset | +
GET |
+[/{tileMatrixSetId}]/tilejson.json |
+JSON (TileJSON) | +return a Mapbox TileJSON document | +
GET |
+[/{tileMatrixSetId}]/WMTSCapabilities.xml |
+XML | +return OGC WMTS Get Capabilities | +
GET |
+/point/{lon},{lat} |
+JSON (Point) | +return pixel values from a dataset | +
GET |
+/preview[.{format}] |
+image/bin | +create a preview image from a dataset (Optional) | +
GET |
+/crop/{minx},{miny},{maxx},{maxy}[/{width}x{height}].{format} |
+image/bin | +create an image from part of a dataset (Optional) | +
POST |
+/crop[/{width}x{height}][.{format}] |
+image/bin | +create an image from a GeoJSON feature (Optional) | +
GET |
+/map |
+HTML | +return a simple map viewer | +
GET |
+[/{tileMatrixSetId}]/map |
+HTML | +return a simple map viewer | +
titiler.core.factory.MultiBaseTilerFactory
¶Custom TilerFactory
to be used with rio_tiler.io.MultiBaseReader
type readers.
from fastapi import FastAPI
+from rio_tiler.io import STACReader # rio_tiler.io.STACReader is a MultiBaseReader
+
+from titiler.core.factory import MultiBaseTilerFactory
+
+app = FastAPI(description="A lightweight STAC tile server")
+cog = MultiBaseTilerFactory(reader=STACReader)
+app.include_router(cog.router, tags=["STAC"])
+
Method | +URL | +Output | +Description | +
---|---|---|---|
GET |
+/bounds |
+JSON (Bounds) | +return dataset's bounds | +
GET |
+/assets |
+JSON | +return the list of available assets | +
GET |
+/info |
+JSON (Info) | +return assets basic info | +
GET |
+/info.geojson |
+GeoJSON (InfoGeoJSON) | +return assets basic info as a GeoJSON feature | +
GET |
+/asset_statistics |
+JSON (Statistics) | +return per asset statistics | +
GET |
+/statistics |
+JSON (Statistics) | +return assets statistics (merged) | +
POST |
+/statistics |
+GeoJSON (Statistics) | +return assets statistics for a GeoJSON (merged) | +
GET |
+/tiles[/{tileMatrixSetId}]/{z}/{x}/{y}[@{scale}x][.{format}] |
+image/bin | +create a web map tile image from assets | +
GET |
+/[{tileMatrixSetId}]/tilejson.json |
+JSON (TileJSON) | +return a Mapbox TileJSON document | +
GET |
+/{tileMatrixSetId}/WMTSCapabilities.xml |
+XML | +return OGC WMTS Get Capabilities | +
GET |
+/point/{lon},{lat} |
+JSON (Point) | +return pixel values from assets | +
GET |
+/preview[.{format}] |
+image/bin | +create a preview image from assets (Optional) | +
GET |
+/crop/{minx},{miny},{maxx},{maxy}[/{width}x{height}].{format} |
+image/bin | +create an image from part of assets (Optional) | +
POST |
+/crop[/{width}x{height}][.{format}] |
+image/bin | +create an image from a geojson feature intersecting assets (Optional) | +
GET |
+[/{tileMatrixSetId}]/map |
+HTML | +return a simple map viewer | +
titiler.core.factory.MultiBandTilerFactory
¶Custom TilerFactory
to be used with rio_tiler.io.MultiBandReader
type readers.
from fastapi import FastAPI, Query
+from rio_tiler_pds.landsat.aws import LandsatC2Reader # rio_tiler_pds.landsat.aws.LandsatC2Reader is a MultiBandReader
+
+from titiler.core.factory import MultiBandTilerFactory
+
+
+def SceneIDParams(sceneid: str = Query(..., description="Landsat Scene ID")) -> str:
+ """Use `sceneid` in query instead of url."""
+ return sceneid
+
+
+app = FastAPI(description="A lightweight Landsat Collection 2 tile server")
+cog = MultiBandTilerFactory(reader=LandsatC2Reader, path_dependency=SceneIDParams)
+app.include_router(cog.router, tags=["Landsat"])
+
Method | +URL | +Output | +Description | +
---|---|---|---|
GET |
+/bounds |
+JSON (Bounds) | +return dataset's bounds | +
GET |
+/bands |
+JSON | +return the list of available bands | +
GET |
+/info |
+JSON (Info) | +return basic info for a dataset | +
GET |
+/info.geojson |
+GeoJSON (InfoGeoJSON) | +return basic info for a dataset as a GeoJSON feature | +
GET |
+/statistics |
+JSON (Statistics) | +return info and statistics for a dataset | +
POST |
+/statistics |
+GeoJSON (Statistics) | +return info and statistics for a dataset | +
GET |
+/tiles[/{tileMatrixSetId}]/{z}/{x}/{y}[@{scale}x][.{format}] |
+image/bin | +create a web map tile image from a dataset | +
GET |
+/[{tileMatrixSetId}]/tilejson.json |
+JSON (TileJSON) | +return a Mapbox TileJSON document | +
GET |
+/{tileMatrixSetId}/WMTSCapabilities.xml |
+XML | +return OGC WMTS Get Capabilities | +
GET |
+/point/{lon},{lat} |
+JSON (Point) | +return pixel value from a dataset | +
GET |
+/preview[.{format}] |
+image/bin | +create a preview image from a dataset | +
GET |
+/crop/{minx},{miny},{maxx},{maxy}[/{width}x{height}].{format} |
+image/bin | +create an image from part of a dataset | +
POST |
+/crop[/{width}x{height}][.{format}] |
+image/bin | +create an image from a geojson feature | +
GET |
+[/{tileMatrixSetId}]/map |
+HTML | +return a simple map viewer | +
titiler.mosaic.factory.MosaicTilerFactory
¶Method | +URL | +Output | +Description | +
---|---|---|---|
GET |
+/ |
+JSON MosaicJSON | +return a MosaicJSON document | +
GET |
+/bounds |
+JSON (Bounds) | +return mosaic's bounds | +
GET |
+/info |
+JSON (Info) | +return mosaic's basic info | +
GET |
+/info.geojson |
+GeoJSON (InfoGeoJSON) | +return mosaic's basic info as a GeoJSON feature | +
GET |
+/tiles[/{tileMatrixSetId}]/{z}/{x}/{y}[@{scale}x][.{format}] |
+image/bin | +create a web map tile image from a MosaicJSON | +
GET |
+[/{tileMatrixSetId}]/tilejson.json |
+JSON (TileJSON) | +return a Mapbox TileJSON document | +
GET |
+[/{tileMatrixSetId}]/WMTSCapabilities.xml |
+XML | +return OGC WMTS Get Capabilities | +
GET |
+/point/{lon},{lat} |
+JSON (Point) | +return pixel value from a MosaicJSON dataset | +
GET |
+/{z}/{x}/{y}/assets |
+JSON | +return list of assets intersecting a XYZ tile | +
GET |
+/{lon},{lat}/assets |
+JSON | +return list of assets intersecting a point | +
GET |
+/{minx},{miny},{maxx},{maxy}/assets |
+JSON | +return list of assets intersecting a bounding box | +
GET |
+[/{tileMatrixSetId}]/map |
+HTML | +return a simple map viewer | +
Important
+Factories are built around rio_tiler.io.BaseReader
, which defines basic methods to access datasets (e.g COG or STAC). The default reader is COGReader
for TilerFactory
and MosaicBackend
for MosaicTilerFactory
.
Factories classes use dependencies injection to define most of the endpoint options.
+Common dependency.
+RescaleType
+
def ColorMapParams(
+ colormap_name: typing_extensions.Annotated[Union[titiler.core.dependencies.ColorMapName, NoneType], Query(PydanticUndefined)] = None,
+ colormap: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None
+) -> Union[Dict[int, Tuple[int, int, int, int]], Sequence[Tuple[Tuple[Union[float, int], Union[float, int]], Tuple[int, int, int, int]]], NoneType]
+
Colormap Dependency.
+def CoordCRSParams(
+ crs: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None
+) -> Union[rasterio.crs.CRS, NoneType]
+
Coordinate Reference System Coordinates Param.
+def DatasetPathParams(
+ url: typing_extensions.Annotated[str, Query(PydanticUndefined)]
+) -> str
+
Create dataset path from args
+def DstCRSParams(
+ crs: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None
+) -> Union[rasterio.crs.CRS, NoneType]
+
Coordinate Reference System Coordinates Param.
+def RescalingParams(
+ rescale: typing_extensions.Annotated[Union[List[str], NoneType], Query(PydanticUndefined)] = None
+) -> Union[List[Tuple[float, ...]], NoneType]
+
Min/Max data Rescaling
+class AssetsBidxExprParams(
+ assets: typing_extensions.Annotated[Union[List[str], NoneType], Query(PydanticUndefined)] = None,
+ expression: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None,
+ asset_indexes: typing_extensions.Annotated[Union[Sequence[str], NoneType], Query(PydanticUndefined)] = None,
+ asset_as_band: typing_extensions.Annotated[Union[bool, NoneType], Query(PydanticUndefined)] = None
+)
+
Assets, Expression and Asset's band Indexes parameters.
+asset_as_band
+
asset_indexes
+
assets
+
expression
+
def keys(
+ self
+)
+
Return Keys.
+class AssetsBidxExprParamsOptional(
+ assets: typing_extensions.Annotated[Union[List[str], NoneType], Query(PydanticUndefined)] = None,
+ expression: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None,
+ asset_indexes: typing_extensions.Annotated[Union[Sequence[str], NoneType], Query(PydanticUndefined)] = None,
+ asset_as_band: typing_extensions.Annotated[Union[bool, NoneType], Query(PydanticUndefined)] = None
+)
+
Assets, Expression and Asset's band Indexes parameters but with no requirement.
+asset_as_band
+
asset_indexes
+
assets
+
expression
+
def keys(
+ self
+)
+
Return Keys.
+class AssetsBidxParams(
+ assets: typing_extensions.Annotated[Union[List[str], NoneType], Query(PydanticUndefined)] = None,
+ asset_indexes: typing_extensions.Annotated[Union[Sequence[str], NoneType], Query(PydanticUndefined)] = None,
+ asset_expression: typing_extensions.Annotated[Union[Sequence[str], NoneType], Query(PydanticUndefined)] = None
+)
+
Assets, Asset's band Indexes and Asset's band Expression parameters.
+asset_expression
+
asset_indexes
+
assets
+
def keys(
+ self
+)
+
Return Keys.
+class AssetsParams(
+ assets: typing_extensions.Annotated[Union[List[str], NoneType], Query(PydanticUndefined)] = None
+)
+
Assets parameters.
+assets
+
def keys(
+ self
+)
+
Return Keys.
+class BandsExprParams(
+ bands: typing_extensions.Annotated[Union[List[str], NoneType], Query(PydanticUndefined)] = None,
+ expression: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None
+)
+
Band names and Expression parameters (Band or Expression required).
+bands
+
expression
+
def keys(
+ self
+)
+
Return Keys.
+class BandsExprParamsOptional(
+ bands: typing_extensions.Annotated[Union[List[str], NoneType], Query(PydanticUndefined)] = None,
+ expression: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None
+)
+
Optional Band names and Expression parameters.
+bands
+
expression
+
def keys(
+ self
+)
+
Return Keys.
+class BandsParams(
+ bands: typing_extensions.Annotated[Union[List[str], NoneType], Query(PydanticUndefined)] = None
+)
+
Band names parameters.
+bands
+
def keys(
+ self
+)
+
Return Keys.
+class BidxExprParams(
+ indexes: typing_extensions.Annotated[Union[List[int], NoneType], Query(PydanticUndefined)] = None,
+ expression: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None
+)
+
Band Indexes and Expression parameters.
+expression
+
indexes
+
def keys(
+ self
+)
+
Return Keys.
+class BidxParams(
+ indexes: typing_extensions.Annotated[Union[List[int], NoneType], Query(PydanticUndefined)] = None
+)
+
Band Indexes parameters.
+indexes
+
def keys(
+ self
+)
+
Return Keys.
+class ColorMapName(
+ /,
+ *args,
+ **kwargs
+)
+
An enumeration.
+accent
+
accent_r
+
afmhot
+
afmhot_r
+
autumn
+
autumn_r
+
binary
+
binary_r
+
blues
+
blues_r
+
bone
+
bone_r
+
brbg
+
brbg_r
+
brg
+
brg_r
+
bugn
+
bugn_r
+
bupu
+
bupu_r
+
bwr
+
bwr_r
+
cfastie
+
cividis
+
cividis_r
+
cmrmap
+
cmrmap_r
+
cool
+
cool_r
+
coolwarm
+
coolwarm_r
+
copper
+
copper_r
+
cubehelix
+
cubehelix_r
+
dark2
+
dark2_r
+
flag
+
flag_r
+
gist_earth
+
gist_earth_r
+
gist_gray
+
gist_gray_r
+
gist_heat
+
gist_heat_r
+
gist_ncar
+
gist_ncar_r
+
gist_rainbow
+
gist_rainbow_r
+
gist_stern
+
gist_stern_r
+
gist_yarg
+
gist_yarg_r
+
gnbu
+
gnbu_r
+
gnuplot
+
gnuplot2
+
gnuplot2_r
+
gnuplot_r
+
gray
+
gray_r
+
greens
+
greens_r
+
greys
+
greys_r
+
hot
+
hot_r
+
hsv
+
hsv_r
+
inferno
+
inferno_r
+
jet
+
jet_r
+
magma
+
magma_r
+
name
+
nipy_spectral
+
nipy_spectral_r
+
ocean
+
ocean_r
+
oranges
+
oranges_r
+
orrd
+
orrd_r
+
paired
+
paired_r
+
pastel1
+
pastel1_r
+
pastel2
+
pastel2_r
+
pink
+
pink_r
+
piyg
+
piyg_r
+
plasma
+
plasma_r
+
prgn
+
prgn_r
+
prism
+
prism_r
+
pubu
+
pubu_r
+
pubugn
+
pubugn_r
+
puor
+
puor_r
+
purd
+
purd_r
+
purples
+
purples_r
+
rainbow
+
rainbow_r
+
rdbu
+
rdbu_r
+
rdgy
+
rdgy_r
+
rdpu
+
rdpu_r
+
rdylbu
+
rdylbu_r
+
rdylgn
+
rdylgn_r
+
reds
+
reds_r
+
rplumbo
+
schwarzwald
+
seismic
+
seismic_r
+
set1
+
set1_r
+
set2
+
set2_r
+
set3
+
set3_r
+
spectral
+
spectral_r
+
spring
+
spring_r
+
summer
+
summer_r
+
tab10
+
tab10_r
+
tab20
+
tab20_r
+
tab20b
+
tab20b_r
+
tab20c
+
tab20c_r
+
terrain
+
terrain_r
+
twilight
+
twilight_r
+
twilight_shifted
+
twilight_shifted_r
+
value
+
viridis
+
viridis_r
+
winter
+
winter_r
+
wistia
+
wistia_r
+
ylgn
+
ylgn_r
+
ylgnbu
+
ylgnbu_r
+
ylorbr
+
ylorbr_r
+
ylorrd
+
ylorrd_r
+
class DatasetParams(
+ nodata: typing_extensions.Annotated[Union[str, int, float, NoneType], Query(PydanticUndefined)] = None,
+ unscale: typing_extensions.Annotated[Union[bool, NoneType], Query(PydanticUndefined)] = False,
+ resampling_method: typing_extensions.Annotated[Literal['nearest', 'bilinear', 'cubic', 'cubic_spline', 'lanczos', 'average', 'mode', 'gauss', 'rms'], Query(PydanticUndefined)] = 'nearest'
+)
+
Low level WarpedVRT Optional parameters.
+nodata
+
resampling_method
+
unscale
+
def keys(
+ self
+)
+
Return Keys.
+class DefaultDependency(
+
+)
+
Dataclass with dict unpacking
+def keys(
+ self
+)
+
Return Keys.
+class ExpressionParams(
+ expression: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None
+)
+
Expression parameters.
+expression
+
def keys(
+ self
+)
+
Return Keys.
+class HistogramParams(
+ bins: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None,
+ range: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None
+)
+
Numpy Histogram options.
+bins
+
range
+
def keys(
+ self
+)
+
Return Keys.
+class ImageParams(
+ max_size: typing_extensions.Annotated[int, 'Maximum image size to read onto.'] = 1024,
+ height: typing_extensions.Annotated[Union[int, NoneType], 'Force output image height.'] = None,
+ width: typing_extensions.Annotated[Union[int, NoneType], 'Force output image width.'] = None
+)
+
Common Preview/Crop parameters.
+height
+
max_size
+
width
+
def keys(
+ self
+)
+
Return Keys.
+class ImageRenderingParams(
+ add_mask: typing_extensions.Annotated[bool, Query(PydanticUndefined)] = True
+)
+
Image Rendering options.
+add_mask
+
def keys(
+ self
+)
+
Return Keys.
+class StatisticsParams(
+ categorical: typing_extensions.Annotated[bool, Query(PydanticUndefined)] = False,
+ categories: typing_extensions.Annotated[Union[List[Union[float, int]], NoneType], Query(PydanticUndefined)] = None,
+ percentiles: typing_extensions.Annotated[Union[List[int], NoneType], Query(PydanticUndefined)] = None
+)
+
Statistics options.
+categorical
+
categories
+
percentiles
+
def keys(
+ self
+)
+
Return Keys.
+ + + + + + + +Titiler error classes.
+DEFAULT_STATUS_CODES
+
def add_exception_handlers(
+ app: fastapi.applications.FastAPI,
+ status_codes: Dict[Type[Exception], int]
+) -> None
+
Add exception handlers to the FastAPI app.
+def exception_handler_factory(
+ status_code: int
+) -> Callable
+
Create a FastAPI exception handler from a status code.
+class BadRequestError(
+ /,
+ *args,
+ **kwargs
+)
+
Bad request error.
+args
+
def with_traceback(
+ ...
+)
+
Exception.with_traceback(tb) --
+set self.traceback to tb and return self.
+class TileNotFoundError(
+ /,
+ *args,
+ **kwargs
+)
+
Tile not found error.
+args
+
def with_traceback(
+ ...
+)
+
Exception.with_traceback(tb) --
+set self.traceback to tb and return self.
+class TilerError(
+ /,
+ *args,
+ **kwargs
+)
+
Base exception class.
+args
+
def with_traceback(
+ ...
+)
+
Exception.with_traceback(tb) --
+set self.traceback to tb and return self.
+ + + + + + + +TiTiler Router factories.
+DEFAULT_TEMPLATES
+
WGS84_CRS
+
img_endpoint_params
+
class AlgorithmFactory(
+ supported_algorithm: titiler.core.algorithm.Algorithms = Algorithms(data={'hillshade': <class 'titiler.core.algorithm.dem.HillShade'>, 'contours': <class 'titiler.core.algorithm.dem.Contours'>, 'normalizedIndex': <class 'titiler.core.algorithm.index.NormalizedIndex'>, 'terrarium': <class 'titiler.core.algorithm.dem.Terrarium'>, 'terrainrgb': <class 'titiler.core.algorithm.dem.TerrainRGB'>}),
+ router: fastapi.routing.APIRouter = <factory>
+)
+
Algorithm endpoints Factory.
+supported_algorithm
+
class BaseTilerFactory(
+ reader: Type[rio_tiler.io.base.BaseReader],
+ router: fastapi.routing.APIRouter = <factory>,
+ path_dependency: Callable[..., Any] = <function DatasetPathParams at 0x7faa86c74b80>,
+ dataset_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.DatasetParams'>,
+ layer_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.BidxExprParams'>,
+ render_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.ImageRenderingParams'>,
+ colormap_dependency: Callable[..., Union[Dict[int, Tuple[int, int, int, int]], Sequence[Tuple[Tuple[Union[float, int], Union[float, int]], Tuple[int, int, int, int]]], NoneType]] = <function ColorMapParams at 0x7faa86ccdf70>,
+ rescale_dependency: Callable[..., Union[List[Tuple[float, ...]], NoneType]] = <function RescalingParams at 0x7faa82d69b80>,
+ process_dependency: Callable[..., Union[titiler.core.algorithm.base.BaseAlgorithm, NoneType]] = <function Algorithms.dependency.<locals>.post_process at 0x7faa7f6c2e50>,
+ reader_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.DefaultDependency'>,
+ environment_dependency: Callable[..., Dict] = <function BaseTilerFactory.<lambda> at 0x7faa7f6c2dc0>,
+ supported_tms: morecantile.defaults.TileMatrixSets = TileMatrixSets(tms={'CanadianNAD83_LCC': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/CanadianNAD83_LCC.json'), 'EuropeanETRS89_LAEAQuad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/EuropeanETRS89_LAEAQuad.json'), 'LINZAntarticaMapTilegrid': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/LINZAntarticaMapTilegrid.json'), 'NZTM2000Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/NZTM2000Quad.json'), 'UPSAntarcticWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UPSAntarcticWGS84Quad.json'), 'UPSArcticWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UPSArcticWGS84Quad.json'), 'UTM31WGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UTM31WGS84Quad.json'), 'WGS1984Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WGS1984Quad.json'), 'WebMercatorQuad': <TileMatrixSet title='Google Maps Compatible for the World' id='WebMercatorQuad' crs='http://www.opengis.net/def/crs/EPSG/0/3857>, 'WorldCRS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WorldCRS84Quad.json'), 'WorldMercatorWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WorldMercatorWGS84Quad.json')}),
+ default_tms: str = 'WebMercatorQuad',
+ router_prefix: str = '',
+ optional_headers: List[titiler.core.resources.enums.OptionalHeader] = <factory>,
+ route_dependencies: List[Tuple[List[titiler.core.routing.EndpointScope], List[fastapi.params.Depends]]] = <factory>,
+ extensions: List[titiler.core.factory.FactoryExtension] = <factory>,
+ templates: starlette.templating.Jinja2Templates = <starlette.templating.Jinja2Templates object at 0x7faa7f8e1b80>
+)
+
BaseTiler Factory.
+Abstract Base Class which defines most inputs used by dynamic tiler.
+Name | +Type | +Description | +Default | +
---|---|---|---|
reader | +rio_tiler.io.base.BaseReader | +A rio-tiler reader (e.g Reader). | +None | +
router | +fastapi.APIRouter | +Application router to register endpoints to. | +None | +
path_dependency | +Callable | +Endpoint dependency defining path to pass to the reader init. |
+None | +
dataset_dependency | +titiler.core.dependencies.DefaultDependency | +Endpoint dependency defining dataset overwriting options (e.g nodata). | +None | +
layer_dependency | +titiler.core.dependencies.DefaultDependency | +Endpoint dependency defining dataset indexes/bands/assets options. | +None | +
render_dependency | +titiler.core.dependencies.DefaultDependency | +Endpoint dependency defining image rendering options (e.g add_mask). | +None | +
colormap_dependency | +Callable | +Endpoint dependency defining ColorMap options (e.g colormap_name). | +None | +
process_dependency | +titiler.core.dependencies.DefaultDependency | +Endpoint dependency defining image post-processing options (e.g rescaling, color-formula). | +None | +
tms_dependency | +Callable | +Endpoint dependency defining TileMatrixSet to use. | +None | +
reader_dependency | +titiler.core.dependencies.DefaultDependency | +Endpoint dependency defining BaseReader options. | +None | +
environment_dependency | +Callable | +Endpoint dependency to define GDAL environment at runtime. | +None | +
router_prefix | +str | +prefix where the router will be mounted in the application. | +None | +
optional_headers | +sequence of titiler.core.resources.enums.OptionalHeader | +additional headers to return with the response. | +None | +
dataset_dependency
+
default_tms
+
layer_dependency
+
reader_dependency
+
render_dependency
+
router_prefix
+
supported_tms
+
templates
+
def add_route_dependencies(
+ self,
+ *,
+ scopes: List[titiler.core.routing.EndpointScope],
+ dependencies=typing.List[fastapi.params.Depends]
+)
+
Add dependencies to routes.
+Allows a developer to add dependencies to a route after the route has been defined.
+def colormap_dependency(
+ colormap_name: typing_extensions.Annotated[Union[titiler.core.dependencies.ColorMapName, NoneType], Query(PydanticUndefined)] = None,
+ colormap: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None
+) -> Union[Dict[int, Tuple[int, int, int, int]], Sequence[Tuple[Tuple[Union[float, int], Union[float, int]], Tuple[int, int, int, int]]], NoneType]
+
Colormap Dependency.
+def environment_dependency(
+
+)
+
def path_dependency(
+ url: typing_extensions.Annotated[str, Query(PydanticUndefined)]
+) -> str
+
Create dataset path from args
+def process_dependency(
+ algorithm: Literal['hillshade', 'contours', 'normalizedIndex', 'terrarium', 'terrainrgb'] = Query(None),
+ algorithm_params: str = Query(None)
+) -> Union[titiler.core.algorithm.base.BaseAlgorithm, NoneType]
+
Data Post-Processing options.
+def register_routes(
+ self
+)
+
Register Tiler Routes.
+def rescale_dependency(
+ rescale: typing_extensions.Annotated[Union[List[str], NoneType], Query(PydanticUndefined)] = None
+) -> Union[List[Tuple[float, ...]], NoneType]
+
Min/Max data Rescaling
+def url_for(
+ self,
+ request: starlette.requests.Request,
+ name: str,
+ **path_params: Any
+) -> str
+
Return full url (with prefix) for a specific endpoint.
+class FactoryExtension(
+
+)
+
Factory Extension.
+def register(
+ self,
+ factory: 'BaseTilerFactory'
+)
+
Register extension to the factory.
+class MultiBandTilerFactory(
+ reader: Type[rio_tiler.io.base.MultiBandReader] = <class 'rio_tiler.io.rasterio.Reader'>,
+ router: fastapi.routing.APIRouter = <factory>,
+ path_dependency: Callable[..., Any] = <function DatasetPathParams at 0x7faa86c74b80>,
+ dataset_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.DatasetParams'>,
+ layer_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.BandsExprParams'>,
+ render_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.ImageRenderingParams'>,
+ colormap_dependency: Callable[..., Union[Dict[int, Tuple[int, int, int, int]], Sequence[Tuple[Tuple[Union[float, int], Union[float, int]], Tuple[int, int, int, int]]], NoneType]] = <function ColorMapParams at 0x7faa86ccdf70>,
+ rescale_dependency: Callable[..., Union[List[Tuple[float, ...]], NoneType]] = <function RescalingParams at 0x7faa82d69b80>,
+ process_dependency: Callable[..., Union[titiler.core.algorithm.base.BaseAlgorithm, NoneType]] = <function Algorithms.dependency.<locals>.post_process at 0x7faa7f6c2e50>,
+ reader_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.DefaultDependency'>,
+ environment_dependency: Callable[..., Dict] = <function BaseTilerFactory.<lambda> at 0x7faa7f6c2dc0>,
+ supported_tms: morecantile.defaults.TileMatrixSets = TileMatrixSets(tms={'CanadianNAD83_LCC': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/CanadianNAD83_LCC.json'), 'EuropeanETRS89_LAEAQuad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/EuropeanETRS89_LAEAQuad.json'), 'LINZAntarticaMapTilegrid': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/LINZAntarticaMapTilegrid.json'), 'NZTM2000Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/NZTM2000Quad.json'), 'UPSAntarcticWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UPSAntarcticWGS84Quad.json'), 'UPSArcticWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UPSArcticWGS84Quad.json'), 'UTM31WGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UTM31WGS84Quad.json'), 'WGS1984Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WGS1984Quad.json'), 'WebMercatorQuad': <TileMatrixSet title='Google Maps Compatible for the World' id='WebMercatorQuad' crs='http://www.opengis.net/def/crs/EPSG/0/3857>, 'WorldCRS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WorldCRS84Quad.json'), 'WorldMercatorWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WorldMercatorWGS84Quad.json')}),
+ default_tms: str = 'WebMercatorQuad',
+ router_prefix: str = '',
+ optional_headers: List[titiler.core.resources.enums.OptionalHeader] = <factory>,
+ route_dependencies: List[Tuple[List[titiler.core.routing.EndpointScope], List[fastapi.params.Depends]]] = <factory>,
+ extensions: List[titiler.core.factory.FactoryExtension] = <factory>,
+ templates: starlette.templating.Jinja2Templates = <starlette.templating.Jinja2Templates object at 0x7faa7f8e1b80>,
+ stats_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.StatisticsParams'>,
+ histogram_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.HistogramParams'>,
+ img_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.ImageParams'>,
+ add_preview: bool = True,
+ add_part: bool = True,
+ add_viewer: bool = True,
+ bands_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.BandsParams'>
+)
+
Custom Tiler Factory for MultiBandReader classes.
+Note:
+ To be able to use the rio_tiler.io.MultiBandReader we need to be able to pass a bands
+ argument to most of its methods. By using the BandsExprParams
for the layer_dependency
, the
+ .tile(), .point(), .preview() and the .part() methods will receive bands or expression arguments.
The rio_tiler.io.MultiBandReader `.info()` and `.metadata()` have `bands` as
+a requirement arguments (https://github.com/cogeotiff/rio-tiler/blob/main/rio_tiler/io/base.py#L775).
+This means we have to update the /info and /metadata endpoints in order to add the `bands` dependency.
+
+For implementation example see https://github.com/developmentseed/titiler-pds
+
add_part
+
add_preview
+
add_viewer
+
bands_dependency
+
dataset_dependency
+
default_tms
+
histogram_dependency
+
img_dependency
+
layer_dependency
+
reader
+
reader_dependency
+
render_dependency
+
router_prefix
+
stats_dependency
+
supported_tms
+
templates
+
def add_route_dependencies(
+ self,
+ *,
+ scopes: List[titiler.core.routing.EndpointScope],
+ dependencies=typing.List[fastapi.params.Depends]
+)
+
Add dependencies to routes.
+Allows a developer to add dependencies to a route after the route has been defined.
+def bounds(
+ self
+)
+
Register /bounds endpoint.
+def colormap_dependency(
+ colormap_name: typing_extensions.Annotated[Union[titiler.core.dependencies.ColorMapName, NoneType], Query(PydanticUndefined)] = None,
+ colormap: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None
+) -> Union[Dict[int, Tuple[int, int, int, int]], Sequence[Tuple[Tuple[Union[float, int], Union[float, int]], Tuple[int, int, int, int]]], NoneType]
+
Colormap Dependency.
+def environment_dependency(
+
+)
+
def info(
+ self
+)
+
Register /info endpoint.
+def map_viewer(
+ self
+)
+
Register /map endpoint.
+def part(
+ self
+)
+
Register /crop endpoint.
+def path_dependency(
+ url: typing_extensions.Annotated[str, Query(PydanticUndefined)]
+) -> str
+
Create dataset path from args
+def point(
+ self
+)
+
Register /point endpoints.
+def preview(
+ self
+)
+
Register /preview endpoint.
+def process_dependency(
+ algorithm: Literal['hillshade', 'contours', 'normalizedIndex', 'terrarium', 'terrainrgb'] = Query(None),
+ algorithm_params: str = Query(None)
+) -> Union[titiler.core.algorithm.base.BaseAlgorithm, NoneType]
+
Data Post-Processing options.
+def register_routes(
+ self
+)
+
This Method register routes to the router.
+Because we wrap the endpoints in a class we cannot define the routes as +methods (because of the self argument). The HACK is to define routes inside +the class method and register them after the class initialization.
+def rescale_dependency(
+ rescale: typing_extensions.Annotated[Union[List[str], NoneType], Query(PydanticUndefined)] = None
+) -> Union[List[Tuple[float, ...]], NoneType]
+
Min/Max data Rescaling
+def statistics(
+ self
+)
+
add statistics endpoints.
+def tile(
+ self
+)
+
Register /tiles endpoint.
+def tilejson(
+ self
+)
+
Register /tilejson.json endpoint.
+def url_for(
+ self,
+ request: starlette.requests.Request,
+ name: str,
+ **path_params: Any
+) -> str
+
Return full url (with prefix) for a specific endpoint.
+def wmts(
+ self
+)
+
Register /wmts endpoint.
+class MultiBaseTilerFactory(
+ reader: Type[rio_tiler.io.base.MultiBaseReader] = <class 'rio_tiler.io.rasterio.Reader'>,
+ router: fastapi.routing.APIRouter = <factory>,
+ path_dependency: Callable[..., Any] = <function DatasetPathParams at 0x7faa86c74b80>,
+ dataset_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.DatasetParams'>,
+ layer_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.AssetsBidxExprParams'>,
+ render_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.ImageRenderingParams'>,
+ colormap_dependency: Callable[..., Union[Dict[int, Tuple[int, int, int, int]], Sequence[Tuple[Tuple[Union[float, int], Union[float, int]], Tuple[int, int, int, int]]], NoneType]] = <function ColorMapParams at 0x7faa86ccdf70>,
+ rescale_dependency: Callable[..., Union[List[Tuple[float, ...]], NoneType]] = <function RescalingParams at 0x7faa82d69b80>,
+ process_dependency: Callable[..., Union[titiler.core.algorithm.base.BaseAlgorithm, NoneType]] = <function Algorithms.dependency.<locals>.post_process at 0x7faa7f6c2e50>,
+ reader_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.DefaultDependency'>,
+ environment_dependency: Callable[..., Dict] = <function BaseTilerFactory.<lambda> at 0x7faa7f6c2dc0>,
+ supported_tms: morecantile.defaults.TileMatrixSets = TileMatrixSets(tms={'CanadianNAD83_LCC': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/CanadianNAD83_LCC.json'), 'EuropeanETRS89_LAEAQuad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/EuropeanETRS89_LAEAQuad.json'), 'LINZAntarticaMapTilegrid': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/LINZAntarticaMapTilegrid.json'), 'NZTM2000Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/NZTM2000Quad.json'), 'UPSAntarcticWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UPSAntarcticWGS84Quad.json'), 'UPSArcticWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UPSArcticWGS84Quad.json'), 'UTM31WGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UTM31WGS84Quad.json'), 'WGS1984Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WGS1984Quad.json'), 'WebMercatorQuad': <TileMatrixSet title='Google Maps Compatible for the World' id='WebMercatorQuad' crs='http://www.opengis.net/def/crs/EPSG/0/3857>, 'WorldCRS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WorldCRS84Quad.json'), 'WorldMercatorWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WorldMercatorWGS84Quad.json')}),
+ default_tms: str = 'WebMercatorQuad',
+ router_prefix: str = '',
+ optional_headers: List[titiler.core.resources.enums.OptionalHeader] = <factory>,
+ route_dependencies: List[Tuple[List[titiler.core.routing.EndpointScope], List[fastapi.params.Depends]]] = <factory>,
+ extensions: List[titiler.core.factory.FactoryExtension] = <factory>,
+ templates: starlette.templating.Jinja2Templates = <starlette.templating.Jinja2Templates object at 0x7faa7f8e1b80>,
+ stats_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.StatisticsParams'>,
+ histogram_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.HistogramParams'>,
+ img_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.ImageParams'>,
+ add_preview: bool = True,
+ add_part: bool = True,
+ add_viewer: bool = True,
+ assets_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.AssetsParams'>
+)
+
Custom Tiler Factory for MultiBaseReader classes.
+Note:
+ To be able to use the rio_tiler.io.MultiBaseReader we need to be able to pass a assets
+ argument to most of its methods. By using the AssetsBidxExprParams
for the layer_dependency
, the
+ .tile(), .point(), .preview() and the .part() methods will receive assets, expression or indexes arguments.
The rio_tiler.io.MultiBaseReader `.info()` and `.metadata()` have `assets` as
+a requirement arguments (https://github.com/cogeotiff/rio-tiler/blob/main/rio_tiler/io/base.py#L365).
+This means we have to update the /info and /metadata endpoints in order to add the `assets` dependency.
+
add_part
+
add_preview
+
add_viewer
+
assets_dependency
+
dataset_dependency
+
default_tms
+
histogram_dependency
+
img_dependency
+
layer_dependency
+
reader
+
reader_dependency
+
render_dependency
+
router_prefix
+
stats_dependency
+
supported_tms
+
templates
+
def add_route_dependencies(
+ self,
+ *,
+ scopes: List[titiler.core.routing.EndpointScope],
+ dependencies=typing.List[fastapi.params.Depends]
+)
+
Add dependencies to routes.
+Allows a developer to add dependencies to a route after the route has been defined.
+def bounds(
+ self
+)
+
Register /bounds endpoint.
+def colormap_dependency(
+ colormap_name: typing_extensions.Annotated[Union[titiler.core.dependencies.ColorMapName, NoneType], Query(PydanticUndefined)] = None,
+ colormap: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None
+) -> Union[Dict[int, Tuple[int, int, int, int]], Sequence[Tuple[Tuple[Union[float, int], Union[float, int]], Tuple[int, int, int, int]]], NoneType]
+
Colormap Dependency.
+def environment_dependency(
+
+)
+
def info(
+ self
+)
+
Register /info endpoint.
+def map_viewer(
+ self
+)
+
Register /map endpoint.
+def part(
+ self
+)
+
Register /crop endpoint.
+def path_dependency(
+ url: typing_extensions.Annotated[str, Query(PydanticUndefined)]
+) -> str
+
Create dataset path from args
+def point(
+ self
+)
+
Register /point endpoints.
+def preview(
+ self
+)
+
Register /preview endpoint.
+def process_dependency(
+ algorithm: Literal['hillshade', 'contours', 'normalizedIndex', 'terrarium', 'terrainrgb'] = Query(None),
+ algorithm_params: str = Query(None)
+) -> Union[titiler.core.algorithm.base.BaseAlgorithm, NoneType]
+
Data Post-Processing options.
+def register_routes(
+ self
+)
+
This Method register routes to the router.
+Because we wrap the endpoints in a class we cannot define the routes as +methods (because of the self argument). The HACK is to define routes inside +the class method and register them after the class initialization.
+def rescale_dependency(
+ rescale: typing_extensions.Annotated[Union[List[str], NoneType], Query(PydanticUndefined)] = None
+) -> Union[List[Tuple[float, ...]], NoneType]
+
Min/Max data Rescaling
+def statistics(
+ self
+)
+
Register /statistics endpoint.
+def tile(
+ self
+)
+
Register /tiles endpoint.
+def tilejson(
+ self
+)
+
Register /tilejson.json endpoint.
+def url_for(
+ self,
+ request: starlette.requests.Request,
+ name: str,
+ **path_params: Any
+) -> str
+
Return full url (with prefix) for a specific endpoint.
+def wmts(
+ self
+)
+
Register /wmts endpoint.
+class TMSFactory(
+ supported_tms: morecantile.defaults.TileMatrixSets = TileMatrixSets(tms={'CanadianNAD83_LCC': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/CanadianNAD83_LCC.json'), 'EuropeanETRS89_LAEAQuad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/EuropeanETRS89_LAEAQuad.json'), 'LINZAntarticaMapTilegrid': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/LINZAntarticaMapTilegrid.json'), 'NZTM2000Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/NZTM2000Quad.json'), 'UPSAntarcticWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UPSAntarcticWGS84Quad.json'), 'UPSArcticWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UPSArcticWGS84Quad.json'), 'UTM31WGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UTM31WGS84Quad.json'), 'WGS1984Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WGS1984Quad.json'), 'WebMercatorQuad': <TileMatrixSet title='Google Maps Compatible for the World' id='WebMercatorQuad' crs='http://www.opengis.net/def/crs/EPSG/0/3857>, 'WorldCRS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WorldCRS84Quad.json'), 'WorldMercatorWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WorldMercatorWGS84Quad.json')}),
+ router: fastapi.routing.APIRouter = <factory>,
+ router_prefix: str = ''
+)
+
TileMatrixSet endpoints Factory.
+router_prefix
+
supported_tms
+
def register_routes(
+ self
+)
+
Register TMS endpoint routes.
+def url_for(
+ self,
+ request: starlette.requests.Request,
+ name: str,
+ **path_params: Any
+) -> str
+
Return full url (with prefix) for a specific endpoint.
+class TilerFactory(
+ reader: Type[rio_tiler.io.base.BaseReader] = <class 'rio_tiler.io.rasterio.Reader'>,
+ router: fastapi.routing.APIRouter = <factory>,
+ path_dependency: Callable[..., Any] = <function DatasetPathParams at 0x7faa86c74b80>,
+ dataset_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.DatasetParams'>,
+ layer_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.BidxExprParams'>,
+ render_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.ImageRenderingParams'>,
+ colormap_dependency: Callable[..., Union[Dict[int, Tuple[int, int, int, int]], Sequence[Tuple[Tuple[Union[float, int], Union[float, int]], Tuple[int, int, int, int]]], NoneType]] = <function ColorMapParams at 0x7faa86ccdf70>,
+ rescale_dependency: Callable[..., Union[List[Tuple[float, ...]], NoneType]] = <function RescalingParams at 0x7faa82d69b80>,
+ process_dependency: Callable[..., Union[titiler.core.algorithm.base.BaseAlgorithm, NoneType]] = <function Algorithms.dependency.<locals>.post_process at 0x7faa7f6c2e50>,
+ reader_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.DefaultDependency'>,
+ environment_dependency: Callable[..., Dict] = <function BaseTilerFactory.<lambda> at 0x7faa7f6c2dc0>,
+ supported_tms: morecantile.defaults.TileMatrixSets = TileMatrixSets(tms={'CanadianNAD83_LCC': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/CanadianNAD83_LCC.json'), 'EuropeanETRS89_LAEAQuad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/EuropeanETRS89_LAEAQuad.json'), 'LINZAntarticaMapTilegrid': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/LINZAntarticaMapTilegrid.json'), 'NZTM2000Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/NZTM2000Quad.json'), 'UPSAntarcticWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UPSAntarcticWGS84Quad.json'), 'UPSArcticWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UPSArcticWGS84Quad.json'), 'UTM31WGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UTM31WGS84Quad.json'), 'WGS1984Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WGS1984Quad.json'), 'WebMercatorQuad': <TileMatrixSet title='Google Maps Compatible for the World' id='WebMercatorQuad' crs='http://www.opengis.net/def/crs/EPSG/0/3857>, 'WorldCRS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WorldCRS84Quad.json'), 'WorldMercatorWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WorldMercatorWGS84Quad.json')}),
+ default_tms: str = 'WebMercatorQuad',
+ router_prefix: str = '',
+ optional_headers: List[titiler.core.resources.enums.OptionalHeader] = <factory>,
+ route_dependencies: List[Tuple[List[titiler.core.routing.EndpointScope], List[fastapi.params.Depends]]] = <factory>,
+ extensions: List[titiler.core.factory.FactoryExtension] = <factory>,
+ templates: starlette.templating.Jinja2Templates = <starlette.templating.Jinja2Templates object at 0x7faa7f8e1b80>,
+ stats_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.StatisticsParams'>,
+ histogram_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.HistogramParams'>,
+ img_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.ImageParams'>,
+ add_preview: bool = True,
+ add_part: bool = True,
+ add_viewer: bool = True
+)
+
Tiler Factory.
+Name | +Type | +Description | +Default | +
---|---|---|---|
reader | +rio_tiler.io.base.BaseReader | +A rio-tiler reader. Defaults to rio_tiler.io.Reader . |
+rio_tiler.io.Reader |
+
stats_dependency | +titiler.core.dependencies.DefaultDependency | +Endpoint dependency defining options for rio-tiler's statistics method. | +None | +
histogram_dependency | +titiler.core.dependencies.DefaultDependency | +Endpoint dependency defining options for numpy's histogram method. | +None | +
img_dependency | +titiler.core.dependencies.DefaultDependency | +Endpoint dependency defining options for rio-tiler's preview/crop method. | +None | +
add_preview | +bool | +add /preview endpoints. Defaults to True. |
+True | +
add_part | +bool | +add /crop endpoints. Defaults to True. |
+True | +
add_viewer | +bool | +add /map endpoints. Defaults to True. |
+True | +
add_part
+
add_preview
+
add_viewer
+
dataset_dependency
+
default_tms
+
histogram_dependency
+
img_dependency
+
layer_dependency
+
reader
+
reader_dependency
+
render_dependency
+
router_prefix
+
stats_dependency
+
supported_tms
+
templates
+
def add_route_dependencies(
+ self,
+ *,
+ scopes: List[titiler.core.routing.EndpointScope],
+ dependencies=typing.List[fastapi.params.Depends]
+)
+
Add dependencies to routes.
+Allows a developer to add dependencies to a route after the route has been defined.
+def bounds(
+ self
+)
+
Register /bounds endpoint.
+def colormap_dependency(
+ colormap_name: typing_extensions.Annotated[Union[titiler.core.dependencies.ColorMapName, NoneType], Query(PydanticUndefined)] = None,
+ colormap: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None
+) -> Union[Dict[int, Tuple[int, int, int, int]], Sequence[Tuple[Tuple[Union[float, int], Union[float, int]], Tuple[int, int, int, int]]], NoneType]
+
Colormap Dependency.
+def environment_dependency(
+
+)
+
def info(
+ self
+)
+
Register /info endpoint.
+def map_viewer(
+ self
+)
+
Register /map endpoint.
+def part(
+ self
+)
+
Register /crop endpoint.
+def path_dependency(
+ url: typing_extensions.Annotated[str, Query(PydanticUndefined)]
+) -> str
+
Create dataset path from args
+def point(
+ self
+)
+
Register /point endpoints.
+def preview(
+ self
+)
+
Register /preview endpoint.
+def process_dependency(
+ algorithm: Literal['hillshade', 'contours', 'normalizedIndex', 'terrarium', 'terrainrgb'] = Query(None),
+ algorithm_params: str = Query(None)
+) -> Union[titiler.core.algorithm.base.BaseAlgorithm, NoneType]
+
Data Post-Processing options.
+def register_routes(
+ self
+)
+
This Method register routes to the router.
+Because we wrap the endpoints in a class we cannot define the routes as +methods (because of the self argument). The HACK is to define routes inside +the class method and register them after the class initialization.
+def rescale_dependency(
+ rescale: typing_extensions.Annotated[Union[List[str], NoneType], Query(PydanticUndefined)] = None
+) -> Union[List[Tuple[float, ...]], NoneType]
+
Min/Max data Rescaling
+def statistics(
+ self
+)
+
add statistics endpoints.
+def tile(
+ self
+)
+
Register /tiles endpoint.
+def tilejson(
+ self
+)
+
Register /tilejson.json endpoint.
+def url_for(
+ self,
+ request: starlette.requests.Request,
+ name: str,
+ **path_params: Any
+) -> str
+
Return full url (with prefix) for a specific endpoint.
+def wmts(
+ self
+)
+
Register /wmts endpoint.
+ + + + + + + +Titiler middlewares.
+class CacheControlMiddleware(
+ app: Callable[[MutableMapping[str, Any], Callable[[], Awaitable[MutableMapping[str, Any]]], Callable[[MutableMapping[str, Any]], Awaitable[NoneType]]], Awaitable[NoneType]],
+ cachecontrol: Union[str, NoneType] = None,
+ cachecontrol_max_http_code: Union[int, NoneType] = 500,
+ exclude_path: Union[Set[str], NoneType] = None
+)
+
MiddleWare to add CacheControl in response headers.
+class LoggerMiddleware(
+ app: Callable[[MutableMapping[str, Any], Callable[[], Awaitable[MutableMapping[str, Any]]], Callable[[MutableMapping[str, Any]], Awaitable[NoneType]]], Awaitable[NoneType]],
+ querystrings: bool = False,
+ headers: bool = False
+)
+
MiddleWare to add logging.
+class LowerCaseQueryStringMiddleware(
+ app: Callable[[MutableMapping[str, Any], Callable[[], Awaitable[MutableMapping[str, Any]]], Callable[[MutableMapping[str, Any]], Awaitable[NoneType]]], Awaitable[NoneType]]
+)
+
Middleware to make URL parameters case-insensitive.
+taken from: tiangolo/fastapi#826
+class TotalTimeMiddleware(
+ app: Callable[[MutableMapping[str, Any], Callable[[], Awaitable[MutableMapping[str, Any]]], Callable[[MutableMapping[str, Any]], Awaitable[NoneType]]], Awaitable[NoneType]]
+)
+
MiddleWare to add Total process time in response headers.
+ + + + + + + +Titiler.core Enums.
+class ImageDriver(
+ /,
+ *args,
+ **kwargs
+)
+
Supported output GDAL drivers.
+jp2
+
jpeg
+
jpg
+
name
+
npy
+
png
+
pngraw
+
tif
+
value
+
webp
+
class ImageType(
+ /,
+ *args,
+ **kwargs
+)
+
Available Output image type.
+jp2
+
jpeg
+
jpg
+
name
+
npy
+
png
+
pngraw
+
tif
+
value
+
webp
+
class MediaType(
+ /,
+ *args,
+ **kwargs
+)
+
Responses Media types formerly known as MIME types.
+geojson
+
html
+
jp2
+
jpeg
+
jpg
+
json
+
mvt
+
name
+
npy
+
pbf
+
png
+
pngraw
+
text
+
tif
+
value
+
webp
+
xml
+
class OptionalHeader(
+ /,
+ *args,
+ **kwargs
+)
+
Optional Header to add in responses.
+name
+
server_timing
+
value
+
x_assets
+
Custom routing classes.
+def add_route_dependencies(
+ routes: List[starlette.routing.BaseRoute],
+ *,
+ scopes: List[titiler.core.routing.EndpointScope],
+ dependencies=typing.List[fastapi.params.Depends]
+)
+
Add dependencies to routes.
+Allows a developer to add dependencies to a route after the route has been defined.
+def apiroute_factory(
+ env: Union[Dict, NoneType] = None
+) -> Type[fastapi.routing.APIRoute]
+
Create Custom API Route class with custom Env.
+Because we cannot create middleware for specific router we need to create
+a custom APIRoute which add the rasterio.Env(
block before the endpoint is
+actually called. This way we set the env outside the threads and we make sure
+that event multithreaded Reader will get the environment set.
Note: This has been tested in python 3.6 and 3.7 only.
+class EndpointScope(
+ /,
+ *args,
+ **kwargs
+)
+
Define endpoint.
+def clear(
+ ...
+)
+
D.clear() -> None. Remove all items from D.
+def copy(
+ ...
+)
+
D.copy() -> a shallow copy of D
+def fromkeys(
+ iterable,
+ value=None,
+ /
+)
+
Create a new dictionary with keys from iterable and values set to value.
+def get(
+ self,
+ key,
+ default=None,
+ /
+)
+
Return the value for key if key is in the dictionary, else default.
+def items(
+ ...
+)
+
D.items() -> a set-like object providing a view on D's items
+def keys(
+ ...
+)
+
D.keys() -> a set-like object providing a view on D's keys
+def pop(
+ ...
+)
+
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
+If key is not found, d is returned if given, otherwise KeyError is raised
+def popitem(
+ self,
+ /
+)
+
Remove and return a (key, value) pair as a 2-tuple.
+Pairs are returned in LIFO (last-in, first-out) order. +Raises KeyError if the dict is empty.
+def setdefault(
+ self,
+ key,
+ default=None,
+ /
+)
+
Insert key with a value of default if key is not in the dictionary.
+Return the value for key if key is in the dictionary, else default.
+def update(
+ ...
+)
+
D.update([E, ]**F) -> None. Update D from dict/iterable E and F.
+If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] +If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v +In either case, this is followed by: for k in F: D[k] = F[k]
+def values(
+ ...
+)
+
D.values() -> an object providing a view on D's values
+ + + + + + + +rio-cogeo Extension.
+class cogValidateExtension(
+
+)
+
Add /validate endpoint to a COG TilerFactory.
+def register(
+ self,
+ factory: titiler.core.factory.BaseTilerFactory
+)
+
Register endpoint to the tiler factory.
+ + + + + + + +rio-stac Extension.
+class Item(
+ /,
+ *args,
+ **kwargs
+)
+
STAC Item.
+def clear(
+ ...
+)
+
D.clear() -> None. Remove all items from D.
+def copy(
+ ...
+)
+
D.copy() -> a shallow copy of D
+def fromkeys(
+ iterable,
+ value=None,
+ /
+)
+
Create a new dictionary with keys from iterable and values set to value.
+def get(
+ self,
+ key,
+ default=None,
+ /
+)
+
Return the value for key if key is in the dictionary, else default.
+def items(
+ ...
+)
+
D.items() -> a set-like object providing a view on D's items
+def keys(
+ ...
+)
+
D.keys() -> a set-like object providing a view on D's keys
+def pop(
+ ...
+)
+
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
+If key is not found, d is returned if given, otherwise KeyError is raised
+def popitem(
+ self,
+ /
+)
+
Remove and return a (key, value) pair as a 2-tuple.
+Pairs are returned in LIFO (last-in, first-out) order. +Raises KeyError if the dict is empty.
+def setdefault(
+ self,
+ key,
+ default=None,
+ /
+)
+
Insert key with a value of default if key is not in the dictionary.
+Return the value for key if key is in the dictionary, else default.
+def update(
+ ...
+)
+
D.update([E, ]**F) -> None. Update D from dict/iterable E and F.
+If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] +If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v +In either case, this is followed by: for k in F: D[k] = F[k]
+def values(
+ ...
+)
+
D.values() -> an object providing a view on D's values
+class stacExtension(
+
+)
+
Add /stac endpoint to a COG TilerFactory.
+def register(
+ self,
+ factory: titiler.core.factory.BaseTilerFactory
+)
+
Register endpoint to the tiler factory.
+ + + + + + + +titiler Viewer Extensions.
+DEFAULT_TEMPLATES
+
class cogViewerExtension(
+ templates: starlette.templating.Jinja2Templates = <starlette.templating.Jinja2Templates object at 0x7f355b3745b0>
+)
+
Add /viewer endpoint to the TilerFactory.
+templates
+
def register(
+ self,
+ factory: titiler.core.factory.BaseTilerFactory
+)
+
Register endpoint to the tiler factory.
+class stacViewerExtension(
+ templates: starlette.templating.Jinja2Templates = <starlette.templating.Jinja2Templates object at 0x7f355b3745b0>
+)
+
Add /viewer endpoint to the TilerFactory.
+templates
+
def register(
+ self,
+ factory: titiler.core.factory.BaseTilerFactory
+)
+
Register endpoint to the tiler factory.
+ + + + + + + +TiTiler.mosaic Router factories.
+MAX_THREADS
+
WGS84_CRS
+
img_endpoint_params
+
def PixelSelectionParams(
+ pixel_selection: typing_extensions.Annotated[Literal['first', 'highest', 'lowest', 'mean', 'median', 'stdev', 'lastbandlow', 'lastbandhight'], Query(PydanticUndefined)] = 'first'
+) -> rio_tiler.mosaic.methods.base.MosaicMethodBase
+
Returns the mosaic method used to combine datasets together.
+class MosaicTilerFactory(
+ reader: Type[cogeo_mosaic.backends.base.BaseBackend] = <function MosaicBackend at 0x7fa42abd2550>,
+ router: fastapi.routing.APIRouter = <factory>,
+ path_dependency: Callable[..., Any] = <function DatasetPathParams at 0x7fa42a2c25e0>,
+ dataset_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.DatasetParams'>,
+ layer_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.BidxExprParams'>,
+ render_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.ImageRenderingParams'>,
+ colormap_dependency: Callable[..., Union[Dict[int, Tuple[int, int, int, int]], Sequence[Tuple[Tuple[Union[float, int], Union[float, int]], Tuple[int, int, int, int]]], NoneType]] = <function ColorMapParams at 0x7fa42a2c2550>,
+ rescale_dependency: Callable[..., Union[List[Tuple[float, ...]], NoneType]] = <function RescalingParams at 0x7fa42a2c2670>,
+ process_dependency: Callable[..., Union[titiler.core.algorithm.base.BaseAlgorithm, NoneType]] = <function Algorithms.dependency.<locals>.post_process at 0x7fa42a0a5790>,
+ reader_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.DefaultDependency'>,
+ environment_dependency: Callable[..., Dict] = <function BaseTilerFactory.<lambda> at 0x7fa42a0a5700>,
+ supported_tms: morecantile.defaults.TileMatrixSets = TileMatrixSets(tms={'CanadianNAD83_LCC': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/CanadianNAD83_LCC.json'), 'EuropeanETRS89_LAEAQuad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/EuropeanETRS89_LAEAQuad.json'), 'LINZAntarticaMapTilegrid': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/LINZAntarticaMapTilegrid.json'), 'NZTM2000Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/NZTM2000Quad.json'), 'UPSAntarcticWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UPSAntarcticWGS84Quad.json'), 'UPSArcticWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UPSArcticWGS84Quad.json'), 'UTM31WGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/UTM31WGS84Quad.json'), 'WGS1984Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WGS1984Quad.json'), 'WebMercatorQuad': <TileMatrixSet title='Google Maps Compatible for the World' id='WebMercatorQuad' crs='http://www.opengis.net/def/crs/EPSG/0/3857>, 'WorldCRS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WorldCRS84Quad.json'), 'WorldMercatorWGS84Quad': PosixPath('/opt/hostedtoolcache/Python/3.8.17/x64/lib/python3.8/site-packages/morecantile/data/WorldMercatorWGS84Quad.json')}),
+ default_tms: str = 'WebMercatorQuad',
+ router_prefix: str = '',
+ optional_headers: List[titiler.core.resources.enums.OptionalHeader] = <factory>,
+ route_dependencies: List[Tuple[List[titiler.core.routing.EndpointScope], List[fastapi.params.Depends]]] = <factory>,
+ extensions: List[titiler.core.factory.FactoryExtension] = <factory>,
+ templates: starlette.templating.Jinja2Templates = <starlette.templating.Jinja2Templates object at 0x7fa42a26cd00>,
+ dataset_reader: Union[Type[rio_tiler.io.base.BaseReader], Type[rio_tiler.io.base.MultiBaseReader], Type[rio_tiler.io.base.MultiBandReader]] = <class 'rio_tiler.io.rasterio.Reader'>,
+ backend_dependency: Type[titiler.core.dependencies.DefaultDependency] = <class 'titiler.core.dependencies.DefaultDependency'>,
+ pixel_selection_dependency: Callable[..., rio_tiler.mosaic.methods.base.MosaicMethodBase] = <function PixelSelectionParams at 0x7fa42abd2430>,
+ add_viewer: bool = True
+)
+
MosaicTiler Factory.
+The main difference with titiler.endpoint.factory.TilerFactory is that this factory
+needs the reader
to be of cogeo_mosaic.backends.BaseBackend
type (e.g MosaicBackend) and a dataset_reader
(BaseReader).
add_viewer
+
backend_dependency
+
dataset_dependency
+
dataset_reader
+
default_tms
+
layer_dependency
+
reader_dependency
+
render_dependency
+
router_prefix
+
supported_tms
+
templates
+
def add_route_dependencies(
+ self,
+ *,
+ scopes: List[titiler.core.routing.EndpointScope],
+ dependencies=typing.List[fastapi.params.Depends]
+)
+
Add dependencies to routes.
+Allows a developer to add dependencies to a route after the route has been defined.
+def assets(
+ self
+)
+
Register /assets endpoint.
+def bounds(
+ self
+)
+
Register /bounds endpoint.
+def colormap_dependency(
+ colormap_name: typing_extensions.Annotated[Union[titiler.core.dependencies.ColorMapName, NoneType], Query(PydanticUndefined)] = None,
+ colormap: typing_extensions.Annotated[Union[str, NoneType], Query(PydanticUndefined)] = None
+) -> Union[Dict[int, Tuple[int, int, int, int]], Sequence[Tuple[Tuple[Union[float, int], Union[float, int]], Tuple[int, int, int, int]]], NoneType]
+
Colormap Dependency.
+def environment_dependency(
+
+)
+
def info(
+ self
+)
+
Register /info endpoint
+def map_viewer(
+ self
+)
+
Register /map endpoint.
+def path_dependency(
+ url: typing_extensions.Annotated[str, Query(PydanticUndefined)]
+) -> str
+
Create dataset path from args
+def pixel_selection_dependency(
+ pixel_selection: typing_extensions.Annotated[Literal['first', 'highest', 'lowest', 'mean', 'median', 'stdev', 'lastbandlow', 'lastbandhight'], Query(PydanticUndefined)] = 'first'
+) -> rio_tiler.mosaic.methods.base.MosaicMethodBase
+
Returns the mosaic method used to combine datasets together.
+def point(
+ self
+)
+
Register /point endpoint.
+def process_dependency(
+ algorithm: Literal['hillshade', 'contours', 'normalizedIndex', 'terrarium', 'terrainrgb'] = Query(None),
+ algorithm_params: str = Query(None)
+) -> Union[titiler.core.algorithm.base.BaseAlgorithm, NoneType]
+
Data Post-Processing options.
+def read(
+ self
+)
+
Register / (Get) Read endpoint.
+def reader(
+ input: str,
+ *args: Any,
+ **kwargs: Any
+) -> cogeo_mosaic.backends.base.BaseBackend
+
Select mosaic backend for input.
+def register_routes(
+ self
+)
+
This Method register routes to the router.
+Because we wrap the endpoints in a class we cannot define the routes as +methods (because of the self argument). The HACK is to define routes inside +the class method and register them after the class initialization.
+def rescale_dependency(
+ rescale: typing_extensions.Annotated[Union[List[str], NoneType], Query(PydanticUndefined)] = None
+) -> Union[List[Tuple[float, ...]], NoneType]
+
Min/Max data Rescaling
+def tile(
+ self
+)
+
Register /tiles endpoints.
+def tilejson(
+ self
+)
+
Add tilejson endpoint.
+def url_for(
+ self,
+ request: starlette.requests.Request,
+ name: str,
+ **path_params: Any
+) -> str
+
Return full url (with prefix) for a specific endpoint.
+def validate(
+ self
+)
+
Register /validate endpoint.
+def wmts(
+ self
+)
+
Add wmts endpoint.
+ + + + + + + +Titiler.mosaic Enums.
+None
+class PixelSelectionMethod(
+ /,
+ *args,
+ **kwargs
+)
+
first
+
highest
+
lowest
+
mean
+
median
+
name
+
stdev
+
value
+
\n {translation(\"search.result.term.missing\")}: {...missing}\n
\n }\n