morecantile 5.4.2__tar.gz → 6.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. {morecantile-5.4.2 → morecantile-6.1.0}/.gitignore +4 -0
  2. {morecantile-5.4.2 → morecantile-6.1.0}/PKG-INFO +8 -3
  3. morecantile-6.1.0/benchmarks/README.md +63 -0
  4. morecantile-6.1.0/benchmarks/benchmarks.py +96 -0
  5. morecantile-6.1.0/benchmarks/requirements.txt +6 -0
  6. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/__init__.py +1 -1
  7. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/commons.py +4 -4
  8. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/models.py +31 -21
  9. {morecantile-5.4.2 → morecantile-6.1.0}/pyproject.toml +9 -3
  10. {morecantile-5.4.2 → morecantile-6.1.0}/.pre-commit-config.yaml +0 -0
  11. {morecantile-5.4.2 → morecantile-6.1.0}/LICENSE +0 -0
  12. {morecantile-5.4.2 → morecantile-6.1.0}/README.md +0 -0
  13. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/CDB1GlobalGrid.json +0 -0
  14. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/CanadianNAD83_LCC.json +0 -0
  15. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/EuropeanETRS89_LAEAQuad.json +0 -0
  16. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/GNOSISGlobalGrid.json +0 -0
  17. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/LINZAntarticaMapTilegrid.json +0 -0
  18. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/NZTM2000Quad.json +0 -0
  19. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/README.md +0 -0
  20. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/UPSAntarcticWGS84Quad.json +0 -0
  21. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/UPSArcticWGS84Quad.json +0 -0
  22. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/UTM31WGS84Quad.json +0 -0
  23. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/WGS1984Quad.json +0 -0
  24. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/WebMercatorQuad.json +0 -0
  25. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/WorldCRS84Quad.json +0 -0
  26. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/data/WorldMercatorWGS84Quad.json +0 -0
  27. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/defaults.py +0 -0
  28. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/errors.py +0 -0
  29. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/py.typed +0 -0
  30. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/scripts/__init__.py +0 -0
  31. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/scripts/cli.py +0 -0
  32. {morecantile-5.4.2 → morecantile-6.1.0}/morecantile/utils.py +0 -0
@@ -130,3 +130,7 @@ dmypy.json
130
130
 
131
131
  # PyCharm:
132
132
  .idea
133
+
134
+ # VSCode
135
+ .vscode
136
+ .vscode/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: morecantile
3
- Version: 5.4.2
3
+ Version: 6.1.0
4
4
  Summary: Construct and use map tile grids (a.k.a TileMatrixSet / TMS).
5
5
  Keywords: GIS,TMS,TileMatrixSet,Map Tile
6
6
  Author-email: Vincent Sarago <vincent@developmentseed.com>
@@ -18,10 +18,14 @@ Classifier: Topic :: Scientific/Engineering :: GIS
18
18
  Requires-Dist: attrs
19
19
  Requires-Dist: pyproj~=3.1
20
20
  Requires-Dist: pydantic~=2.0
21
+ Requires-Dist: pytest ; extra == "benchmark"
22
+ Requires-Dist: pytest-benchmark ; extra == "benchmark"
21
23
  Requires-Dist: pre-commit ; extra == "dev"
22
24
  Requires-Dist: bump-my-version ; extra == "dev"
23
- Requires-Dist: mkdocs ; extra == "docs"
24
- Requires-Dist: mkdocs-material ; extra == "docs"
25
+ Requires-Dist: mkdocs>=1.4.3 ; extra == "docs"
26
+ Requires-Dist: mkdocs-material[imaging]>=9.5 ; extra == "docs"
27
+ Requires-Dist: griffe-inherited-docstrings>=1.0.0 ; extra == "docs"
28
+ Requires-Dist: mkdocstrings[python]>=0.25.1 ; extra == "docs"
25
29
  Requires-Dist: pygments ; extra == "docs"
26
30
  Requires-Dist: rasterio>=1.2.1 ; extra == "rasterio"
27
31
  Requires-Dist: mercantile ; extra == "test"
@@ -30,6 +34,7 @@ Requires-Dist: pytest-cov ; extra == "test"
30
34
  Requires-Dist: rasterio>=1.2.1 ; extra == "test"
31
35
  Project-URL: Documentation, https://developmentseed.org/morecantile/
32
36
  Project-URL: Source, https://github.com/developmentseed/morecantile
37
+ Provides-Extra: benchmark
33
38
  Provides-Extra: dev
34
39
  Provides-Extra: docs
35
40
  Provides-Extra: rasterio
@@ -0,0 +1,63 @@
1
+
2
+ ## Benchmark
3
+
4
+ Compare `mercantile`, `utiles` and `morecantile`
5
+
6
+ ```sh
7
+ python -m pip install -r requirements.txt
8
+ python -m pytest benchmarks.py --benchmark-only --benchmark-columns 'min, max, mean, median' --benchmark-sort 'min'
9
+ ```
10
+
11
+ ```
12
+ ----------------------------------------------------- benchmark 'bounds': 21 tests ----------------------------------------------------
13
+ Name (time in ns) Min Max Mean Median
14
+ ---------------------------------------------------------------------------------------------------------------------------------------
15
+ test_bounds[utiles-(486, 332, 30)] 83.0000 (1.0) 52,000.0000 (52.97) 195.3371 (1.48) 208.0000 (1.60)
16
+ test_bounds[utiles-(0, 0, 0)] 83.0000 (1.00) 31,167.0000 (31.75) 193.5957 (1.47) 208.0000 (1.60)
17
+ test_bounds[utiles-(1, 0, 1)] 125.0000 (1.51) 981.6700 (1.0) 132.0177 (1.0) 130.8300 (1.01)
18
+ test_bounds[utiles-(1, 40, 7)] 125.0000 (1.51) 8,606.2500 (8.77) 132.5298 (1.00) 130.0000 (1.0)
19
+ test_bounds[utiles-(486, 332, 10)] 128.3300 (1.55) 1,600.8300 (1.63) 133.4046 (1.01) 131.6700 (1.01)
20
+ test_bounds[utiles-(1, 1, 1)] 129.5900 (1.56) 16,846.2500 (17.16) 141.9846 (1.08) 134.1700 (1.03)
21
+ test_bounds[utiles-(486, 332, 20)] 138.3300 (1.67) 1,123.3300 (1.14) 142.5420 (1.08) 141.2500 (1.09)
22
+ test_bounds[mercantile-(1, 40, 7)] 1,000.0000 (12.05) 92,416.0000 (94.14) 1,193.0112 (9.04) 1,167.0000 (8.98)
23
+ test_bounds[mercantile-(1, 1, 1)] 1,075.0000 (12.95) 48,066.8000 (48.96) 1,154.8100 (8.75) 1,141.6000 (8.78)
24
+ test_bounds[mercantile-(0, 0, 0)] 1,083.0000 (13.05) 21,041.0000 (21.43) 1,214.6049 (9.20) 1,208.0000 (9.29)
25
+ test_bounds[mercantile-(1, 0, 1)] 1,083.0000 (13.05) 75,291.0000 (76.70) 1,213.7837 (9.19) 1,208.0000 (9.29)
26
+ test_bounds[mercantile-(486, 332, 10)] 1,083.0000 (13.05) 55,750.0000 (56.79) 1,223.7598 (9.27) 1,208.0000 (9.29)
27
+ test_bounds[mercantile-(486, 332, 20)] 1,083.0000 (13.05) 89,041.0000 (90.70) 1,248.4256 (9.46) 1,209.0000 (9.30)
28
+ test_bounds[mercantile-(486, 332, 30)] 1,083.0000 (13.05) 194,958.0000 (198.60) 1,239.4339 (9.39) 1,209.0000 (9.30)
29
+ test_bounds[morecantile-(1, 0, 1)] 20,083.0000 (241.96) 132,625.0000 (135.10) 20,893.1235 (158.26) 20,667.0000 (158.98)
30
+ test_bounds[morecantile-(0, 0, 0)] 20,166.0000 (242.96) 120,333.0000 (122.58) 20,974.1961 (158.87) 20,708.0000 (159.29)
31
+ test_bounds[morecantile-(1, 1, 1)] 20,334.0000 (244.99) 60,958.0000 (62.10) 21,236.2953 (160.86) 20,750.0000 (159.62)
32
+ test_bounds[morecantile-(1, 40, 7)] 21,667.0000 (261.05) 173,458.0000 (176.70) 22,622.6537 (171.36) 22,333.0000 (171.79)
33
+ test_bounds[morecantile-(486, 332, 10)] 22,166.0000 (267.06) 205,125.0000 (208.96) 23,512.1607 (178.10) 22,875.0000 (175.96)
34
+ test_bounds[morecantile-(486, 332, 20)] 24,708.0000 (297.69) 129,250.0000 (131.66) 25,775.0796 (195.24) 25,375.0000 (195.19)
35
+ test_bounds[morecantile-(486, 332, 30)] 71,292.0000 (858.94) 205,625.0000 (209.46) 73,569.4565 (557.27) 72,667.0000 (558.98)
36
+ ---------------------------------------------------------------------------------------------------------------------------------------
37
+
38
+ ---------------------------------------------------- benchmark 'xy_bounds': 21 tests -----------------------------------------------------
39
+ Name (time in ns) Min Max Mean Median
40
+ ------------------------------------------------------------------------------------------------------------------------------------------
41
+ test_xy_bounds[utiles-(0, 0, 0)] 83.0000 (1.0) 57,375.0000 (112.55) 145.9127 (1.57) 125.0000 (1.36)
42
+ test_xy_bounds[utiles-(1, 1, 1)] 88.3400 (1.06) 1,335.4200 (2.62) 93.1478 (1.00) 92.5000 (1.00)
43
+ test_xy_bounds[utiles-(1, 40, 7)] 88.7500 (1.07) 1,451.2500 (2.85) 93.1258 (1.0) 92.0900 (1.0)
44
+ test_xy_bounds[utiles-(1, 0, 1)] 89.5900 (1.08) 861.6600 (1.69) 93.6428 (1.01) 93.3300 (1.01)
45
+ test_xy_bounds[utiles-(486, 332, 10)] 90.0000 (1.08) 509.7950 (1.0) 93.2818 (1.00) 92.9150 (1.01)
46
+ test_xy_bounds[utiles-(486, 332, 20)] 90.4100 (1.09) 864.1700 (1.70) 94.2974 (1.01) 94.1600 (1.02)
47
+ test_xy_bounds[utiles-(486, 332, 30)] 90.4100 (1.09) 1,377.5000 (2.70) 94.7366 (1.02) 94.1600 (1.02)
48
+ test_xy_bounds[mercantile-(0, 0, 0)] 708.0000 (8.53) 42,250.0000 (82.88) 843.2292 (9.05) 833.0000 (9.05)
49
+ test_xy_bounds[mercantile-(486, 332, 10)] 731.2500 (8.81) 5,393.7500 (10.58) 770.8331 (8.28) 764.6000 (8.30)
50
+ test_xy_bounds[mercantile-(486, 332, 30)] 731.2500 (8.81) 7,316.6500 (14.35) 770.2423 (8.27) 764.6000 (8.30)
51
+ test_xy_bounds[mercantile-(1, 0, 1)] 732.1429 (8.82) 9,404.8571 (18.45) 791.7721 (8.50) 785.7143 (8.53)
52
+ test_xy_bounds[mercantile-(1, 40, 7)] 733.3000 (8.83) 5,950.0000 (11.67) 772.3273 (8.29) 766.7000 (8.33)
53
+ test_xy_bounds[mercantile-(486, 332, 20)] 733.3500 (8.84) 7,408.3000 (14.53) 773.4718 (8.31) 768.7500 (8.35)
54
+ test_xy_bounds[mercantile-(1, 1, 1)] 735.4000 (8.86) 4,762.5000 (9.34) 783.2100 (8.41) 777.1000 (8.44)
55
+ test_xy_bounds[morecantile-(0, 0, 0)] 3,042.0000 (36.65) 108,208.0000 (212.26) 3,287.1089 (35.30) 3,250.0000 (35.29)
56
+ test_xy_bounds[morecantile-(1, 0, 1)] 3,291.0000 (39.65) 68,166.0000 (133.71) 3,503.4695 (37.62) 3,459.0000 (37.56)
57
+ test_xy_bounds[morecantile-(1, 1, 1)] 3,291.0000 (39.65) 72,875.0000 (142.95) 3,506.8544 (37.66) 3,500.0000 (38.01)
58
+ test_xy_bounds[morecantile-(1, 40, 7)] 4,375.0000 (52.71) 76,375.0000 (149.82) 4,630.2893 (49.72) 4,584.0000 (49.78)
59
+ test_xy_bounds[morecantile-(486, 332, 10)] 4,875.0000 (58.73) 85,208.0000 (167.14) 5,197.3581 (55.81) 5,125.0000 (55.65)
60
+ test_xy_bounds[morecantile-(486, 332, 20)] 6,916.0000 (83.33) 78,458.0000 (153.90) 7,221.0669 (77.54) 7,166.0000 (77.82)
61
+ test_xy_bounds[morecantile-(486, 332, 30)] 52,667.0000 (634.54) 404,208.0000 (792.88) 54,749.1232 (587.90) 54,333.0000 (590.00)
62
+ ------------------------------------------------------------------------------------------------------------------------------------------
63
+ ```
@@ -0,0 +1,96 @@
1
+ """Morecantile/Mercantile/Utiles comparison benchmark
2
+
3
+ The benchmark suite is adapted from jessekrubin/utiles
4
+ https://github.com/jessekrubin/utiles/blob/ea58b9a017a2e3528f03cc20f16ef531737b863f/utiles-pyo3/bench/test_bench.py#L17-L25
5
+ """
6
+ # This file is a modified version of https://github.com/jessekrubin/utiles/blob/ea58b9a017a2e3528f03cc20f16ef531737b863f/utiles-pyo3/bench/test_bench.py.
7
+ #
8
+ # The original license follows.
9
+ #
10
+ # MIT License
11
+ #
12
+ # Copyright (c) 2023 jessekrubin
13
+ #
14
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ # of this software and associated documentation files (the "Software"), to deal
16
+ # in the Software without restriction, including without limitation the rights
17
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ # copies of the Software, and to permit persons to whom the Software is
19
+ # furnished to do so, subject to the following conditions:
20
+ #
21
+ # The above copyright notice and this permission notice shall be included in all
22
+ # copies or substantial portions of the Software.
23
+ #
24
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ # SOFTWARE.
31
+
32
+ from typing import Callable, Tuple
33
+
34
+ import mercantile
35
+ import pytest
36
+ import utiles
37
+
38
+ import morecantile
39
+
40
+ tms = morecantile.tms.get("WebMercatorQuad")
41
+
42
+ TEST_TILES = (
43
+ (0, 0, 0),
44
+ (1, 0, 1),
45
+ (1, 1, 1),
46
+ (1, 40, 7),
47
+ (486, 332, 10),
48
+ # HIGH ZOOM
49
+ (486, 332, 20),
50
+ # OUTSIDE TMS Range
51
+ (486, 332, 30),
52
+ )
53
+
54
+
55
+ @pytest.mark.parametrize(
56
+ "tile",
57
+ [pytest.param(t, id=str(t)) for t in TEST_TILES],
58
+ )
59
+ @pytest.mark.parametrize(
60
+ "func",
61
+ [
62
+ pytest.param(mercantile.bounds, id="mercantile"),
63
+ pytest.param(tms.bounds, id="morecantile"),
64
+ pytest.param(utiles.bounds, id="utiles"),
65
+ ],
66
+ )
67
+ @pytest.mark.benchmark(group="bounds")
68
+ def test_bounds(
69
+ tile: Tuple[int, int, int],
70
+ func: Callable[[Tuple[int, int, int]], Tuple[float, float]],
71
+ benchmark,
72
+ ) -> None:
73
+ """Benchmark bounds() method."""
74
+ _ = benchmark(func, *tile)
75
+
76
+
77
+ @pytest.mark.parametrize(
78
+ "tile",
79
+ [pytest.param(t, id=str(t)) for t in TEST_TILES],
80
+ )
81
+ @pytest.mark.parametrize(
82
+ "func",
83
+ [
84
+ pytest.param(mercantile.xy_bounds, id="mercantile"),
85
+ pytest.param(tms.xy_bounds, id="morecantile"),
86
+ pytest.param(utiles.xy_bounds, id="utiles"),
87
+ ],
88
+ )
89
+ @pytest.mark.benchmark(group="xy_bounds")
90
+ def test_xy_bounds(
91
+ tile: Tuple[int, int, int],
92
+ func: Callable[[Tuple[int, int, int]], Tuple[float, float]],
93
+ benchmark,
94
+ ) -> None:
95
+ """Benchmark xy_bounds() method."""
96
+ _ = benchmark(func, *tile)
@@ -0,0 +1,6 @@
1
+ pytest
2
+ pytest-benchmark
3
+
4
+ morecantile
5
+ mercantile
6
+ utiles
@@ -8,7 +8,7 @@ Refs:
8
8
 
9
9
  """
10
10
 
11
- __version__ = "5.4.2"
11
+ __version__ = "6.1.0"
12
12
 
13
13
  from .commons import BoundingBox, Coords, Tile # noqa
14
14
  from .defaults import TileMatrixSets, tms # noqa
@@ -7,10 +7,10 @@ class BoundingBox(NamedTuple):
7
7
  """A xmin,ymin,xmax,ymax coordinates tuple.
8
8
 
9
9
  Args:
10
- left (number): min horizontal coordinate.
11
- bottom (number):min vertical coordinate.
12
- right (number): max horizontal coordinate.
13
- top (number): max vertical coordinate.
10
+ left (number): min horizontal coordinate.
11
+ bottom (number):min vertical coordinate.
12
+ right (number): max horizontal coordinate.
13
+ top (number): max vertical coordinate.
14
14
 
15
15
  Examples:
16
16
  >>> BoundingBox(-180.0, -90.0, 180.0, 90.0)
@@ -40,7 +40,6 @@ from morecantile.utils import (
40
40
  NumType = Union[float, int]
41
41
  BoundsType = Tuple[NumType, NumType]
42
42
  LL_EPSILON = 1e-11
43
- WGS84_CRS = pyproj.CRS.from_epsg(4326)
44
43
  axesInfo = Annotated[List[str], Field(min_length=2, max_length=2)]
45
44
 
46
45
 
@@ -486,24 +485,25 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
486
485
  ]
487
486
 
488
487
  # Private attributes
489
- _geographic_crs: pyproj.CRS = PrivateAttr(default=WGS84_CRS)
490
488
  _to_geographic: pyproj.Transformer = PrivateAttr()
491
489
  _from_geographic: pyproj.Transformer = PrivateAttr()
492
490
 
491
+ _tile_matrices_idx: Dict[int, int] = PrivateAttr()
492
+
493
493
  def __init__(self, **data):
494
494
  """Set private attributes."""
495
495
  super().__init__(**data)
496
496
 
497
- self._geographic_crs = pyproj.CRS.from_user_input(
498
- data.get("_geographic_crs", WGS84_CRS)
499
- )
497
+ self._tile_matrices_idx = {
498
+ int(mat.id): idx for idx, mat in enumerate(self.tileMatrices)
499
+ }
500
500
 
501
501
  try:
502
502
  self._to_geographic = pyproj.Transformer.from_crs(
503
- self.crs._pyproj_crs, self._geographic_crs, always_xy=True
503
+ self.crs._pyproj_crs, self.crs._pyproj_crs.geodetic_crs, always_xy=True
504
504
  )
505
505
  self._from_geographic = pyproj.Transformer.from_crs(
506
- self._geographic_crs, self.crs._pyproj_crs, always_xy=True
506
+ self.crs._pyproj_crs.geodetic_crs, self.crs._pyproj_crs, always_xy=True
507
507
  )
508
508
  except ProjError:
509
509
  warnings.warn(
@@ -555,7 +555,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
555
555
  @cached_property
556
556
  def geographic_crs(self) -> pyproj.CRS:
557
557
  """Return the TMS's geographic CRS."""
558
- return self._geographic_crs
558
+ return self.crs._pyproj_crs.geodetic_crs
559
559
 
560
560
  @cached_property
561
561
  def rasterio_crs(self):
@@ -565,7 +565,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
565
565
  @cached_property
566
566
  def rasterio_geographic_crs(self):
567
567
  """Return the geographic CRS as a rasterio CRS."""
568
- return to_rasterio_crs(self._geographic_crs)
568
+ return to_rasterio_crs(self.crs._pyproj_crs.geodetic_crs)
569
569
 
570
570
  @property
571
571
  def minzoom(self) -> int:
@@ -656,7 +656,6 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
656
656
  title: Optional[str] = None,
657
657
  id: Optional[str] = None,
658
658
  ordered_axes: Optional[List[str]] = None,
659
- geographic_crs: pyproj.CRS = WGS84_CRS,
660
659
  screen_pixel_size: float = 0.28e-3,
661
660
  decimation_base: int = 2,
662
661
  **kwargs: Any,
@@ -689,8 +688,6 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
689
688
  Tile Matrix Set title
690
689
  id: str, optional
691
690
  Tile Matrix Set identifier
692
- geographic_crs: pyproj.CRS
693
- Geographic (lat,lon) coordinate reference system (default is EPSG:4326)
694
691
  ordered_axes: list of str, optional
695
692
  Override Axis order (e.g `["N", "S"]`) else default to CRS's metadata
696
693
  screen_pixel_size: float, optional
@@ -769,15 +766,13 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
769
766
  tileMatrices=tile_matrices,
770
767
  id=id,
771
768
  title=title,
772
- _geographic_crs=geographic_crs,
773
769
  **kwargs,
774
770
  )
775
771
 
776
772
  def matrix(self, zoom: int) -> TileMatrix:
777
773
  """Return the TileMatrix for a specific zoom."""
778
- for m in self.tileMatrices:
779
- if m.id == str(zoom):
780
- return m
774
+ if (idx := self._tile_matrices_idx.get(zoom, None)) is not None:
775
+ return self.tileMatrices[idx]
781
776
 
782
777
  #######################################################################
783
778
  # If user wants a deeper matrix we calculate it
@@ -1103,8 +1098,23 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
1103
1098
  """
1104
1099
  t = _parse_tile_arg(*tile)
1105
1100
 
1106
- left, top = self._ul(t)
1107
- right, bottom = self._lr(t)
1101
+ matrix = self.matrix(t.z)
1102
+ origin_x, origin_y = self._matrix_origin(matrix)
1103
+
1104
+ cf = (
1105
+ matrix.get_coalesce_factor(t.y)
1106
+ if matrix.variableMatrixWidths is not None
1107
+ else 1
1108
+ )
1109
+
1110
+ left = origin_x + math.floor(t.x / cf) * matrix.cellSize * cf * matrix.tileWidth
1111
+ top = origin_y - t.y * matrix.cellSize * matrix.tileHeight
1112
+ right = (
1113
+ origin_x
1114
+ + (math.floor(t.x / cf) + 1) * matrix.cellSize * cf * matrix.tileWidth
1115
+ )
1116
+ bottom = origin_y - (t.y + 1) * matrix.cellSize * matrix.tileHeight
1117
+
1108
1118
  return BoundingBox(left, bottom, right, top)
1109
1119
 
1110
1120
  def ul(self, *tile: Tile) -> Coords:
@@ -1156,10 +1166,10 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
1156
1166
  BoundingBox: The bounding box of the input tile.
1157
1167
 
1158
1168
  """
1159
- t = _parse_tile_arg(*tile)
1169
+ _left, _bottom, _right, _top = self.xy_bounds(*tile)
1170
+ left, top = self.lnglat(_left, _top)
1171
+ right, bottom = self.lnglat(_right, _bottom)
1160
1172
 
1161
- left, top = self.ul(t)
1162
- right, bottom = self.lr(t)
1163
1173
  return BoundingBox(left, bottom, right, top)
1164
1174
 
1165
1175
  @property
@@ -36,13 +36,19 @@ test = [
36
36
  "pytest-cov",
37
37
  "rasterio>=1.2.1",
38
38
  ]
39
+ benchmark = [
40
+ "pytest",
41
+ "pytest-benchmark",
42
+ ]
39
43
  dev = [
40
44
  "pre-commit",
41
45
  "bump-my-version",
42
46
  ]
43
47
  docs = [
44
- "mkdocs",
45
- "mkdocs-material",
48
+ "mkdocs>=1.4.3",
49
+ "mkdocs-material[imaging]>=9.5",
50
+ "griffe-inherited-docstrings>=1.0.0",
51
+ "mkdocstrings[python]>=0.25.1",
46
52
  "pygments",
47
53
  ]
48
54
 
@@ -114,7 +120,7 @@ filterwarnings = [
114
120
  ]
115
121
 
116
122
  [tool.bumpversion]
117
- current_version = "5.4.2"
123
+ current_version = "6.1.0"
118
124
 
119
125
  search = "{current_version}"
120
126
  replace = "{new_version}"
File without changes
File without changes