66from urllib .parse import urlencode
77
88import jinja2
9- import pyproj
109import rasterio
1110from attrs import define , field
1211from fastapi import Depends , Query
2221from titiler .core .factory import FactoryExtension , MultiBaseTilerFactory
2322from titiler .core .resources .enums import ImageType
2423from titiler .core .resources .responses import XMLResponse
25- from titiler .core .utils import check_query_params , tms_limits
24+ from titiler .core .utils import (
25+ check_query_params ,
26+ rio_crs_to_pyproj ,
27+ tms_limits ,
28+ tms_limits_to_xml ,
29+ tms_to_xml ,
30+ )
2631from titiler .pgstac import model
2732from titiler .pgstac .errors import NoLayerFound
2833from titiler .pgstac .factory import MosaicTilerFactory , logger
@@ -300,35 +305,9 @@ def wmts( # noqa: C901
300305 tms ,
301306 bounds ,
302307 zooms = (tms_minzoom , tms_maxzoom ),
308+ geographic_crs = self .crs ,
303309 )
304310
305- tilematrix_limits : list [str ] = []
306- for tms_limit in _limits :
307- tm = f"""
308- <TileMatrixLimits>
309- <TileMatrix>{ tms_limit ['tileMatrix' ]} </TileMatrix>
310- <MinTileRow>{ tms_limit ['minTileRow' ]} </MinTileRow>
311- <MaxTileRow>{ tms_limit ['maxTileRow' ]} </MaxTileRow>
312- <MinTileCol>{ tms_limit ['minTileCol' ]} </MinTileCol>
313- <MaxTileCol>{ tms_limit ['maxTileCol' ]} </MaxTileCol>
314- </TileMatrixLimits>"""
315- tilematrix_limits .append (tm )
316-
317- tileMatrix = []
318- for zoom in range (tms_minzoom , tms_maxzoom + 1 ):
319- matrix = tms .matrix (zoom )
320- tm = f"""
321- <TileMatrix>
322- <ows:Identifier>{ matrix .id } </ows:Identifier>
323- <ScaleDenominator>{ matrix .scaleDenominator } </ScaleDenominator>
324- <TopLeftCorner>{ matrix .pointOfOrigin [0 ]} { matrix .pointOfOrigin [1 ]} </TopLeftCorner>
325- <TileWidth>{ matrix .tileWidth } </TileWidth>
326- <TileHeight>{ matrix .tileHeight } </TileHeight>
327- <MatrixWidth>{ matrix .matrixWidth } </MatrixWidth>
328- <MatrixHeight>{ matrix .matrixHeight } </MatrixHeight>
329- </TileMatrix>"""
330- tileMatrix .append (tm )
331-
332311 if use_epsg :
333312 supported_crs = f"EPSG:{ tms .crs .to_epsg ()} "
334313 else :
@@ -337,9 +316,9 @@ def wmts( # noqa: C901
337316 tileMatrixSet .append (
338317 {
339318 "id" : tms_id ,
340- "tilematrix" : tileMatrix ,
319+ "tilematrix" : tms_to_xml ( tms , tms_minzoom , tms_maxzoom ) ,
341320 "crs" : supported_crs ,
342- "limits" : tilematrix_limits ,
321+ "limits" : tms_limits_to_xml ( _limits ) ,
343322 }
344323 )
345324 except Exception as e : # noqa
@@ -351,11 +330,10 @@ def wmts( # noqa: C901
351330 bbox_crs_type = "BoundingBox"
352331 bbox_crs_uri = CRS_to_urn (self .crs ) # type: ignore
353332 # WGS88BoundingBox is always xy ordered, but BoundingBox must match the CRS order
354- with rasterio .Env (OSR_WKT_FORMAT = "WKT2_2018" ):
355- proj_crs = pyproj .CRS .from_user_input (self .crs )
356- if crs_axis_inverted (proj_crs ):
357- # match the bounding box coordinate order to the CRS
358- bounds = [bounds [1 ], bounds [0 ], bounds [3 ], bounds [2 ]]
333+ proj_crs = rio_crs_to_pyproj (self .crs )
334+ if crs_axis_inverted (proj_crs ):
335+ # match the bounding box coordinate order to the CRS
336+ bounds = [bounds [1 ], bounds [0 ], bounds [3 ], bounds [2 ]]
359337
360338 layers : list [dict [str , Any ]] = []
361339 for tilematrix in tileMatrixSet :
@@ -523,35 +501,9 @@ def wmts( # noqa: C901
523501 tms ,
524502 bounds ,
525503 zooms = (tms_minzoom , tms_maxzoom ),
504+ geographic_crs = self .crs ,
526505 )
527506
528- tilematrix_limits : list [str ] = []
529- for tms_limit in _limits :
530- tm = f"""
531- <TileMatrixLimits>
532- <TileMatrix>{ tms_limit ['tileMatrix' ]} </TileMatrix>
533- <MinTileRow>{ tms_limit ['minTileRow' ]} </MinTileRow>
534- <MaxTileRow>{ tms_limit ['maxTileRow' ]} </MaxTileRow>
535- <MinTileCol>{ tms_limit ['minTileCol' ]} </MinTileCol>
536- <MaxTileCol>{ tms_limit ['maxTileCol' ]} </MaxTileCol>
537- </TileMatrixLimits>"""
538- tilematrix_limits .append (tm )
539-
540- tileMatrix = []
541- for zoom in range (tms_minzoom , tms_maxzoom + 1 ):
542- matrix = tms .matrix (zoom )
543- tm = f"""
544- <TileMatrix>
545- <ows:Identifier>{ matrix .id } </ows:Identifier>
546- <ScaleDenominator>{ matrix .scaleDenominator } </ScaleDenominator>
547- <TopLeftCorner>{ matrix .pointOfOrigin [0 ]} { matrix .pointOfOrigin [1 ]} </TopLeftCorner>
548- <TileWidth>{ matrix .tileWidth } </TileWidth>
549- <TileHeight>{ matrix .tileHeight } </TileHeight>
550- <MatrixWidth>{ matrix .matrixWidth } </MatrixWidth>
551- <MatrixHeight>{ matrix .matrixHeight } </MatrixHeight>
552- </TileMatrix>"""
553- tileMatrix .append (tm )
554-
555507 if use_epsg :
556508 supported_crs = f"EPSG:{ tms .crs .to_epsg ()} "
557509 else :
@@ -560,9 +512,9 @@ def wmts( # noqa: C901
560512 tileMatrixSet .append (
561513 {
562514 "id" : tms_id ,
563- "tilematrix" : tileMatrix ,
515+ "tilematrix" : tms_to_xml ( tms , tms_minzoom , tms_maxzoom ) ,
564516 "crs" : supported_crs ,
565- "limits" : tilematrix_limits ,
517+ "limits" : tms_limits_to_xml ( _limits ) ,
566518 }
567519 )
568520 except Exception as e : # noqa
@@ -574,11 +526,10 @@ def wmts( # noqa: C901
574526 bbox_crs_type = "BoundingBox"
575527 bbox_crs_uri = CRS_to_urn (self .crs ) # type: ignore
576528 # WGS88BoundingBox is always xy ordered, but BoundingBox must match the CRS order
577- with rasterio .Env (OSR_WKT_FORMAT = "WKT2_2018" ):
578- proj_crs = pyproj .CRS .from_user_input (self .crs )
579- if crs_axis_inverted (proj_crs ):
580- # match the bounding box coordinate order to the CRS
581- bounds = [bounds [1 ], bounds [0 ], bounds [3 ], bounds [2 ]]
529+ proj_crs = rio_crs_to_pyproj (self .crs )
530+ if crs_axis_inverted (proj_crs ):
531+ # match the bounding box coordinate order to the CRS
532+ bounds = [bounds [1 ], bounds [0 ], bounds [3 ], bounds [2 ]]
582533
583534 layers : list [dict [str , Any ]] = []
584535 for tilematrix in tileMatrixSet :
0 commit comments