From 6aeedbd8ed4e355a37680be103c3b63f7f3e37c8 Mon Sep 17 00:00:00 2001 From: Pete Gadomski Date: Wed, 6 Mar 2024 01:50:32 -0700 Subject: [PATCH] Add `use_epsg` parameter to WMTS endpoint (#782) * feat: add use_epsg param to wmts This enables ArcMap compatability. * fix: escape urls in wmts template Without the escapes, you can only have one query parameter --- src/titiler/application/tests/routes/test_cog.py | 11 +++++++++++ src/titiler/core/titiler/core/factory.py | 16 +++++++++++++++- src/titiler/core/titiler/core/templates/wmts.xml | 8 ++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/titiler/application/tests/routes/test_cog.py b/src/titiler/application/tests/routes/test_cog.py index e69a0b501..0bcb751b8 100644 --- a/src/titiler/application/tests/routes/test_cog.py +++ b/src/titiler/application/tests/routes/test_cog.py @@ -67,6 +67,10 @@ def test_wmts(rio, app): "http://testserver/cog/tiles/WebMercatorQuad/{TileMatrix}/{TileCol}/{TileRow}@1x.png?url=https" in response.content.decode() ) + assert ( + "http://www.opengis.net/def/crs/EPSG/0/3857" + in response.content.decode() + ) response = app.get( "/cog/WMTSCapabilities.xml?url=https://myurl.com/cog.tif&tile_scale=2&tile_format=jpg" @@ -78,6 +82,13 @@ def test_wmts(rio, app): in response.content.decode() ) + response = app.get( + "/cog/WMTSCapabilities.xml?url=https://myurl.com/cog.tif&use_epsg=true" + ) + assert response.status_code == 200 + assert response.headers["content-type"] == "application/xml" + assert "EPSG:3857" in response.content.decode() + @patch("rio_tiler.io.rasterio.rasterio") def test_tile(rio, app): diff --git a/src/titiler/core/titiler/core/factory.py b/src/titiler/core/titiler/core/factory.py index 6fcf0b282..7cb9b7fd4 100644 --- a/src/titiler/core/titiler/core/factory.py +++ b/src/titiler/core/titiler/core/factory.py @@ -238,7 +238,8 @@ def add_route_dependencies( route.dependant.dependencies.insert( # type: ignore 0, get_parameterless_sub_dependant( - depends=depends, path=route.path_format # type: ignore + depends=depends, + path=route.path_format, # type: ignore ), ) @@ -778,6 +779,12 @@ def wmts( Optional[int], Query(description="Overwrite default maxzoom."), ] = None, + use_epsg: Annotated[ + bool, + Query( + description="Use EPSG code, not opengis.net, for the ows:SupportedCRS in the TileMatrixSet (set to True to enable ArcMap compatability)" + ), + ] = False, layer_params=Depends(self.layer_dependency), dataset_params=Depends(self.dataset_dependency), tile_params=Depends(self.tile_dependency), @@ -807,6 +814,7 @@ def wmts( "minzoom", "maxzoom", "service", + "use_epsg", "request", ] qs = [ @@ -839,6 +847,11 @@ def wmts( """ tileMatrix.append(tm) + if use_epsg: + supported_crs = f"EPSG:{tms.crs.to_epsg()}" + else: + supported_crs = tms.crs.srs + return self.templates.TemplateResponse( "wmts.xml", { @@ -847,6 +860,7 @@ def wmts( "bounds": bounds, "tileMatrix": tileMatrix, "tms": tms, + "supported_crs": supported_crs, "title": "Cloud Optimized GeoTIFF", "layer_name": "cogeo", "media_type": tile_format.mediatype, diff --git a/src/titiler/core/titiler/core/templates/wmts.xml b/src/titiler/core/titiler/core/templates/wmts.xml index 8305851ce..897d0acbd 100644 --- a/src/titiler/core/titiler/core/templates/wmts.xml +++ b/src/titiler/core/titiler/core/templates/wmts.xml @@ -8,7 +8,7 @@ - + RESTful @@ -21,7 +21,7 @@ - + RESTful @@ -52,11 +52,11 @@ {{ tms.id }} - {{ tms.crs.srs }} + {{ supported_crs }} {% for item in tileMatrix %} {{ item | safe }} {% endfor %} - +