Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### titiler.core

* update `TileJSON` spec from 2.2.0 to 3.0.0

## 0.24.1 (2025-10-10)

* add `grayscale` and `bitonal` algorithms
Expand Down
2 changes: 1 addition & 1 deletion src/titiler/application/tests/routes/test_cog.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ def test_tilejson(rio, app):
)
assert response.status_code == 200
body = response.json()
assert body["tilejson"] == "2.2.0"
assert body["tilejson"] == "3.0.0"
assert body["version"] == "1.0.0"
assert body["scheme"] == "xyz"
assert len(body["tiles"]) == 1
Expand Down
2 changes: 1 addition & 1 deletion src/titiler/application/tests/routes/test_stac.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def test_tilejson(httpx, rio, app):
)
assert response.status_code == 200
body = response.json()
assert body["tilejson"] == "2.2.0"
assert body["tilejson"] == "3.0.0"
assert body["version"] == "1.0.0"
assert body["scheme"] == "xyz"
assert len(body["tiles"]) == 1
Expand Down
10 changes: 7 additions & 3 deletions src/titiler/core/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
def test_tilejson_model():
"""Make sure TileJSON model validates input and return default."""
tj = TileJSON(tiles=["https://something.xyz/{x}/{y}/{z}"])
assert tj.center == (0.0, 0.0, 0)
assert tj.bounds == [-180, -90, 180, 90]
assert list(map(round, tj.center)) == [0.0, 0.0, 0]
assert tj.bounds == [-180, -85.0511287798066, 180, 85.0511287798066]
assert tj.minzoom == 0
assert tj.maxzoom == 30
assert tj.scheme == "xyz"
Expand All @@ -19,8 +19,12 @@ def test_tilejson_model():
tiles=["https://something.xyz/{x}/{y}/{z}"], center=(10, 10, 4), scheme="tms"
)
assert tj.center == (10.0, 10.0, 4)
assert tj.bounds == [-180, -90, 180, 90]
assert tj.bounds == [-180, -85.0511287798066, 180, 85.0511287798066]
assert tj.scheme == "tms"

with pytest.raises(ValidationError):
TileJSON(tiles=["https://something.xyz/{x}/{y}/{z}"], scheme="abc")

# Check extra fields are allowed
tj = TileJSON(tiles=["https://something.xyz/{x}/{y}/{z}"], dtype="uint8")
assert tj.dtype == "uint8"
28 changes: 21 additions & 7 deletions src/titiler/core/titiler/core/models/mapbox.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
"""Common response models."""

from typing import List, Literal, Optional, Tuple
from typing import Annotated, Dict, List, Literal, Optional, Tuple

from pydantic import BaseModel, Field, model_validator


class TileJSON(BaseModel):
class LayerJSON(BaseModel):
"""
https://github.com/mapbox/tilejson-spec/tree/master/3.0.0#33-vector_layers
"""

id: str
fields: Annotated[Dict, Field(default_factory=dict)]
description: Optional[str] = None
minzoom: Optional[int] = None
maxzoom: Optional[int] = None


class TileJSON(BaseModel, extra="allow"):
"""
TileJSON model.

Based on https://github.com/mapbox/tilejson-spec/tree/master/2.2.0
Based on https://github.com/mapbox/tilejson-spec/tree/master/3.0.0

"""

tilejson: str = "2.2.0"
tilejson: str = "3.0.0"
name: Optional[str] = None
description: Optional[str] = None
version: str = "1.0.0"
Expand All @@ -22,11 +34,13 @@ class TileJSON(BaseModel):
legend: Optional[str] = None
scheme: Literal["xyz", "tms"] = "xyz"
tiles: List[str]
vector_layers: Optional[List[LayerJSON]] = None
grids: Optional[List[str]] = None
data: Optional[List[str]] = None
minzoom: int = Field(0, ge=0, le=30)
maxzoom: int = Field(30, ge=0, le=30)
bounds: List[float] = [-180, -90, 180, 90]
minzoom: int = Field(0)
maxzoom: int = Field(30)
fillzoom: Optional[int] = None
bounds: List[float] = [-180, -85.0511287798066, 180, 85.0511287798066]
center: Optional[Tuple[float, float, int]] = None

@model_validator(mode="after")
Expand Down
Loading