morecantile 7.0.0__tar.gz → 7.0.1__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.
- {morecantile-7.0.0 → morecantile-7.0.1}/PKG-INFO +1 -1
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/__init__.py +1 -1
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/defaults.py +4 -5
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/models.py +62 -54
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/utils.py +3 -4
- {morecantile-7.0.0 → morecantile-7.0.1}/pyproject.toml +1 -4
- {morecantile-7.0.0 → morecantile-7.0.1}/.gitignore +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/LICENSE +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/README.md +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/commons.py +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/CDB1GlobalGrid.json +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/CanadianNAD83_LCC.json +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/EuropeanETRS89_LAEAQuad.json +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/GNOSISGlobalGrid.json +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/LINZAntarticaMapTilegrid.json +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/NZTM2000Quad.json +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/README.md +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/UPSAntarcticWGS84Quad.json +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/UPSArcticWGS84Quad.json +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/UTM31WGS84Quad.json +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/WGS1984Quad.json +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/WebMercatorQuad.json +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/WorldCRS84Quad.json +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/data/WorldMercatorWGS84Quad.json +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/errors.py +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/py.typed +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/scripts/__init__.py +0 -0
- {morecantile-7.0.0 → morecantile-7.0.1}/morecantile/scripts/cli.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: morecantile
|
|
3
|
-
Version: 7.0.
|
|
3
|
+
Version: 7.0.1
|
|
4
4
|
Summary: Construct and use map tile grids (a.k.a TileMatrixSet / TMS).
|
|
5
5
|
Project-URL: Source, https://github.com/developmentseed/morecantile
|
|
6
6
|
Project-URL: Documentation, https://developmentseed.org/morecantile/
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import os
|
|
4
4
|
import pathlib
|
|
5
5
|
from copy import copy, deepcopy
|
|
6
|
-
from typing import Dict, List, Union
|
|
7
6
|
|
|
8
7
|
import attr
|
|
9
8
|
|
|
@@ -17,7 +16,7 @@ user_tms_dir = os.environ.get("TILEMATRIXSET_DIRECTORY", None)
|
|
|
17
16
|
if user_tms_dir:
|
|
18
17
|
tms_paths.extend(list(pathlib.Path(user_tms_dir).glob("*.json")))
|
|
19
18
|
|
|
20
|
-
default_tms:
|
|
19
|
+
default_tms: dict[str, TileMatrixSet | pathlib.Path] = {
|
|
21
20
|
tms.stem: tms for tms in sorted(tms_paths)
|
|
22
21
|
}
|
|
23
22
|
|
|
@@ -26,7 +25,7 @@ default_tms: Dict[str, Union[TileMatrixSet, pathlib.Path]] = {
|
|
|
26
25
|
class TileMatrixSets:
|
|
27
26
|
"""Default TileMatrixSets holder."""
|
|
28
27
|
|
|
29
|
-
tilematrixsets:
|
|
28
|
+
tilematrixsets: dict = attr.ib()
|
|
30
29
|
|
|
31
30
|
def get(self, identifier: str) -> TileMatrixSet:
|
|
32
31
|
"""Fetch a TMS."""
|
|
@@ -43,13 +42,13 @@ class TileMatrixSets:
|
|
|
43
42
|
|
|
44
43
|
return deepcopy(tilematrix)
|
|
45
44
|
|
|
46
|
-
def list(self) ->
|
|
45
|
+
def list(self) -> list[str]:
|
|
47
46
|
"""List registered TMS."""
|
|
48
47
|
return list(self.tilematrixsets.keys())
|
|
49
48
|
|
|
50
49
|
def register(
|
|
51
50
|
self,
|
|
52
|
-
custom_tms:
|
|
51
|
+
custom_tms: dict[str, TileMatrixSet],
|
|
53
52
|
overwrite: bool = False,
|
|
54
53
|
) -> "TileMatrixSets":
|
|
55
54
|
"""Register TileMatrixSet(s)."""
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
import math
|
|
4
4
|
import os
|
|
5
5
|
import warnings
|
|
6
|
+
from collections.abc import Iterator, Sequence
|
|
6
7
|
from functools import cached_property, lru_cache
|
|
7
|
-
from typing import Any,
|
|
8
|
+
from typing import Any, Literal
|
|
8
9
|
|
|
9
10
|
import pyproj
|
|
10
11
|
from pydantic import (
|
|
@@ -39,10 +40,10 @@ from morecantile.utils import (
|
|
|
39
40
|
truncate_coordinates,
|
|
40
41
|
)
|
|
41
42
|
|
|
42
|
-
NumType =
|
|
43
|
-
BoundsType =
|
|
43
|
+
NumType = float | int
|
|
44
|
+
BoundsType = tuple[NumType, NumType]
|
|
44
45
|
LL_EPSILON = 1e-11
|
|
45
|
-
axesInfo = Annotated[
|
|
46
|
+
axesInfo = Annotated[list[str], Field(min_length=2, max_length=2)]
|
|
46
47
|
WGS84_CRS = pyproj.CRS.from_epsg(4326)
|
|
47
48
|
DEFAULT_GEOGRAPHIC_CRS = os.environ.get("MORECANTILE_DEFAULT_GEOGRAPHIC_CRS")
|
|
48
49
|
|
|
@@ -70,7 +71,7 @@ class CRSWKT(BaseModel):
|
|
|
70
71
|
"""Coordinate Reference System (CRS) from WKT encoded as PROJJSON Object."""
|
|
71
72
|
|
|
72
73
|
wkt: Annotated[
|
|
73
|
-
|
|
74
|
+
dict,
|
|
74
75
|
Field(
|
|
75
76
|
json_schema_extra={
|
|
76
77
|
"description": "An object defining the CRS using the JSON encoding for Well-known text representation of coordinate reference systems 2.0",
|
|
@@ -83,7 +84,7 @@ class CRSRef(BaseModel):
|
|
|
83
84
|
"""CRS from referenceSystem."""
|
|
84
85
|
|
|
85
86
|
referenceSystem: Annotated[
|
|
86
|
-
|
|
87
|
+
dict[str, Any],
|
|
87
88
|
Field(
|
|
88
89
|
json_schema_extra={
|
|
89
90
|
"description": "A reference system data structure as defined in the MD_ReferenceSystem of the ISO 19115",
|
|
@@ -92,7 +93,7 @@ class CRSRef(BaseModel):
|
|
|
92
93
|
]
|
|
93
94
|
|
|
94
95
|
|
|
95
|
-
class CRS(RootModel[
|
|
96
|
+
class CRS(RootModel[str | CRSUri | CRSWKT | CRSRef]):
|
|
96
97
|
"""CRS model.
|
|
97
98
|
|
|
98
99
|
Ref: https://github.com/opengeospatial/ogcapi-tiles/blob/master/openapi/schemas/common-geodata/crs.yaml
|
|
@@ -125,7 +126,7 @@ class CRS(RootModel[Union[str, Union[CRSUri, CRSWKT, CRSRef]]]):
|
|
|
125
126
|
"""return the string form of the user input used to create the CRS."""
|
|
126
127
|
return self._pyproj_crs.srs
|
|
127
128
|
|
|
128
|
-
def to_epsg(self, *args: Any, **kwargs: Any) ->
|
|
129
|
+
def to_epsg(self, *args: Any, **kwargs: Any) -> int | None:
|
|
129
130
|
"""return EPSG number of the CRS."""
|
|
130
131
|
return self._pyproj_crs.to_epsg(*args, **kwargs)
|
|
131
132
|
|
|
@@ -137,7 +138,7 @@ class CRS(RootModel[Union[str, Union[CRSUri, CRSWKT, CRSRef]]]):
|
|
|
137
138
|
"""return PROJ4 version of the CRS."""
|
|
138
139
|
return self._pyproj_crs.to_proj4(*args, **kwargs)
|
|
139
140
|
|
|
140
|
-
def to_dict(self) ->
|
|
141
|
+
def to_dict(self) -> dict:
|
|
141
142
|
"""return DICT version of the CRS."""
|
|
142
143
|
return self._pyproj_crs.to_dict()
|
|
143
144
|
|
|
@@ -171,7 +172,7 @@ def crs_axis_inverted(crs: pyproj.CRS) -> bool:
|
|
|
171
172
|
return crs.axis_info[0].abbrev.upper() in ["Y", "LAT", "N"]
|
|
172
173
|
|
|
173
174
|
|
|
174
|
-
def ordered_axis_inverted(ordered_axes:
|
|
175
|
+
def ordered_axis_inverted(ordered_axes: list[str]) -> bool:
|
|
175
176
|
"""Check if ordered axes have inverted AXIS (lat,lon) instead of (lon,lat)."""
|
|
176
177
|
return ordered_axes[0].upper() in ["Y", "LAT", "N"]
|
|
177
178
|
|
|
@@ -200,7 +201,7 @@ class TMSBoundingBox(BaseModel, arbitrary_types_allowed=True):
|
|
|
200
201
|
),
|
|
201
202
|
]
|
|
202
203
|
crs: Annotated[
|
|
203
|
-
|
|
204
|
+
CRS | None,
|
|
204
205
|
Field(
|
|
205
206
|
json_schema_extra={
|
|
206
207
|
"description": "Coordinate Reference System (CRS)",
|
|
@@ -208,7 +209,7 @@ class TMSBoundingBox(BaseModel, arbitrary_types_allowed=True):
|
|
|
208
209
|
),
|
|
209
210
|
] = None
|
|
210
211
|
orderedAxes: Annotated[
|
|
211
|
-
|
|
212
|
+
axesInfo | None,
|
|
212
213
|
Field(
|
|
213
214
|
json_schema_extra={
|
|
214
215
|
"description": "Ordered list of names of the dimensions defined in the CRS",
|
|
@@ -264,7 +265,7 @@ class TileMatrix(BaseModel, extra="forbid"):
|
|
|
264
265
|
"""
|
|
265
266
|
|
|
266
267
|
title: Annotated[
|
|
267
|
-
|
|
268
|
+
str | None,
|
|
268
269
|
Field(
|
|
269
270
|
json_schema_extra={
|
|
270
271
|
"description": "Title of this tile matrix, normally used for display to a human",
|
|
@@ -272,7 +273,7 @@ class TileMatrix(BaseModel, extra="forbid"):
|
|
|
272
273
|
),
|
|
273
274
|
] = None
|
|
274
275
|
description: Annotated[
|
|
275
|
-
|
|
276
|
+
str | None,
|
|
276
277
|
Field(
|
|
277
278
|
json_schema_extra={
|
|
278
279
|
"description": "Brief narrative description of this tile matrix set, normally available for display to a human",
|
|
@@ -280,7 +281,7 @@ class TileMatrix(BaseModel, extra="forbid"):
|
|
|
280
281
|
),
|
|
281
282
|
] = None
|
|
282
283
|
keywords: Annotated[
|
|
283
|
-
|
|
284
|
+
list[str] | None,
|
|
284
285
|
Field(
|
|
285
286
|
json_schema_extra={
|
|
286
287
|
"description": "Unordered list of one or more commonly used or formalized word(s) or phrase(s) used to describe this dataset",
|
|
@@ -369,7 +370,7 @@ class TileMatrix(BaseModel, extra="forbid"):
|
|
|
369
370
|
),
|
|
370
371
|
]
|
|
371
372
|
variableMatrixWidths: Annotated[
|
|
372
|
-
|
|
373
|
+
list[variableMatrixWidth] | None,
|
|
373
374
|
Field(
|
|
374
375
|
json_schema_extra={
|
|
375
376
|
"description": "Describes the rows that has variable matrix width",
|
|
@@ -409,7 +410,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
409
410
|
"""
|
|
410
411
|
|
|
411
412
|
title: Annotated[
|
|
412
|
-
|
|
413
|
+
str | None,
|
|
413
414
|
Field(
|
|
414
415
|
json_schema_extra={
|
|
415
416
|
"description": "Title of this tile matrix set, normally used for display to a human",
|
|
@@ -418,7 +419,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
418
419
|
),
|
|
419
420
|
] = None
|
|
420
421
|
description: Annotated[
|
|
421
|
-
|
|
422
|
+
str | None,
|
|
422
423
|
Field(
|
|
423
424
|
json_schema_extra={
|
|
424
425
|
"description": "Brief narrative description of this tile matrix set, normally available for display to a human",
|
|
@@ -427,7 +428,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
427
428
|
),
|
|
428
429
|
] = None
|
|
429
430
|
keywords: Annotated[
|
|
430
|
-
|
|
431
|
+
list[str] | None,
|
|
431
432
|
Field(
|
|
432
433
|
json_schema_extra={
|
|
433
434
|
"description": "Unordered list of one or more commonly used or formalized word(s) or phrase(s) used to describe this tile matrix set",
|
|
@@ -436,7 +437,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
436
437
|
),
|
|
437
438
|
] = None
|
|
438
439
|
id: Annotated[
|
|
439
|
-
|
|
440
|
+
str | None,
|
|
440
441
|
Field(
|
|
441
442
|
pattern=r"^[\w\d_\-]+$",
|
|
442
443
|
json_schema_extra={
|
|
@@ -446,7 +447,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
446
447
|
),
|
|
447
448
|
] = None
|
|
448
449
|
uri: Annotated[
|
|
449
|
-
|
|
450
|
+
str | None,
|
|
450
451
|
Field(
|
|
451
452
|
json_schema_extra={
|
|
452
453
|
"description": "Reference to an official source for this tileMatrixSet",
|
|
@@ -455,7 +456,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
455
456
|
),
|
|
456
457
|
] = None
|
|
457
458
|
orderedAxes: Annotated[
|
|
458
|
-
|
|
459
|
+
axesInfo | None,
|
|
459
460
|
Field(
|
|
460
461
|
json_schema_extra={
|
|
461
462
|
"description": "Ordered list of names of the dimensions defined in the CRS",
|
|
@@ -473,7 +474,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
473
474
|
),
|
|
474
475
|
]
|
|
475
476
|
wellKnownScaleSet: Annotated[
|
|
476
|
-
|
|
477
|
+
AnyHttpUrl | None,
|
|
477
478
|
Field(
|
|
478
479
|
json_schema_extra={
|
|
479
480
|
"description": "Reference to a well-known scale set",
|
|
@@ -482,7 +483,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
482
483
|
),
|
|
483
484
|
] = None
|
|
484
485
|
boundingBox: Annotated[
|
|
485
|
-
|
|
486
|
+
TMSBoundingBox | None,
|
|
486
487
|
Field(
|
|
487
488
|
json_schema_extra={
|
|
488
489
|
"description": "Minimum bounding rectangle surrounding the tile matrix set, in the supported CRS",
|
|
@@ -491,7 +492,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
491
492
|
),
|
|
492
493
|
] = None
|
|
493
494
|
tileMatrices: Annotated[
|
|
494
|
-
|
|
495
|
+
list[TileMatrix],
|
|
495
496
|
Field(
|
|
496
497
|
json_schema_extra={
|
|
497
498
|
"description": "Describes scale levels and its tile matrices",
|
|
@@ -502,7 +503,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
502
503
|
|
|
503
504
|
# Private attributes
|
|
504
505
|
_geographic_crs: pyproj.CRS = PrivateAttr()
|
|
505
|
-
_tile_matrices_idx:
|
|
506
|
+
_tile_matrices_idx: dict[int, int] = PrivateAttr()
|
|
506
507
|
|
|
507
508
|
def __init__(self, **data):
|
|
508
509
|
"""Set private attributes."""
|
|
@@ -560,7 +561,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
560
561
|
"""Return rasterio CRS."""
|
|
561
562
|
return to_rasterio_crs(self.crs._pyproj_crs)
|
|
562
563
|
|
|
563
|
-
def set_geographic_crs(self, crs: CRS) -> None:
|
|
564
|
+
def set_geographic_crs(self, crs: pyproj.CRS) -> None:
|
|
564
565
|
"""Overwrite Geographic CRS for the TMS."""
|
|
565
566
|
self._geographic_crs = crs
|
|
566
567
|
|
|
@@ -606,7 +607,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
606
607
|
)
|
|
607
608
|
|
|
608
609
|
@classmethod
|
|
609
|
-
def from_v1(cls, tms:
|
|
610
|
+
def from_v1(cls, tms: dict) -> "TileMatrixSet":
|
|
610
611
|
"""
|
|
611
612
|
Makes a TMS from a v1 TMS definition
|
|
612
613
|
|
|
@@ -626,7 +627,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
626
627
|
WKSS URL
|
|
627
628
|
boundingBox: TMSBoundingBox (optional)
|
|
628
629
|
Bounding box of TMS
|
|
629
|
-
tileMatrix:
|
|
630
|
+
tileMatrix: list[TileMatrix]
|
|
630
631
|
List of Tile Matrices
|
|
631
632
|
|
|
632
633
|
Returns:
|
|
@@ -664,21 +665,21 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
664
665
|
@classmethod
|
|
665
666
|
def custom(
|
|
666
667
|
cls,
|
|
667
|
-
extent:
|
|
668
|
+
extent: list[float],
|
|
668
669
|
crs: pyproj.CRS,
|
|
669
670
|
tile_width: int = 256,
|
|
670
671
|
tile_height: int = 256,
|
|
671
|
-
matrix_scale:
|
|
672
|
-
extent_crs:
|
|
672
|
+
matrix_scale: list | None = None,
|
|
673
|
+
extent_crs: pyproj.CRS | None = None,
|
|
673
674
|
minzoom: int = 0,
|
|
674
675
|
maxzoom: int = 24,
|
|
675
|
-
title:
|
|
676
|
-
id:
|
|
677
|
-
ordered_axes:
|
|
676
|
+
title: str | None = None,
|
|
677
|
+
id: str | None = None,
|
|
678
|
+
ordered_axes: list[str] | None = None,
|
|
678
679
|
screen_pixel_size: float = 0.28e-3,
|
|
679
680
|
decimation_base: int = 2,
|
|
680
681
|
corner_of_origin: Literal["topLeft", "bottomLeft"] = "topLeft",
|
|
681
|
-
point_of_origin:
|
|
682
|
+
point_of_origin: list[float] = None,
|
|
682
683
|
**kwargs: Any,
|
|
683
684
|
):
|
|
684
685
|
"""
|
|
@@ -736,7 +737,10 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
736
737
|
|
|
737
738
|
if extent_crs:
|
|
738
739
|
transform = pyproj.Transformer.from_crs(extent_crs, crs, always_xy=True)
|
|
739
|
-
|
|
740
|
+
left, bottom, right, top = extent
|
|
741
|
+
extent = list(
|
|
742
|
+
transform.transform_bounds(left, bottom, right, top, densify_pts=21)
|
|
743
|
+
)
|
|
740
744
|
|
|
741
745
|
if decimation_base <= 1:
|
|
742
746
|
raise ValueError(
|
|
@@ -762,7 +766,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
762
766
|
height = abs(bbox.top - bbox.bottom)
|
|
763
767
|
mpu = meters_per_unit(crs)
|
|
764
768
|
|
|
765
|
-
tile_matrices:
|
|
769
|
+
tile_matrices: list[TileMatrix] = []
|
|
766
770
|
for zoom in range(minzoom, maxzoom + 1):
|
|
767
771
|
res = max(
|
|
768
772
|
width / (tile_width * matrix_scale[0]) / float(decimation_base) ** zoom,
|
|
@@ -872,9 +876,9 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
872
876
|
def zoom_for_res(
|
|
873
877
|
self,
|
|
874
878
|
res: float,
|
|
875
|
-
max_z:
|
|
879
|
+
max_z: int | None = None,
|
|
876
880
|
zoom_level_strategy: str = "auto",
|
|
877
|
-
min_z:
|
|
881
|
+
min_z: int | None = None,
|
|
878
882
|
) -> int:
|
|
879
883
|
"""Get TMS zoom level corresponding to a specific resolution.
|
|
880
884
|
|
|
@@ -1044,7 +1048,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
1044
1048
|
zoom: int,
|
|
1045
1049
|
truncate=False,
|
|
1046
1050
|
ignore_coalescence: bool = False,
|
|
1047
|
-
geographic_crs:
|
|
1051
|
+
geographic_crs: pyproj.CRS | None = None,
|
|
1048
1052
|
) -> Tile:
|
|
1049
1053
|
"""
|
|
1050
1054
|
Get the tile for a given geographic longitude and latitude pair.
|
|
@@ -1076,8 +1080,11 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
1076
1080
|
)
|
|
1077
1081
|
|
|
1078
1082
|
if truncate:
|
|
1083
|
+
left, bottom, right, top = self.xy_bbox
|
|
1079
1084
|
bbox = BoundingBox(
|
|
1080
|
-
*_to_geographic.transform_bounds(
|
|
1085
|
+
*_to_geographic.transform_bounds(
|
|
1086
|
+
left, bottom, right, top, densify_pts=21
|
|
1087
|
+
),
|
|
1081
1088
|
)
|
|
1082
1089
|
lng, lat = truncate_coordinates(lng, lat, bbox)
|
|
1083
1090
|
|
|
@@ -1287,7 +1294,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
1287
1294
|
north: float,
|
|
1288
1295
|
zooms: Sequence[int],
|
|
1289
1296
|
truncate: bool = False,
|
|
1290
|
-
geographic_crs:
|
|
1297
|
+
geographic_crs: pyproj.CRS | None = None,
|
|
1291
1298
|
) -> Iterator[Tile]:
|
|
1292
1299
|
"""
|
|
1293
1300
|
Get the tiles overlapped by a geographic bounding box
|
|
@@ -1330,8 +1337,9 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
1330
1337
|
)
|
|
1331
1338
|
|
|
1332
1339
|
# TMS bbox
|
|
1340
|
+
left, bottom, right, top = self.xy_bbox
|
|
1333
1341
|
bbox = BoundingBox(
|
|
1334
|
-
*_to_geographic.transform_bounds(
|
|
1342
|
+
*_to_geographic.transform_bounds(left, bottom, right, top, densify_pts=21),
|
|
1335
1343
|
)
|
|
1336
1344
|
|
|
1337
1345
|
if truncate:
|
|
@@ -1379,13 +1387,13 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
1379
1387
|
def feature(
|
|
1380
1388
|
self,
|
|
1381
1389
|
tile: Tile,
|
|
1382
|
-
fid:
|
|
1383
|
-
props:
|
|
1384
|
-
buffer:
|
|
1385
|
-
precision:
|
|
1390
|
+
fid: str | None = None,
|
|
1391
|
+
props: dict | None = None,
|
|
1392
|
+
buffer: NumType | None = None,
|
|
1393
|
+
precision: int | None = None,
|
|
1386
1394
|
projected: bool = False,
|
|
1387
|
-
geographic_crs:
|
|
1388
|
-
) ->
|
|
1395
|
+
geographic_crs: pyproj.CRS | None = None,
|
|
1396
|
+
) -> dict:
|
|
1389
1397
|
"""
|
|
1390
1398
|
Get the GeoJSON feature corresponding to a tile.
|
|
1391
1399
|
|
|
@@ -1445,7 +1453,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
1445
1453
|
geom = bbox_to_feature(west, south, east, north)
|
|
1446
1454
|
|
|
1447
1455
|
xyz = str(tile)
|
|
1448
|
-
feat:
|
|
1456
|
+
feat: dict[str, Any] = {
|
|
1449
1457
|
"type": "Feature",
|
|
1450
1458
|
"bbox": bbox,
|
|
1451
1459
|
"id": xyz,
|
|
@@ -1561,7 +1569,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
1561
1569
|
|
|
1562
1570
|
return Tile(xtile, ytile, i + 1)
|
|
1563
1571
|
|
|
1564
|
-
def minmax(self, zoom: int) ->
|
|
1572
|
+
def minmax(self, zoom: int) -> dict:
|
|
1565
1573
|
"""Return TileMatrix Extrema.
|
|
1566
1574
|
|
|
1567
1575
|
Parameters
|
|
@@ -1571,7 +1579,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
1571
1579
|
|
|
1572
1580
|
Returns
|
|
1573
1581
|
-------
|
|
1574
|
-
|
|
1582
|
+
dict
|
|
1575
1583
|
|
|
1576
1584
|
"""
|
|
1577
1585
|
m = self.matrix(zoom)
|
|
@@ -1594,7 +1602,7 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True, extra="ignore"):
|
|
|
1594
1602
|
|
|
1595
1603
|
return validx and validy
|
|
1596
1604
|
|
|
1597
|
-
def neighbors(self, *tile: Tile) ->
|
|
1605
|
+
def neighbors(self, *tile: Tile) -> list[Tile]:
|
|
1598
1606
|
"""The neighbors of a tile
|
|
1599
1607
|
|
|
1600
1608
|
The neighbors function makes no guarantees regarding neighbor tile
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""morecantile utils."""
|
|
2
2
|
|
|
3
3
|
import math
|
|
4
|
-
from typing import Dict, List, Tuple
|
|
5
4
|
|
|
6
5
|
from pyproj import CRS
|
|
7
6
|
from pyproj.enums import WktVersion
|
|
@@ -90,7 +89,7 @@ def meters_per_unit(crs: CRS) -> float:
|
|
|
90
89
|
) from e
|
|
91
90
|
|
|
92
91
|
|
|
93
|
-
def bbox_to_feature(west: float, south: float, east: float, north: float) ->
|
|
92
|
+
def bbox_to_feature(west: float, south: float, east: float, north: float) -> dict:
|
|
94
93
|
"""Create a GeoJSON feature from a bbox."""
|
|
95
94
|
return {
|
|
96
95
|
"type": "Polygon",
|
|
@@ -112,7 +111,7 @@ def point_in_bbox(point: Coords, bbox: BoundingBox, precision: int = 5) -> bool:
|
|
|
112
111
|
|
|
113
112
|
def truncate_coordinates(
|
|
114
113
|
lng: float, lat: float, bbox: BoundingBox
|
|
115
|
-
) ->
|
|
114
|
+
) -> tuple[float, float]:
|
|
116
115
|
"""
|
|
117
116
|
Truncate coordinates to a given bbox.
|
|
118
117
|
|
|
@@ -137,7 +136,7 @@ def is_power_of_two(number: int) -> bool:
|
|
|
137
136
|
return (number & (number - 1) == 0) and number != 0
|
|
138
137
|
|
|
139
138
|
|
|
140
|
-
def check_quadkey_support(tms:
|
|
139
|
+
def check_quadkey_support(tms: list) -> bool:
|
|
141
140
|
"""Check if a Tile Matrix Set supports quadkeys"""
|
|
142
141
|
return all(
|
|
143
142
|
(t.matrixWidth == t.matrixHeight)
|
|
@@ -36,10 +36,7 @@ dev = [
|
|
|
36
36
|
"mercantile",
|
|
37
37
|
"pytest",
|
|
38
38
|
"pytest-cov",
|
|
39
|
-
# ref: https://github.com/pallets/click/issues/2939
|
|
40
|
-
"click!=8.2.1,!=8.2.2",
|
|
41
39
|
"pre-commit",
|
|
42
|
-
"bump-my-version==1.2.4",
|
|
43
40
|
]
|
|
44
41
|
|
|
45
42
|
docs = [
|
|
@@ -122,7 +119,7 @@ filterwarnings = [
|
|
|
122
119
|
]
|
|
123
120
|
|
|
124
121
|
[tool.bumpversion]
|
|
125
|
-
current_version = "7.0.
|
|
122
|
+
current_version = "7.0.1"
|
|
126
123
|
|
|
127
124
|
search = "{current_version}"
|
|
128
125
|
replace = "{new_version}"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|