Skip to content

Commit

Permalink
move mosaicViewerExtension to extension.py
Browse files Browse the repository at this point in the history
  • Loading branch information
hrodmn committed Jun 27, 2023
1 parent 17d9905 commit db40b59
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 116 deletions.
123 changes: 7 additions & 116 deletions runtime/eoapi/raster/eoapi/raster/app.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
"""TiTiler+PgSTAC FastAPI application."""

import logging
from dataclasses import dataclass
from typing import Dict, List, Literal, Optional, Tuple
from urllib.parse import urlencode
from typing import Dict

import pystac
from eoapi.raster import __version__ as eoapi_raster_version
from eoapi.raster.config import ApiSettings
from eoapi.raster.extension import mosaicViewerExtension
from fastapi import Depends, FastAPI, Query
from jinja2 import ChoiceLoader, PackageLoader
from psycopg import OperationalError
Expand All @@ -17,21 +16,14 @@
from starlette.responses import HTMLResponse
from starlette.templating import Jinja2Templates
from starlette_cramjam.middleware import CompressionMiddleware
from titiler.core.dependencies import AssetsBidxExprParamsOptional, RescalingParams
from titiler.core.errors import DEFAULT_STATUS_CODES, add_exception_handlers
from titiler.core.factory import (
AlgorithmFactory,
FactoryExtension,
MultiBaseTilerFactory,
TMSFactory,
)
from titiler.core.factory import AlgorithmFactory, MultiBaseTilerFactory, TMSFactory
from titiler.core.middleware import CacheControlMiddleware
from titiler.core.resources.enums import ImageType, OptionalHeader
from titiler.core.resources.enums import OptionalHeader
from titiler.mosaic.errors import MOSAIC_STATUS_CODES
from titiler.mosaic.resources.enums import PixelSelectionMethod
from titiler.pgstac.db import close_db_connection, connect_to_db
from titiler.pgstac.dependencies import ItemPathParams, PgSTACParams
from titiler.pgstac.factory import BaseTilerFactory, MosaicTilerFactory
from titiler.pgstac.dependencies import ItemPathParams
from titiler.pgstac.factory import MosaicTilerFactory
from titiler.pgstac.reader import PgSTACReader

try:
Expand Down Expand Up @@ -69,117 +61,16 @@

###############################################################################
# MOSAIC Endpoints
# https://github.com/developmentseed/titiler/blob/main/src/titiler/extensions/titiler/extensions/viewer.py#LL21C1-L42C1
@dataclass
class mosaicViewerExtension(FactoryExtension):
"""Add /map endpoint to the TilerFactory."""

def register(self, factory: BaseTilerFactory):
"""Register endpoint to the tiler factory."""

@factory.router.get("/{searchid}/map", response_class=HTMLResponse)
@factory.router.get(
"/{searchid}/{TileMatrixSetId}/map", response_class=HTMLResponse
)
def map_viewer(
request: Request,
searchid=Depends(factory.path_dependency),
TileMatrixSetId: Literal["WebMercatorQuad"] = Query(
"WebMercatorQuad",
description="TileMatrixSet Name (default: 'WebMercatorQuad')",
), # noqa
tile_format: Optional[ImageType] = Query(
None, description="Output image type. Default is auto."
), # noqa
tile_scale: int = Query(
1, gt=0, lt=4, description="Tile size scale. 1=256x256, 2=512x512..."
), # noqa
minzoom: Optional[int] = Query(
None, description="Overwrite default minzoom."
), # noqa
maxzoom: Optional[int] = Query(
None, description="Overwrite default maxzoom."
), # noqa
layer_params=Depends(factory.layer_dependency), # noqa
dataset_params=Depends(factory.dataset_dependency), # noqa
pixel_selection: PixelSelectionMethod = Query(
PixelSelectionMethod.first, description="Pixel selection method."
), # noqa
buffer: Optional[float] = Query(
None,
gt=0,
alias="buffer",
title="Tile buffer.",
description="Buffer on each side of the given tile. It must be a multiple of `0.5`. Output **tilesize** will be expanded to `tilesize + 2 * buffer` (e.g 0.5 = 257x257, 1.0 = 258x258).",
), # noqa
post_process=Depends(factory.process_dependency), # noqa
rescale: Optional[List[Tuple[float, ...]]] = Depends(
RescalingParams
), # noqa
color_formula: Optional[str] = Query(
None,
title="Color Formula",
description="rio-color formula (info: https://github.com/mapbox/rio-color)",
), # noqa
colormap=Depends(factory.colormap_dependency), # noqa
render_params=Depends(factory.render_dependency), # noqa
pgstac_params: PgSTACParams = Depends(), # noqa
backend_params=Depends(factory.backend_dependency), # noqa
reader_params=Depends(factory.reader_dependency), # noqa
env=Depends(factory.environment_dependency), # noqa
):
"""Return a simple map viewer."""
tilejson_url = factory.url_for(
request, "tilejson", searchid=searchid, TileMatrixSetId=TileMatrixSetId
)

assets_url = factory.url_for(
request,
"assets_for_tile",
searchid=searchid,
TileMatrixSetId=TileMatrixSetId,
x="{x}",
y="{y}",
z="{z}",
)

info_url = factory.url_for(
request,
"info_search",
searchid=searchid,
)

if request.query_params._list:
tilejson_url += f"?{urlencode(request.query_params._list)}"

tms = factory.supported_tms.get(TileMatrixSetId)
return templates.TemplateResponse(
name="mosaic-browser.html",
context={
"request": request,
"tilejson_url": tilejson_url,
"assets_url": assets_url,
"info_url": info_url,
"tms": tms,
"resolutions": [tms._resolution(matrix) for matrix in tms],
},
media_type="text/html",
)


###############################################################################
# MOSAIC Endpoints
# https://github.com/developmentseed/eoAPI/blob/main/runtime/eoapi/raster/eoapi/raster/app.py
mosaic = MosaicTilerFactory(
optional_headers=optional_headers,
router_prefix="/mosaic",
add_statistics=True,
add_map_viewer=False,
add_viewer=False,
add_mosaic_list=True,
extensions=[
mosaicViewerExtension(),
],
layer_dependency=AssetsBidxExprParamsOptional,
)


Expand Down
123 changes: 123 additions & 0 deletions runtime/eoapi/raster/eoapi/raster/extension.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
"""mosaicViewerExtension for /map endpoint"""
from dataclasses import dataclass
from typing import List, Literal, Optional, Tuple
from urllib.parse import urlencode

from fastapi import Depends, Query
from jinja2 import ChoiceLoader, PackageLoader
from starlette.requests import Request
from starlette.responses import HTMLResponse
from starlette.templating import Jinja2Templates
from titiler.core.dependencies import RescalingParams
from titiler.core.factory import FactoryExtension
from titiler.core.resources.enums import ImageType
from titiler.mosaic.resources.enums import PixelSelectionMethod
from titiler.pgstac.dependencies import PgSTACParams
from titiler.pgstac.factory import BaseTilerFactory

templates = Jinja2Templates( # type: ignore
directory="",
loader=ChoiceLoader(
[
PackageLoader(__package__, "templates"),
]
),
)


@dataclass
class mosaicViewerExtension(FactoryExtension):
"""Add /map endpoint to the TilerFactory."""

def register(self, factory: BaseTilerFactory):
"""Register endpoint to the tiler factory."""

@factory.router.get("/{searchid}/map", response_class=HTMLResponse)
@factory.router.get(
"/{searchid}/{TileMatrixSetId}/map", response_class=HTMLResponse
)
def map_viewer(
request: Request,
searchid=Depends(factory.path_dependency),
TileMatrixSetId: Literal["WebMercatorQuad"] = Query(
"WebMercatorQuad",
description="TileMatrixSet Name (default: 'WebMercatorQuad')",
), # noqa
tile_format: Optional[ImageType] = Query(
None, description="Output image type. Default is auto."
), # noqa
tile_scale: int = Query(
1, gt=0, lt=4, description="Tile size scale. 1=256x256, 2=512x512..."
), # noqa
minzoom: Optional[int] = Query(
None, description="Overwrite default minzoom."
), # noqa
maxzoom: Optional[int] = Query(
None, description="Overwrite default maxzoom."
), # noqa
layer_params=Depends(factory.layer_dependency), # noqa
dataset_params=Depends(factory.dataset_dependency), # noqa
pixel_selection: PixelSelectionMethod = Query(
PixelSelectionMethod.first, description="Pixel selection method."
), # noqa
buffer: Optional[float] = Query(
None,
gt=0,
alias="buffer",
title="Tile buffer.",
description="Buffer on each side of the given tile. It must be a multiple of `0.5`. Output **tilesize** will be expanded to `tilesize + 2 * buffer` (e.g 0.5 = 257x257, 1.0 = 258x258).",
), # noqa
post_process=Depends(factory.process_dependency), # noqa
rescale: Optional[List[Tuple[float, ...]]] = Depends(
RescalingParams
), # noqa
color_formula: Optional[str] = Query(
None,
title="Color Formula",
description="rio-color formula (info: https://github.com/mapbox/rio-color)",
), # noqa
colormap=Depends(factory.colormap_dependency), # noqa
render_params=Depends(factory.render_dependency), # noqa
pgstac_params: PgSTACParams = Depends(), # noqa
backend_params=Depends(factory.backend_dependency), # noqa
reader_params=Depends(factory.reader_dependency), # noqa
env=Depends(factory.environment_dependency), # noqa
):
"""Return a simple map viewer."""
tilejson_url = factory.url_for(
request, "tilejson", searchid=searchid, TileMatrixSetId=TileMatrixSetId
)

# TODO: use assets_for_bbox to avoid needing the zoom level?
assets_url = factory.url_for(
request,
"assets_for_tile",
searchid=searchid,
TileMatrixSetId=TileMatrixSetId,
x="{x}",
y="{y}",
z="{z}",
)

info_url = factory.url_for(
request,
"info_search",
searchid=searchid,
)

if request.query_params._list:
tilejson_url += f"?{urlencode(request.query_params._list)}"

tms = factory.supported_tms.get(TileMatrixSetId)
return templates.TemplateResponse(
name="mosaic-browser.html",
context={
"request": request,
"tilejson_url": tilejson_url,
"assets_url": assets_url,
"info_url": info_url,
"tms": tms,
"resolutions": [tms._resolution(matrix) for matrix in tms],
},
media_type="text/html",
)

0 comments on commit db40b59

Please sign in to comment.