morecantile 6.0.0__py3-none-any.whl → 6.2.0__py3-none-any.whl

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.
morecantile/__init__.py CHANGED
@@ -8,7 +8,7 @@ Refs:
8
8
 
9
9
  """
10
10
 
11
- __version__ = "6.0.0"
11
+ __version__ = "6.2.0"
12
12
 
13
13
  from .commons import BoundingBox, Coords, Tile # noqa
14
14
  from .defaults import TileMatrixSets, tms # noqa
morecantile/defaults.py CHANGED
@@ -55,7 +55,7 @@ class TileMatrixSets:
55
55
  """Register TileMatrixSet(s)."""
56
56
  for identifier in custom_tms.keys():
57
57
  if identifier in self.tms and not overwrite:
58
- raise Exception(f"{identifier} is already a registered TMS.")
58
+ raise InvalidIdentifier(f"{identifier} is already a registered TMS.")
59
59
 
60
60
  return TileMatrixSets({**self.tms, **custom_tms})
61
61
 
morecantile/models.py CHANGED
@@ -488,10 +488,16 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
488
488
  _to_geographic: pyproj.Transformer = PrivateAttr()
489
489
  _from_geographic: pyproj.Transformer = PrivateAttr()
490
490
 
491
+ _tile_matrices_idx: Dict[int, int] = PrivateAttr()
492
+
491
493
  def __init__(self, **data):
492
494
  """Set private attributes."""
493
495
  super().__init__(**data)
494
496
 
497
+ self._tile_matrices_idx = {
498
+ int(mat.id): idx for idx, mat in enumerate(self.tileMatrices)
499
+ }
500
+
495
501
  try:
496
502
  self._to_geographic = pyproj.Transformer.from_crs(
497
503
  self.crs._pyproj_crs, self.crs._pyproj_crs.geodetic_crs, always_xy=True
@@ -504,6 +510,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
504
510
  "Could not create coordinate Transformer from input CRS to the given geographic CRS"
505
511
  "some methods might not be available.",
506
512
  UserWarning,
513
+ stacklevel=1,
507
514
  )
508
515
  self._to_geographic = None
509
516
  self._from_geographic = None
@@ -531,10 +538,8 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
531
538
  def is_variable(self) -> bool:
532
539
  """Check if TMS has variable width matrix."""
533
540
  return any(
534
- [
535
- True if matrix.variableMatrixWidths is not None else False
536
- for matrix in self.tileMatrices
537
- ]
541
+ True if matrix.variableMatrixWidths is not None else False
542
+ for matrix in self.tileMatrices
538
543
  )
539
544
 
540
545
  def __iter__(self):
@@ -765,9 +770,8 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
765
770
 
766
771
  def matrix(self, zoom: int) -> TileMatrix:
767
772
  """Return the TileMatrix for a specific zoom."""
768
- for m in self.tileMatrices:
769
- if m.id == str(zoom):
770
- return m
773
+ if (idx := self._tile_matrices_idx.get(zoom, None)) is not None:
774
+ return self.tileMatrices[idx]
771
775
 
772
776
  #######################################################################
773
777
  # If user wants a deeper matrix we calculate it
@@ -795,6 +799,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
795
799
  warnings.warn(
796
800
  f"TileMatrix not found for level: {zoom} - Creating values from TMS Scale.",
797
801
  UserWarning,
802
+ stacklevel=1,
798
803
  )
799
804
 
800
805
  # TODO: what if we want to construct a matrix for a level up ?
@@ -889,6 +894,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
889
894
  warnings.warn(
890
895
  f"Point ({x}, {y}) is outside TMS bounds {list(self.xy_bbox)}.",
891
896
  PointOutsideTMSBounds,
897
+ stacklevel=1,
892
898
  )
893
899
 
894
900
  lng, lat = self._to_geographic.transform(x, y)
@@ -908,6 +914,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
908
914
  warnings.warn(
909
915
  f"Point ({lng}, {lat}) is outside TMS bounds {list(self.bbox)}.",
910
916
  PointOutsideTMSBounds,
917
+ stacklevel=1,
911
918
  )
912
919
 
913
920
  x, y = self._from_geographic.transform(lng, lat)
@@ -1093,8 +1100,23 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
1093
1100
  """
1094
1101
  t = _parse_tile_arg(*tile)
1095
1102
 
1096
- left, top = self._ul(t)
1097
- right, bottom = self._lr(t)
1103
+ matrix = self.matrix(t.z)
1104
+ origin_x, origin_y = self._matrix_origin(matrix)
1105
+
1106
+ cf = (
1107
+ matrix.get_coalesce_factor(t.y)
1108
+ if matrix.variableMatrixWidths is not None
1109
+ else 1
1110
+ )
1111
+
1112
+ left = origin_x + math.floor(t.x / cf) * matrix.cellSize * cf * matrix.tileWidth
1113
+ top = origin_y - t.y * matrix.cellSize * matrix.tileHeight
1114
+ right = (
1115
+ origin_x
1116
+ + (math.floor(t.x / cf) + 1) * matrix.cellSize * cf * matrix.tileWidth
1117
+ )
1118
+ bottom = origin_y - (t.y + 1) * matrix.cellSize * matrix.tileHeight
1119
+
1098
1120
  return BoundingBox(left, bottom, right, top)
1099
1121
 
1100
1122
  def ul(self, *tile: Tile) -> Coords:
@@ -1146,10 +1168,10 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
1146
1168
  BoundingBox: The bounding box of the input tile.
1147
1169
 
1148
1170
  """
1149
- t = _parse_tile_arg(*tile)
1171
+ _left, _bottom, _right, _top = self.xy_bounds(*tile)
1172
+ left, top = self.lnglat(_left, _top)
1173
+ right, bottom = self.lnglat(_right, _bottom)
1150
1174
 
1151
- left, top = self.ul(t)
1152
- right, bottom = self.lr(t)
1153
1175
  return BoundingBox(left, bottom, right, top)
1154
1176
 
1155
1177
  @property
@@ -1352,6 +1374,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
1352
1374
  "CRS is no longer part of the GeoJSON specification."
1353
1375
  "Other projection than EPSG:4326 might not be supported.",
1354
1376
  UserWarning,
1377
+ stacklevel=1,
1355
1378
  )
1356
1379
  feat.update(
1357
1380
  {
morecantile/utils.py CHANGED
@@ -118,12 +118,10 @@ def is_power_of_two(number: int) -> bool:
118
118
  def check_quadkey_support(tms: List) -> bool:
119
119
  """Check if a Tile Matrix Set supports quadkeys"""
120
120
  return all(
121
- [
122
- (t.matrixWidth == t.matrixHeight)
123
- and is_power_of_two(t.matrixWidth)
124
- and ((t.matrixWidth * 2) == tms[i + 1].matrixWidth)
125
- for i, t in enumerate(tms[:-1])
126
- ]
121
+ (t.matrixWidth == t.matrixHeight)
122
+ and is_power_of_two(t.matrixWidth)
123
+ and ((t.matrixWidth * 2) == tms[i + 1].matrixWidth)
124
+ for i, t in enumerate(tms[:-1])
127
125
  )
128
126
 
129
127
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: morecantile
3
- Version: 6.0.0
3
+ Version: 6.2.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>
@@ -14,10 +14,13 @@ Classifier: Programming Language :: Python :: 3.9
14
14
  Classifier: Programming Language :: Python :: 3.10
15
15
  Classifier: Programming Language :: Python :: 3.11
16
16
  Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
17
18
  Classifier: Topic :: Scientific/Engineering :: GIS
18
19
  Requires-Dist: attrs
19
- Requires-Dist: pyproj~=3.1
20
+ Requires-Dist: pyproj>=3.1,<4.0
20
21
  Requires-Dist: pydantic~=2.0
22
+ Requires-Dist: pytest ; extra == "benchmark"
23
+ Requires-Dist: pytest-benchmark ; extra == "benchmark"
21
24
  Requires-Dist: pre-commit ; extra == "dev"
22
25
  Requires-Dist: bump-my-version ; extra == "dev"
23
26
  Requires-Dist: mkdocs>=1.4.3 ; extra == "docs"
@@ -32,6 +35,7 @@ Requires-Dist: pytest-cov ; extra == "test"
32
35
  Requires-Dist: rasterio>=1.2.1 ; extra == "test"
33
36
  Project-URL: Documentation, https://developmentseed.org/morecantile/
34
37
  Project-URL: Source, https://github.com/developmentseed/morecantile
38
+ Provides-Extra: benchmark
35
39
  Provides-Extra: dev
36
40
  Provides-Extra: docs
37
41
  Provides-Extra: rasterio
@@ -1,10 +1,10 @@
1
- morecantile/__init__.py,sha256=nU-M9zzFyyUJOGF9xw5-VjHdf30Ft4Kui1uizI32GzQ,436
1
+ morecantile/__init__.py,sha256=KRnysWzcvNgWYQZkJP1uG2KO_Ca-PbfZywfToeD36AE,436
2
2
  morecantile/commons.py,sha256=iHElysLSMu-zb3h1G1-AJnQrZ6y-2GseZkoBkOuzcZ8,1031
3
- morecantile/defaults.py,sha256=9lvHmZ9WM_J5uNCS9VWEy8O5_x2dA2Spvk4H5aHv6UQ,1804
3
+ morecantile/defaults.py,sha256=PYqEekETggu4yLKhPuU8FTTu04qpR0w_xhewIBkFS1E,1812
4
4
  morecantile/errors.py,sha256=rhtdpNglfEz5nC8I-BJKUr_gkOwAPwVi1vhLFJ2StYw,907
5
- morecantile/models.py,sha256=ZOA_J0cLVZd1Sknn1CW3bDRVwM1M6iVpIujb-Zm5bE8,51068
5
+ morecantile/models.py,sha256=muzqOjaZvIyk6mYXRywy0dT18W1eqLtyC4b1F0MgDeg,51966
6
6
  morecantile/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- morecantile/utils.py,sha256=-JUTcrwhT_TEWAPWV8YQBQJoYU2HfVkqQEJaggtnKJg,4020
7
+ morecantile/utils.py,sha256=wEdAc8cZE7iqnuEdfRBSWSzJtYpcIaC6I9eCewhqXy8,3984
8
8
  morecantile/data/CDB1GlobalGrid.json,sha256=VDc2ukAWtTQeCdOG8YMqsGO-D7eSzSCN1TEaBn2qLZI,36115
9
9
  morecantile/data/CanadianNAD83_LCC.json,sha256=RuR9z5MjxKzU4KE-CutrzjpWBz9c-XXykKAxcD83veU,7267
10
10
  morecantile/data/EuropeanETRS89_LAEAQuad.json,sha256=pR2Q7eAlLRG74SRdzYhXj19bf5qBvHrE6kzJ5cvko1Q,4679
@@ -21,8 +21,8 @@ morecantile/data/WorldCRS84Quad.json,sha256=l0Wf2faYwzRwO0mG-Tea1Vydpi7V1Oel5L9l
21
21
  morecantile/data/WorldMercatorWGS84Quad.json,sha256=JaqoBSu5qVJmL-J7oSVU1etP2OPWx_aVaTc68dGX0Ec,7001
22
22
  morecantile/scripts/__init__.py,sha256=-CJncfgWDnSZ8au-SJtgX-OFgCddlf7___d91qQcqQM,23
23
23
  morecantile/scripts/cli.py,sha256=TOc1RjLXuTzKs2FNNHQ3eCiGqiBoDFA4fKWpOAuY12s,17364
24
- morecantile-6.0.0.dist-info/entry_points.txt,sha256=keoXuYgnX-mdrGWwXIHqEkSZjQK_iAmtmdrtZ3sCT24,59
25
- morecantile-6.0.0.dist-info/LICENSE,sha256=18IxFIta7rF_RcVSIgLUUd_alyfQ9bGoZKQm5vOarGU,1073
26
- morecantile-6.0.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
27
- morecantile-6.0.0.dist-info/METADATA,sha256=LHgzSmCyr9fyl8iYdOX1sPRExHAa38Vd1YnDZFOOp04,7140
28
- morecantile-6.0.0.dist-info/RECORD,,
24
+ morecantile-6.2.0.dist-info/entry_points.txt,sha256=keoXuYgnX-mdrGWwXIHqEkSZjQK_iAmtmdrtZ3sCT24,59
25
+ morecantile-6.2.0.dist-info/LICENSE,sha256=18IxFIta7rF_RcVSIgLUUd_alyfQ9bGoZKQm5vOarGU,1073
26
+ morecantile-6.2.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
27
+ morecantile-6.2.0.dist-info/METADATA,sha256=fDX754cdrEPZvGR7vJR2d4jUck4aJhRZ0ALxcyDwvcs,7322
28
+ morecantile-6.2.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: flit 3.9.0
2
+ Generator: flit 3.10.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any