Skip to content

Commit

Permalink
use url_for for route matching, refactor wmts endpoints (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentsarago authored Aug 11, 2020
1 parent 24ec8b6 commit 0110e5b
Show file tree
Hide file tree
Showing 8 changed files with 292 additions and 154 deletions.
5 changes: 5 additions & 0 deletions tests/routes/test_cog.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ def test_wmts(reader, app):
assert response.status_code == 200
assert response.headers["content-type"] == "application/xml"
assert response.headers["Cache-Control"] == "public, max-age=3600"
assert (
"http://testserver/cog/WMTSCapabilities.xml?url=https://myurl.com/cog.tif"
in response.content.decode()
)
assert "<ows:Identifier>cogeo</ows:Identifier>" in response.content.decode()
assert (
"http://testserver/cog/tiles/WebMercatorQuad/{TileMatrix}/{TileCol}/{TileRow}@1x.png?url=https"
in response.content.decode()
Expand Down
4 changes: 2 additions & 2 deletions tests/routes/test_mosaic.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ def test_tilejson(app):
TileJSON(**body)

assert (
body["tiles"][0]
== "http://testserver/mosaicjson/tiles/WebMercatorQuad/{z}/{x}/{y}@1x"
"http://testserver/mosaicjson/tiles/WebMercatorQuad/{z}/{x}/{y}@1x?url="
in body["tiles"][0]
)
assert body["minzoom"] == mosaicjson["minzoom"]
assert body["maxzoom"] == mosaicjson["maxzoom"]
Expand Down
80 changes: 49 additions & 31 deletions titiler/endpoints/cog.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ async def cog_tile(
content = utils.reformat(
tile,
mask,
img_format=format,
format,
colormap=colormap,
transform=dst_transform,
crs=tms.crs,
Expand Down Expand Up @@ -231,7 +231,7 @@ async def cog_preview(
timings.append(("Post-process", t.elapsed))

with utils.Timer() as t:
content = utils.reformat(data, mask, img_format=format, colormap=colormap)
content = utils.reformat(data, mask, format, colormap=colormap)
timings.append(("Format", t.elapsed))

if timings:
Expand Down Expand Up @@ -287,7 +287,7 @@ async def cog_part(
timings.append(("Post-process", t.elapsed))

with utils.Timer() as t:
content = utils.reformat(data, mask, img_format=format, colormap=colormap)
content = utils.reformat(data, mask, format, colormap=colormap)
timings.append(("Format", t.elapsed))

if timings:
Expand Down Expand Up @@ -365,21 +365,26 @@ async def cog_tilejson(
maxzoom: Optional[int] = Query(None, description="Overwrite default maxzoom."),
):
"""Return TileJSON document for a COG."""
scheme = request.url.scheme
host = request.headers["host"]
kwargs = {
"z": "{z}",
"x": "{x}",
"y": "{y}",
"scale": tile_scale,
"TileMatrixSetId": TileMatrixSetId.name,
}
if tile_format:
kwargs["format"] = tile_format.value

kwargs = dict(request.query_params)
kwargs.pop("tile_format", None)
kwargs.pop("tile_scale", None)
kwargs.pop("TileMatrixSetId", None)
kwargs.pop("minzoom", None)
kwargs.pop("maxzoom", None)
q = dict(request.query_params)
q.pop("TileMatrixSetId", None)
q.pop("tile_format", None)
q.pop("tile_scale", None)
q.pop("minzoom", None)
q.pop("maxzoom", None)
qs = urlencode(list(q.items()))

qs = urlencode(list(kwargs.items()))
if tile_format:
tile_url = f"{scheme}://{host}/cog/tiles/{TileMatrixSetId.name}/{{z}}/{{x}}/{{y}}@{tile_scale}x.{tile_format}?{qs}"
else:
tile_url = f"{scheme}://{host}/cog/tiles/{TileMatrixSetId.name}/{{z}}/{{x}}/{{y}}@{tile_scale}x?{qs}"
tiles_url = request.url_for("cog_tile", **kwargs).replace("\\", "")
tiles_url += f"?{qs}"

tms = morecantile.tms.get(TileMatrixSetId.name)
with COGReader(url, tms=tms) as cog:
Expand All @@ -392,7 +397,7 @@ async def cog_tilejson(
"minzoom": minzoom or cog.minzoom,
"maxzoom": maxzoom or cog.maxzoom,
"name": os.path.basename(url),
"tiles": [tile_url],
"tiles": [tiles_url],
}

return tjson
Expand All @@ -402,7 +407,7 @@ async def cog_tilejson(
@router.get(
"/{TileMatrixSetId}/WMTSCapabilities.xml", response_class=XMLResponse, tags=["OGC"],
)
def wmts(
def cog_wmts(
request: Request,
TileMatrixSetId: TileMatrixSetNames = Query(
TileMatrixSetNames.WebMercatorQuad, # type: ignore
Expand All @@ -415,20 +420,35 @@ def wmts(
tile_scale: int = Query(
1, gt=0, lt=4, description="Tile size scale. 1=256x256, 2=512x512..."
),
minzoom: Optional[int] = Query(None, description="Overwrite default minzoom."),
maxzoom: Optional[int] = Query(None, description="Overwrite default maxzoom."),
):
"""OGC WMTS endpoint."""
scheme = request.url.scheme
host = request.headers["host"]
endpoint = f"{scheme}://{host}/cog"

kwargs = dict(request.query_params)
kwargs.pop("tile_format", None)
kwargs.pop("tile_scale", None)
qs = urlencode(list(kwargs.items()))
kwargs = {
"z": "{TileMatrix}",
"x": "{TileCol}",
"y": "{TileRow}",
"scale": tile_scale,
"format": tile_format.value,
"TileMatrixSetId": TileMatrixSetId.name,
}
tiles_endpoint = request.url_for("cog_tile", **kwargs)
q = dict(request.query_params)
q.pop("TileMatrixSetId", None)
q.pop("tile_format", None)
q.pop("tile_scale", None)
q.pop("minzoom", None)
q.pop("maxzoom", None)
q.pop("SERVICE", None)
q.pop("REQUEST", None)
qs = urlencode(list(q.items()))
tiles_endpoint += f"?{qs}"

tms = morecantile.tms.get(TileMatrixSetId.name)
with COGReader(url, tms=tms) as cog:
minzoom, maxzoom, bounds = cog.minzoom, cog.maxzoom, cog.bounds
bounds = cog.bounds
minzoom = minzoom or cog.minzoom
maxzoom = maxzoom or cog.maxzoom

media_type = ImageMimeTypes[tile_format.value].value

Expand All @@ -447,18 +467,16 @@ def wmts(
</TileMatrix>"""
tileMatrix.append(tm)

tile_ext = f"@{tile_scale}x.{tile_format.value}"
return templates.TemplateResponse(
"wmts.xml",
{
"request": request,
"endpoint": endpoint,
"tiles_endpoint": tiles_endpoint,
"bounds": bounds,
"tileMatrix": tileMatrix,
"tms": tms,
"title": "Cloud Optimized GeoTIFF",
"query_string": qs,
"tile_format": tile_ext,
"layer_name": "cogeo",
"media_type": media_type,
},
media_type=MimeTypes.xml.value,
Expand Down
Loading

0 comments on commit 0110e5b

Please sign in to comment.