Skip to content

Commit d9d3633

Browse files
Merge pull request #177 from developmentseed/feature/strict_tile_validation
check maxzoom in is_valid
2 parents 9600968 + b04ce75 commit d9d3633

File tree

4 files changed

+52
-2
lines changed

4 files changed

+52
-2
lines changed

CHANGES.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,23 @@
22
## Unreleased
33

44
* remove python 3.8 support
5+
* check tile's zoom against TMS's `maxzoom` in `TileMatrixSet.is_valid` and add `strict=True|False` options
6+
7+
```python
8+
import morecantile
9+
tms = morecantile.tms.get("WebMercatorQuad")
10+
11+
# before
12+
assert tms.is_valid(0, 0, 25)
13+
>> UserWarning: TileMatrix not found for level: 25 - Creating values from TMS Scale.
14+
15+
# now
16+
assert tms.is_valid(0, 0, 25), "Tile(0, 0, 25) is not valid"
17+
>> AssertionError: Tile(0, 0, 25) is not valid
18+
19+
assert tms.is_valid(0, 0, 25, strict=False)
20+
>> UserWarning: TileMatrix not found for level: 25 - Creating values from TMS Scale.
21+
```
522

623
## 6.2.0 (2024-12-19)
724

morecantile/models.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,11 +1480,12 @@ def minmax(self, zoom: int) -> Dict:
14801480
"y": {"min": 0, "max": m.matrixHeight - 1},
14811481
}
14821482

1483-
def is_valid(self, *tile: Tile) -> bool:
1483+
def is_valid(self, *tile: Tile, strict: bool = True) -> bool:
14841484
"""Check if a tile is valid."""
14851485
t = _parse_tile_arg(*tile)
14861486

1487-
if t.z < self.minzoom:
1487+
disable_overzoom = self.is_variable or strict
1488+
if t.z < self.minzoom or (disable_overzoom and t.z > self.maxzoom):
14881489
return False
14891490

14901491
matrix = self.matrix(t.z)

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ dependencies = [
2424
"attrs",
2525
"pyproj>=3.1,<4.0",
2626
"pydantic~=2.0",
27+
"click",
2728
]
2829

2930
[project.optional-dependencies]
@@ -35,6 +36,8 @@ test = [
3536
"pytest",
3637
"pytest-cov",
3738
"rasterio>=1.2.1",
39+
# ref: https://github.com/pallets/click/issues/2939
40+
"click!=8.2.1,!=8.2.2",
3841
]
3942
benchmark = [
4043
"pytest",

tests/test_morecantile.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,9 +529,19 @@ def test_is_power_of_two():
529529
@pytest.mark.parametrize(
530530
"t,res",
531531
[
532+
# X Y Z
532533
(morecantile.Tile(0, 0, 0), True),
534+
# zoom 0 has only tile 0,0,0 valid
533535
(morecantile.Tile(1, 0, 0), False),
536+
# MinZoom is 0
534537
(morecantile.Tile(0, 0, -1), False),
538+
# MaxZoom is 24
539+
(morecantile.Tile(0, 0, 24), True),
540+
(morecantile.Tile(0, 0, 25), False),
541+
# Negative X
542+
(morecantile.Tile(-1, 0, 1), False),
543+
# Negative Y
544+
(morecantile.Tile(0, -1, 1), False),
535545
],
536546
)
537547
def test_is_valid_tile(t, res):
@@ -540,6 +550,25 @@ def test_is_valid_tile(t, res):
540550
assert tms.is_valid(t) == res
541551

542552

553+
def test_is_valid_overzoom():
554+
"""test if tile are valid."""
555+
tms = morecantile.tms.get("WebMercatorQuad")
556+
t = morecantile.Tile(0, 0, 25)
557+
assert tms.is_valid(t, strict=False)
558+
assert not tms.is_valid(t, strict=True)
559+
560+
tms = morecantile.tms.get("GNOSISGlobalGrid")
561+
t = morecantile.Tile(0, 0, 28)
562+
assert tms.is_valid(t, strict=False)
563+
564+
t = morecantile.Tile(0, 0, 29)
565+
assert not tms.is_valid(t, strict=False)
566+
567+
# We can't overzoom VariableMatrixWidth TMS
568+
t = morecantile.Tile(0, 0, 29)
569+
assert not tms.is_valid(t)
570+
571+
543572
def test_neighbors():
544573
"""test neighbors."""
545574
tms = morecantile.tms.get("WebMercatorQuad")

0 commit comments

Comments
 (0)