From 1d11d0463a442486e0839d86ee17807664322c15 Mon Sep 17 00:00:00 2001 From: adrian-knauer Date: Thu, 12 Aug 2021 17:48:06 +0200 Subject: [PATCH 01/13] added NoQuadkeySupport error --- .idea/.gitignore | 8 ++++++++ .idea/inspectionProfiles/Project_Default.xml | 6 ++++++ .idea/inspectionProfiles/profiles_settings.xml | 6 ++++++ .idea/misc.xml | 4 ++++ .idea/modules.xml | 8 ++++++++ .idea/morecantile.iml | 15 +++++++++++++++ .idea/vcs.xml | 6 ++++++ morecantile/errors.py | 4 ++++ 8 files changed, 57 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/morecantile.iml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..8465c53 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..f2dc18f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/morecantile.iml b/.idea/morecantile.iml new file mode 100644 index 0000000..4f2c9af --- /dev/null +++ b/.idea/morecantile.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/morecantile/errors.py b/morecantile/errors.py index e32626f..144df8e 100644 --- a/morecantile/errors.py +++ b/morecantile/errors.py @@ -19,3 +19,7 @@ class TileArgParsingError(MorecantileError): class PointOutsideTMSBounds(UserWarning): """Point is outside TMS bounds.""" + + +class NoQuadkeySupport(MorecantileError): + """Raised when a custom TileMatrixSet doesn't support quadkeys""" From 1164d44e2bd691b3d0286a82532ee8410df47f3f Mon Sep 17 00:00:00 2001 From: adrian-knauer Date: Fri, 13 Aug 2021 12:45:41 +0200 Subject: [PATCH 02/13] added check for quadkey support --- morecantile/models.py | 6 ++++++ morecantile/utils.py | 19 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/morecantile/models.py b/morecantile/models.py index 00db746..d8f4035 100644 --- a/morecantile/models.py +++ b/morecantile/models.py @@ -14,6 +14,7 @@ from .utils import ( _parse_tile_arg, bbox_to_feature, + check_quadkey_support, meters_per_unit, point_in_bbox, truncate_lnglat, @@ -162,6 +163,11 @@ def _invert_axis(self) -> bool: """Check if CRS has inverted AXIS (lat,lon) instead of (lon,lat).""" return crs_axis_inverted(self.crs) + @property + def quadkey(self) -> bool: + """Indicator if the Tile Matrix Set supports the creation of quadkeys""" + return check_quadkey_support(self.tileMatrix) + @classmethod def load(cls, name: str): """Load default TileMatrixSet.""" diff --git a/morecantile/utils.py b/morecantile/utils.py index 2dd87b8..582f925 100644 --- a/morecantile/utils.py +++ b/morecantile/utils.py @@ -1,7 +1,7 @@ """morecantile utils.""" import math -from typing import Dict, Tuple +from typing import Dict, List, Tuple from rasterio.crs import CRS @@ -92,3 +92,20 @@ def point_in_bbox(point: Coords, bbox: BoundingBox, precision: int = 5) -> bool: and round(point.y, precision) >= round(bbox.bottom, precision) and round(point.y, precision) <= round(bbox.top, precision) ) + + +def is_power_of_two(number: int) -> bool: + """Check if a number is a power of 2""" + return (number & (number - 1) == 0) and number != 0 + + +def check_quadkey_support(tms: List) -> bool: + """Check if a Tile Matrix Set supports quadkeys""" + return all( + [ + (t.matrixWidth == t.matrixHeight) + and is_power_of_two(t.matrixWidth) + and ((t.matrixWidth * 2) == tms[i + 1].matrixWidth) + for i, t in enumerate(tms[:-1]) + ] + ) From 7f3f35591f425f42b0414013aad87c0cf158334c Mon Sep 17 00:00:00 2001 From: adrian-knauer Date: Fri, 13 Aug 2021 15:29:19 +0200 Subject: [PATCH 03/13] added test for quadkey check --- tests/test_models.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_models.py b/tests/test_models.py index 0e6be1b..bd4ec7d 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -99,6 +99,14 @@ def test_load(): TileMatrixSet.load("ANotValidName") +def test_quadkey_support(): + tms = TileMatrixSet.load("CanadianNAD83_LCC") + assert not tms.quadkey + + tms = TileMatrixSet.load("UPSArcticWGS84Quad") + assert tms.quadkey + + def test_findMatrix(): """Should raise an error when TileMatrix is not found.""" tms = morecantile.tms.get("WebMercatorQuad") From 3bd0338a8673231ce0033ddc613960f825098c99 Mon Sep 17 00:00:00 2001 From: adrian-knauer Date: Fri, 13 Aug 2021 15:37:02 +0200 Subject: [PATCH 04/13] removed pycharm files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index b6e4761..23077b4 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,6 @@ dmypy.json # Pyre type checker .pyre/ + +# PyCharm: +.idea From 79c443ba9951569eb0df21f1a83d7477647578f1 Mon Sep 17 00:00:00 2001 From: adrian-knauer Date: Fri, 13 Aug 2021 15:42:20 +0200 Subject: [PATCH 05/13] really removed pycharm files --- .idea/.gitignore | 8 -------- .idea/inspectionProfiles/Project_Default.xml | 6 ------ .idea/inspectionProfiles/profiles_settings.xml | 6 ------ .idea/misc.xml | 4 ---- .idea/modules.xml | 8 -------- .idea/morecantile.iml | 15 --------------- .idea/vcs.xml | 6 ------ 7 files changed, 53 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/morecantile.iml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 73f69e0..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 03d9549..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2d..0000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 8465c53..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index f2dc18f..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/morecantile.iml b/.idea/morecantile.iml deleted file mode 100644 index 4f2c9af..0000000 --- a/.idea/morecantile.iml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From a7948731ea3d16ef1a5f6c47817ff9aed74e9f8f Mon Sep 17 00:00:00 2001 From: adrian-knauer Date: Fri, 13 Aug 2021 16:42:36 +0200 Subject: [PATCH 06/13] added quadkey and quadkey_to_tile --- morecantile/errors.py | 4 +++ morecantile/models.py | 66 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/morecantile/errors.py b/morecantile/errors.py index 144df8e..ee67d47 100644 --- a/morecantile/errors.py +++ b/morecantile/errors.py @@ -23,3 +23,7 @@ class PointOutsideTMSBounds(UserWarning): class NoQuadkeySupport(MorecantileError): """Raised when a custom TileMatrixSet doesn't support quadkeys""" + + +class QuadKeyError(MorecantileError): + """Raised when errors occur in computing or parsing quad keys""" diff --git a/morecantile/models.py b/morecantile/models.py index d8f4035..11728e0 100644 --- a/morecantile/models.py +++ b/morecantile/models.py @@ -10,7 +10,12 @@ from rasterio.warp import transform, transform_bounds, transform_geom from .commons import BoundingBox, Coords, Tile -from .errors import InvalidIdentifier, PointOutsideTMSBounds +from .errors import ( + InvalidIdentifier, + NoQuadkeySupport, + PointOutsideTMSBounds, + QuadKeyError, +) from .utils import ( _parse_tile_arg, bbox_to_feature, @@ -164,7 +169,7 @@ def _invert_axis(self) -> bool: return crs_axis_inverted(self.crs) @property - def quadkey(self) -> bool: + def quadkey_support(self) -> bool: """Indicator if the Tile Matrix Set supports the creation of quadkeys""" return check_quadkey_support(self.tileMatrix) @@ -789,3 +794,60 @@ def feature( feat["id"] = fid return feat + + def quadkey(self, *tile: Tile) -> str: + """Get the quadkey of a tile + Parameters + ---------- + tile : Tile or sequence of int + May be be either an instance of Tile or 3 ints, X, Y, Z. + Returns + ------- + str + """ + if not self.quadkey_support: + raise NoQuadkeySupport( + "This Tile Matrix Set doesn't support 2 x 2 quadkeys." + ) + tile = _parse_tile_arg(*tile) + xtile, ytile, zoom = tile + qk = [] + for z in range(zoom, self.minzoom, -1): + digit = 0 + mask = 1 << (z - 1) + if xtile & mask: + digit += 1 + if ytile & mask: + digit += 2 + qk.append(str(digit)) + return "".join(qk) + + def quadkey_to_tile(self, qk: str) -> Tile: + """Get the tile corresponding to a quadkey + Parameters + ---------- + qk : str + A quadkey string. + Returns + ------- + Tile + """ + if not self.quadkey_support: + raise NoQuadkeySupport( + "This Tile Matrix Set doesn't support 2 x 2 quadkeys." + ) + if len(qk) == 0: + return Tile(0, 0, 0) + xtile, ytile = 0, 0 + for i, digit in enumerate(reversed(qk)): + mask = 1 << i + if digit == "1": + xtile = xtile | mask + elif digit == "2": + ytile = ytile | mask + elif digit == "3": + xtile = xtile | mask + ytile = ytile | mask + elif digit != "0": + raise QuadKeyError("Unexpected quadkey digit: %r", digit) + return Tile(xtile, ytile, i + 1) From ac4d33c0bc6f02b7bfe0aef37972262ed04dc097 Mon Sep 17 00:00:00 2001 From: adrian-knauer Date: Fri, 13 Aug 2021 17:11:29 +0200 Subject: [PATCH 07/13] added tests for quadkey functions --- tests/test_models.py | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/tests/test_models.py b/tests/test_models.py index bd4ec7d..3ce8737 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -10,6 +10,7 @@ from rasterio.crs import CRS import morecantile +from morecantile.commons import Tile from morecantile.errors import InvalidIdentifier from morecantile.models import TileMatrix, TileMatrixSet @@ -101,10 +102,36 @@ def test_load(): def test_quadkey_support(): tms = TileMatrixSet.load("CanadianNAD83_LCC") - assert not tms.quadkey + assert not tms.quadkey_support tms = TileMatrixSet.load("UPSArcticWGS84Quad") - assert tms.quadkey + assert tms.quadkey_support + + +def test_quadkey(): + tms = morecantile.tms.get("WebMercatorQuad") + expected = "0313102310" + assert tms.quadkey(486, 332, 10) == expected + + +def test_quadkey_to_tile(): + tms = morecantile.tms.get("WebMercatorQuad") + qk = "0313102310" + expected = Tile(486, 332, 10) + assert tms.quadkey_to_tile(qk) == expected + + +def test_empty_quadkey_to_tile(): + tms = morecantile.tms.get("WebMercatorQuad") + qk = "" + expected = Tile(0, 0, 0) + assert tms.quadkey_to_tile(qk) == expected + + +def test_quadkey_failure(): + tms = morecantile.tms.get("WebMercatorQuad") + with pytest.raises(morecantile.errors.QuadKeyError): + tms.quadkey_to_tile("lolwut") def test_findMatrix(): From 6d82e35f32e38e44f6986a7597d01e0f24216873 Mon Sep 17 00:00:00 2001 From: adrian-knauer Date: Mon, 16 Aug 2021 09:06:43 +0200 Subject: [PATCH 08/13] added test for power of two check --- tests/test_morecantile.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/test_morecantile.py b/tests/test_morecantile.py index 102a844..d286e69 100644 --- a/tests/test_morecantile.py +++ b/tests/test_morecantile.py @@ -6,7 +6,7 @@ import morecantile from morecantile.errors import InvalidIdentifier, PointOutsideTMSBounds -from morecantile.utils import meters_per_unit +from morecantile.utils import is_power_of_two, meters_per_unit from .conftest import gdal_version, requires_gdal3, requires_gdal_lt_3 @@ -493,3 +493,8 @@ def test_extend_zoom(): more = tms.xy_bounds(2000, 2000, 30) for a, b in zip(more, merc): assert round(a - b, 7) == 0 + + +def test_is_power_of_two(): + assert is_power_of_two(8) + assert not is_power_of_two(7) From 9204a77ecad0cb4fe3caa2cb1d5c95722437c9de Mon Sep 17 00:00:00 2001 From: adrian-knauer Date: Mon, 16 Aug 2021 09:55:20 +0200 Subject: [PATCH 09/13] made quadkey support an instance attribute --- morecantile/models.py | 15 ++++++++------- tests/test_models.py | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/morecantile/models.py b/morecantile/models.py index 11728e0..11e0033 100644 --- a/morecantile/models.py +++ b/morecantile/models.py @@ -127,6 +127,7 @@ class TileMatrixSet(BaseModel): wellKnownScaleSet: Optional[AnyHttpUrl] = None boundingBox: Optional[TMSBoundingBox] tileMatrix: List[TileMatrix] + is_quadkey: bool = False class Config: """Configure TileMatrixSet.""" @@ -139,6 +140,11 @@ def sort_tile_matrices(cls, v): """Sort matrices by identifier""" return sorted(v, key=lambda m: int(m.identifier)) + def __init__(self, **kwargs): + """Check if TileMatrixSet supports quadkeys""" + super().__init__(**kwargs) + self.is_quadkey = check_quadkey_support(self.tileMatrix) + def __iter__(self): """Iterate over matrices""" for matrix in self.tileMatrix: @@ -168,11 +174,6 @@ def _invert_axis(self) -> bool: """Check if CRS has inverted AXIS (lat,lon) instead of (lon,lat).""" return crs_axis_inverted(self.crs) - @property - def quadkey_support(self) -> bool: - """Indicator if the Tile Matrix Set supports the creation of quadkeys""" - return check_quadkey_support(self.tileMatrix) - @classmethod def load(cls, name: str): """Load default TileMatrixSet.""" @@ -805,7 +806,7 @@ def quadkey(self, *tile: Tile) -> str: ------- str """ - if not self.quadkey_support: + if not self.is_quadkey: raise NoQuadkeySupport( "This Tile Matrix Set doesn't support 2 x 2 quadkeys." ) @@ -832,7 +833,7 @@ def quadkey_to_tile(self, qk: str) -> Tile: ------- Tile """ - if not self.quadkey_support: + if not self.is_quadkey: raise NoQuadkeySupport( "This Tile Matrix Set doesn't support 2 x 2 quadkeys." ) diff --git a/tests/test_models.py b/tests/test_models.py index 3ce8737..cf28b41 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -102,10 +102,10 @@ def test_load(): def test_quadkey_support(): tms = TileMatrixSet.load("CanadianNAD83_LCC") - assert not tms.quadkey_support + assert not tms.is_quadkey tms = TileMatrixSet.load("UPSArcticWGS84Quad") - assert tms.quadkey_support + assert tms.is_quadkey def test_quadkey(): From e1865b68959cf96760380711e266f1c95f8c0da8 Mon Sep 17 00:00:00 2001 From: adrian-knauer Date: Mon, 16 Aug 2021 10:09:05 +0200 Subject: [PATCH 10/13] added tests for failing quadkey methods --- morecantile/models.py | 8 ++++---- tests/test_models.py | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/morecantile/models.py b/morecantile/models.py index 11e0033..5f5a189 100644 --- a/morecantile/models.py +++ b/morecantile/models.py @@ -127,7 +127,7 @@ class TileMatrixSet(BaseModel): wellKnownScaleSet: Optional[AnyHttpUrl] = None boundingBox: Optional[TMSBoundingBox] tileMatrix: List[TileMatrix] - is_quadkey: bool = False + is_quadtree: bool = False class Config: """Configure TileMatrixSet.""" @@ -143,7 +143,7 @@ def sort_tile_matrices(cls, v): def __init__(self, **kwargs): """Check if TileMatrixSet supports quadkeys""" super().__init__(**kwargs) - self.is_quadkey = check_quadkey_support(self.tileMatrix) + self.is_quadtree = check_quadkey_support(self.tileMatrix) def __iter__(self): """Iterate over matrices""" @@ -806,7 +806,7 @@ def quadkey(self, *tile: Tile) -> str: ------- str """ - if not self.is_quadkey: + if not self.is_quadtree: raise NoQuadkeySupport( "This Tile Matrix Set doesn't support 2 x 2 quadkeys." ) @@ -833,7 +833,7 @@ def quadkey_to_tile(self, qk: str) -> Tile: ------- Tile """ - if not self.is_quadkey: + if not self.is_quadtree: raise NoQuadkeySupport( "This Tile Matrix Set doesn't support 2 x 2 quadkeys." ) diff --git a/tests/test_models.py b/tests/test_models.py index cf28b41..e8b9efc 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -102,10 +102,10 @@ def test_load(): def test_quadkey_support(): tms = TileMatrixSet.load("CanadianNAD83_LCC") - assert not tms.is_quadkey + assert not tms.is_quadtree tms = TileMatrixSet.load("UPSArcticWGS84Quad") - assert tms.is_quadkey + assert tms.is_quadtree def test_quadkey(): @@ -134,6 +134,18 @@ def test_quadkey_failure(): tms.quadkey_to_tile("lolwut") +def test_quadkey_not_supported_failure(): + tms = TileMatrixSet.load("NZTM2000") + with pytest.raises(morecantile.errors.NoQuadkeySupport): + tms.quadkey(1, 1, 1) + + +def test_quadkey_to_tile_not_supported_failure(): + tms = TileMatrixSet.load("NZTM2000") + with pytest.raises(morecantile.errors.NoQuadkeySupport): + tms.quadkey_to_tile("3") + + def test_findMatrix(): """Should raise an error when TileMatrix is not found.""" tms = morecantile.tms.get("WebMercatorQuad") From ecb96f6297943a7ffac6d3eddb4689cacead671e Mon Sep 17 00:00:00 2001 From: adrian-knauer Date: Mon, 16 Aug 2021 10:53:11 +0200 Subject: [PATCH 11/13] makes is_quadkey a pydantic PrivateAttr --- morecantile/models.py | 10 +++++----- tests/test_models.py | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/morecantile/models.py b/morecantile/models.py index 5f5a189..53bb58a 100644 --- a/morecantile/models.py +++ b/morecantile/models.py @@ -4,7 +4,7 @@ import warnings from typing import Any, Dict, Iterator, List, Optional, Sequence, Tuple, Union -from pydantic import AnyHttpUrl, BaseModel, Field, validator +from pydantic import AnyHttpUrl, BaseModel, Field, PrivateAttr, validator from rasterio.crs import CRS, epsg_treats_as_latlong, epsg_treats_as_northingeasting from rasterio.features import bounds as feature_bounds from rasterio.warp import transform, transform_bounds, transform_geom @@ -127,7 +127,7 @@ class TileMatrixSet(BaseModel): wellKnownScaleSet: Optional[AnyHttpUrl] = None boundingBox: Optional[TMSBoundingBox] tileMatrix: List[TileMatrix] - is_quadtree: bool = False + _is_quadtree: bool = PrivateAttr() class Config: """Configure TileMatrixSet.""" @@ -143,7 +143,7 @@ def sort_tile_matrices(cls, v): def __init__(self, **kwargs): """Check if TileMatrixSet supports quadkeys""" super().__init__(**kwargs) - self.is_quadtree = check_quadkey_support(self.tileMatrix) + self._is_quadtree = check_quadkey_support(self.tileMatrix) def __iter__(self): """Iterate over matrices""" @@ -806,7 +806,7 @@ def quadkey(self, *tile: Tile) -> str: ------- str """ - if not self.is_quadtree: + if not self._is_quadtree: raise NoQuadkeySupport( "This Tile Matrix Set doesn't support 2 x 2 quadkeys." ) @@ -833,7 +833,7 @@ def quadkey_to_tile(self, qk: str) -> Tile: ------- Tile """ - if not self.is_quadtree: + if not self._is_quadtree: raise NoQuadkeySupport( "This Tile Matrix Set doesn't support 2 x 2 quadkeys." ) diff --git a/tests/test_models.py b/tests/test_models.py index e8b9efc..1d211c3 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -102,10 +102,10 @@ def test_load(): def test_quadkey_support(): tms = TileMatrixSet.load("CanadianNAD83_LCC") - assert not tms.is_quadtree + assert not tms._is_quadtree tms = TileMatrixSet.load("UPSArcticWGS84Quad") - assert tms.is_quadtree + assert tms._is_quadtree def test_quadkey(): From bf7572807d3fdf5137eeaf0288c71a3f507b3041 Mon Sep 17 00:00:00 2001 From: vincentsarago Date: Fri, 20 Aug 2021 13:24:16 +0200 Subject: [PATCH 12/13] update changelog --- CHANGES.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 18489ba..10b3093 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,21 @@ ## 2.1.3 (TBD) * add **NZTM2000Quad** tile matrix set from LINZ (author @blacha, https://github.com/developmentseed/morecantile/pull/57) +* add **quadkey** supports (@author adrian-knauer, https://github.com/developmentseed/morecantile/pull/56) + + ```python + import morecantile + + tms = morecantile.tms.get("WebMercatorQuad") + + # Tile to Quadkey + tms.quadkey(486, 332, 10) + >>> "0313102310" + + # Quadkey to Tile + tms.quadkey_to_tile("0313102310") + >>> Tile(486, 332, 10) + ``` ## 2.1.2 (2021-05-18) From 684147705b35034d676cc7dd10ea1c9a5d6ce4d4 Mon Sep 17 00:00:00 2001 From: vincentsarago Date: Fri, 20 Aug 2021 13:58:50 +0200 Subject: [PATCH 13/13] fix types --- morecantile/models.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/morecantile/models.py b/morecantile/models.py index 53bb58a..94bd7f3 100644 --- a/morecantile/models.py +++ b/morecantile/models.py @@ -810,17 +810,18 @@ def quadkey(self, *tile: Tile) -> str: raise NoQuadkeySupport( "This Tile Matrix Set doesn't support 2 x 2 quadkeys." ) + tile = _parse_tile_arg(*tile) - xtile, ytile, zoom = tile qk = [] - for z in range(zoom, self.minzoom, -1): + for z in range(tile.z, self.minzoom, -1): digit = 0 mask = 1 << (z - 1) - if xtile & mask: + if tile.x & mask: digit += 1 - if ytile & mask: + if tile.y & mask: digit += 2 qk.append(str(digit)) + return "".join(qk) def quadkey_to_tile(self, qk: str) -> Tile: