diff --git a/.gitignore b/.gitignore index 3cfc7f31b..e5cc417fe 100644 --- a/.gitignore +++ b/.gitignore @@ -92,6 +92,10 @@ celerybeat-schedule venv/ ENV/ +# VScode +.vscode +.vscode/ + # Spyder project settings .spyderproject .spyproject diff --git a/src/titiler/application/tests/routes/test_cog.py b/src/titiler/application/tests/routes/test_cog.py index 3b185787b..3e7726105 100644 --- a/src/titiler/application/tests/routes/test_cog.py +++ b/src/titiler/application/tests/routes/test_cog.py @@ -53,7 +53,6 @@ def test_info(rio, app): def test_wmts(rio, app): """test wmts endpoints.""" rio.open = mock_rasterio_open - response = app.get( "/cog/WebMercatorQuad/WMTSCapabilities.xml?url=https://myurl.com/cog.tif" ) @@ -69,6 +68,10 @@ def test_wmts(rio, app): "http://testserver/cog/tiles/WebMercatorQuad/{TileMatrix}/{TileCol}/{TileRow}@1x.png?url=https" in response.content.decode() ) + assert ( + '' + not in response.content.decode() # I don't understand yet why this test fails. + ) assert ( "http://www.opengis.net/def/crs/EPSG/0/3857" in response.content.decode() diff --git a/src/titiler/core/titiler/core/factory.py b/src/titiler/core/titiler/core/factory.py index 1cb9dfe76..06ec2e2c3 100644 --- a/src/titiler/core/titiler/core/factory.py +++ b/src/titiler/core/titiler/core/factory.py @@ -27,6 +27,7 @@ from morecantile import TileMatrixSet from morecantile import tms as morecantile_tms from morecantile.defaults import TileMatrixSets +from morecantile.models import CRS_to_uri from pydantic import Field from rio_tiler.colormap import ColorMaps from rio_tiler.colormap import cmap as default_cmap @@ -268,9 +269,9 @@ class TilerFactory(BaseFactory): img_part_dependency: Type[DefaultDependency] = PartFeatureParams # Post Processing Dependencies (algorithm) - process_dependency: Callable[ - ..., Optional[BaseAlgorithm] - ] = available_algorithms.dependency + process_dependency: Callable[..., Optional[BaseAlgorithm]] = ( + available_algorithms.dependency + ) # Image rendering Dependencies rescale_dependency: Callable[..., Optional[RescaleType]] = RescalingParams @@ -573,7 +574,10 @@ def tile( tms = self.supported_tms.get(tileMatrixSetId) with rasterio.Env(**env): with self.reader( - src_path, tms=tms, **reader_params.as_dict() + src_path, + tms=tms, + geographic_crs=tms.geographic_crs, + **reader_params.as_dict(), ) as src_dst: image = src_dst.tile( x, @@ -683,7 +687,10 @@ def tilejson( tms = self.supported_tms.get(tileMatrixSetId) with rasterio.Env(**env): with self.reader( - src_path, tms=tms, **reader_params.as_dict() + src_path, + tms=tms, + geographic_crs=tms.geographic_crs, + **reader_params.as_dict(), ) as src_dst: return { "bounds": src_dst.geographic_bounds, @@ -837,7 +844,10 @@ def wmts( tms = self.supported_tms.get(tileMatrixSetId) with rasterio.Env(**env): with self.reader( - src_path, tms=tms, **reader_params.as_dict() + src_path, + tms=tms, + geographic_crs=tms.geographic_crs, + **reader_params.as_dict(), ) as src_dst: bounds = src_dst.geographic_bounds minzoom = minzoom if minzoom is not None else src_dst.minzoom @@ -863,12 +873,21 @@ def wmts( else: supported_crs = tms.crs.srs + bounds_crs = CRS_to_uri(tms.geographic_crs) + + if tms.geographic_crs == WGS84_CRS: + bounds_type = "WGS84BoundingBox" + else: + bounds_type = "BoundingBox" + return self.templates.TemplateResponse( request, name="wmts.xml", context={ "tiles_endpoint": tiles_url, + "bounds_type": bounds_type, "bounds": bounds, + "bounds_crs": bounds_crs, "tileMatrix": tileMatrix, "tms": tms, "supported_crs": supported_crs, diff --git a/src/titiler/core/titiler/core/templates/wmts.xml b/src/titiler/core/titiler/core/templates/wmts.xml index ae36a247f..2c3a8940f 100644 --- a/src/titiler/core/titiler/core/templates/wmts.xml +++ b/src/titiler/core/titiler/core/templates/wmts.xml @@ -37,10 +37,10 @@ {{ title }} {{ layer_name }} {{ title }} - + {{ bounds[0] }} {{ bounds[1] }} {{ bounds[2] }} {{ bounds[3] }} - + diff --git a/src/titiler/mosaic/titiler/mosaic/factory.py b/src/titiler/mosaic/titiler/mosaic/factory.py index 366e10546..2d8ee4e5a 100644 --- a/src/titiler/mosaic/titiler/mosaic/factory.py +++ b/src/titiler/mosaic/titiler/mosaic/factory.py @@ -14,6 +14,7 @@ from geojson_pydantic.geometries import Polygon from morecantile import tms as morecantile_tms from morecantile.defaults import TileMatrixSets +from morecantile.models import CRS_to_uri from pydantic import Field from rio_tiler.constants import MAX_THREADS, WGS84_CRS from rio_tiler.io import BaseReader, MultiBandReader, MultiBaseReader, Reader @@ -88,9 +89,9 @@ class MosaicTilerFactory(BaseFactory): tile_dependency: Type[DefaultDependency] = TileParams # Post Processing Dependencies (algorithm) - process_dependency: Callable[ - ..., Optional[BaseAlgorithm] - ] = available_algorithms.dependency + process_dependency: Callable[..., Optional[BaseAlgorithm]] = ( + available_algorithms.dependency + ) # Image rendering Dependencies rescale_dependency: Callable[..., Optional[RescaleType]] = RescalingParams @@ -640,17 +641,29 @@ def wmts( """ tileMatrix.append(tm) + supported_crs = tms.crs.srs + + bounds_crs = CRS_to_uri(tms.geographic_crs) + + if tms.geographic_crs == WGS84_CRS: + bounds_type = "WGS84BoundingBox" + else: + bounds_type = "BoundingBox" + return self.templates.TemplateResponse( request, name="wmts.xml", context={ "tiles_endpoint": tiles_url, + "bounds_type": bounds_type, "bounds": bounds, + "bounds_crs": bounds_crs, "tileMatrix": tileMatrix, "tms": tms, - "title": src_path - if isinstance(src_path, str) - else "TiTiler Mosaic", + "supported_crs": supported_crs, + "title": ( + src_path if isinstance(src_path, str) else "TiTiler Mosaic" + ), "layer_name": "Mosaic", "media_type": tile_format.mediatype, },