Skip to content

Commit

Permalink
revert and update xy_bounds and bounds methods
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentsarago committed Oct 16, 2024
1 parent c98b77d commit 3a8bed8
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 35 deletions.
77 changes: 50 additions & 27 deletions morecantile/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,14 +487,15 @@ class TileMatrixSet(BaseModel, arbitrary_types_allowed=True):
# Private attributes
_to_geographic: pyproj.Transformer = PrivateAttr()
_from_geographic: pyproj.Transformer = PrivateAttr()
_tile_matrices_idx: Dict[str, int] = PrivateAttr()

_tile_matrices_idx: Dict[int, int] = PrivateAttr()

def __init__(self, **data):
"""Set private attributes."""
super().__init__(**data)

self._tile_matrices_idx = {
mat.id: idx for idx, mat in enumerate(self.tileMatrices)
int(mat.id): idx for idx, mat in enumerate(self.tileMatrices)
}

try:
Expand Down Expand Up @@ -770,7 +771,7 @@ def custom(

def matrix(self, zoom: int) -> TileMatrix:
"""Return the TileMatrix for a specific zoom."""
if (idx := self._tile_matrices_idx.get(str(zoom), None)) is not None:
if (idx := self._tile_matrices_idx.get(zoom, None)) is not None:
return self.tileMatrices[idx]

#######################################################################
Expand Down Expand Up @@ -1025,58 +1026,61 @@ def tile(
x, y = self.xy(lng, lat, truncate=truncate)
return self._tile(x, y, zoom, ignore_coalescence=ignore_coalescence)

def _ul(self, tile: Tile) -> Coords:
def _ul(self, *tile: Tile) -> Coords:
"""
Return the upper left coordinate of the tile in TMS coordinate reference system.
Attributes
----------
tile: Tile object we want the upper left coordinates of.
tile: (x, y, z) tile coordinates or a Tile object we want the upper left coordinates of.
Returns
-------
Coords: The upper left coordinates of the input tile.
"""
matrix = self.matrix(tile.z)
t = _parse_tile_arg(*tile)

matrix = self.matrix(t.z)
origin_x, origin_y = self._matrix_origin(matrix)

cf = (
matrix.get_coalesce_factor(tile.y)
matrix.get_coalesce_factor(t.y)
if matrix.variableMatrixWidths is not None
else 1
)
return Coords(
origin_x
+ math.floor(tile.x / cf) * matrix.cellSize * cf * matrix.tileWidth,
origin_y - tile.y * matrix.cellSize * matrix.tileHeight,
origin_x + math.floor(t.x / cf) * matrix.cellSize * cf * matrix.tileWidth,
origin_y - t.y * matrix.cellSize * matrix.tileHeight,
)

def _lr(self, tile: Tile) -> Coords:
def _lr(self, *tile: Tile) -> Coords:
"""
Return the lower right coordinate of the tile in TMS coordinate reference system.
Attributes
----------
tile: Tile object we want the lower right coordinates of.
tile: (x, y, z) tile coordinates or a Tile object we want the lower right coordinates of.
Returns
-------
Coords: The lower right coordinates of the input tile.
"""
matrix = self.matrix(tile.z)
t = _parse_tile_arg(*tile)

matrix = self.matrix(t.z)
origin_x, origin_y = self._matrix_origin(matrix)

cf = (
matrix.get_coalesce_factor(tile.y)
matrix.get_coalesce_factor(t.y)
if matrix.variableMatrixWidths is not None
else 1
)
return Coords(
origin_x
+ (math.floor(tile.x / cf) + 1) * matrix.cellSize * cf * matrix.tileWidth,
origin_y - (tile.y + 1) * matrix.cellSize * matrix.tileHeight,
+ (math.floor(t.x / cf) + 1) * matrix.cellSize * cf * matrix.tileWidth,
origin_y - (t.y + 1) * matrix.cellSize * matrix.tileHeight,
)

def xy_bounds(self, *tile: Tile) -> BoundingBox:
Expand All @@ -1094,40 +1098,59 @@ def xy_bounds(self, *tile: Tile) -> BoundingBox:
"""
t = _parse_tile_arg(*tile)

left, top = self._ul(t)
right, bottom = self._lr(t)
matrix = self.matrix(t.z)
origin_x, origin_y = self._matrix_origin(matrix)

cf = (
matrix.get_coalesce_factor(t.y)
if matrix.variableMatrixWidths is not None
else 1
)

left = origin_x + math.floor(t.x / cf) * matrix.cellSize * cf * matrix.tileWidth
top = origin_y - t.y * matrix.cellSize * matrix.tileHeight
right = (
origin_x
+ (math.floor(t.x / cf) + 1) * matrix.cellSize * cf * matrix.tileWidth
)
bottom = origin_y - (t.y + 1) * matrix.cellSize * matrix.tileHeight

return BoundingBox(left, bottom, right, top)

def ul(self, tile: Tile) -> Coords:
def ul(self, *tile: Tile) -> Coords:
"""
Return the upper left coordinates of the tile in geographic coordinate reference system.
Attributes
----------
tile (Tile): Tile object we want the upper left geographic coordinates of.
tile (tuple or Tile): (x, y, z) tile coordinates or a Tile object we want the upper left geographic coordinates of.
Returns
-------
Coords: The upper left geographic coordinates of the input tile.
"""
x, y = self._ul(tile)
t = _parse_tile_arg(*tile)

x, y = self._ul(t)
return Coords(*self.lnglat(x, y))

def lr(self, tile: Tile) -> Coords:
def lr(self, *tile: Tile) -> Coords:
"""
Return the lower right coordinates of the tile in geographic coordinate reference system.
Attributes
----------
tile (Tile): Tile object we want the lower right geographic coordinates of.
tile (tuple or Tile): (x, y, z) tile coordinates or a Tile object we want the lower right geographic coordinates of.
Returns
-------
Coords: The lower right geographic coordinates of the input tile.
"""
x, y = self._lr(tile)
t = _parse_tile_arg(*tile)

x, y = self._lr(t)
return Coords(*self.lnglat(x, y))

def bounds(self, *tile: Tile) -> BoundingBox:
Expand All @@ -1143,10 +1166,10 @@ def bounds(self, *tile: Tile) -> BoundingBox:
BoundingBox: The bounding box of the input tile.
"""
t = _parse_tile_arg(*tile)
_left, _bottom, _right, _top = self.xy_bounds(*tile)
left, top = self.lnglat(_left, _top)
right, bottom = self.lnglat(_right, _bottom)

left, top = self.ul(t)
right, bottom = self.lr(t)
return BoundingBox(left, bottom, right, top)

@property
Expand Down
1 change: 0 additions & 1 deletion morecantile/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ def _parse_tile_arg(*args) -> Tile:
"""
if len(args) == 1:
args = args[0]

if len(args) == 3:
return Tile(*args)
else:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ def test_mars_local_tms():
assert syrtis_tms.geographic_crs
assert syrtis_tms.model_dump(mode="json")

center = syrtis_tms.ul(Tile(1, 1, 1))
center = syrtis_tms.ul(1, 1, 1)
assert round(center.x, 6) == 76.5
assert round(center.y, 6) == 17

Expand Down
15 changes: 9 additions & 6 deletions tests/test_morecantile.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def test_ul_tile():
test form https://github.com/mapbox/mercantile/blob/master/tests/test_funcs.py
"""
tms = morecantile.tms.get("WebMercatorQuad")
xy = tms.ul(morecantile.Tile(486, 332, 10))
xy = tms.ul(486, 332, 10)
expected = (-9.140625, 53.33087298301705)
for a, b in zip(expected, xy):
assert round(a - b, 6) == 0
Expand All @@ -146,7 +146,7 @@ def test_projul_tile():
test form https://github.com/mapbox/mercantile/blob/master/tests/test_funcs.py
"""
tms = morecantile.tms.get("WebMercatorQuad")
xy = tms._ul(morecantile.Tile(486, 332, 10))
xy = tms._ul(486, 332, 10)
expected = (-1017529.7205322663, 7044436.526761846)
for a, b in zip(expected, xy):
assert round(a - b, 6) == 0
Expand Down Expand Up @@ -191,12 +191,15 @@ def test_feature():

################################################################################
# replicate mercantile tests
def test_ul():
# https://github.com/mapbox/mercantile/blob/master/tests/test_funcs.py
@pytest.mark.parametrize(
"args", [(486, 332, 10), [(486, 332, 10)], [morecantile.Tile(486, 332, 10)]]
)
def test_ul(args):
"""test args."""
tile = morecantile.Tile(486, 332, 10)
tms = morecantile.tms.get("WebMercatorQuad")
expected = (-9.140625, 53.33087298301705)
lnglat = tms.ul(tile)
lnglat = tms.ul(*args)
for a, b in zip(expected, lnglat):
assert round(a - b, 6) == 0
assert lnglat[0] == lnglat.x
Expand All @@ -222,7 +225,7 @@ def test_bbox(args):
def test_xy_tile():
"""x, y for the 486-332-10 tile is correctly calculated."""
tms = morecantile.tms.get("WebMercatorQuad")
ul = tms.ul(morecantile.Tile(486, 332, 10))
ul = tms.ul(486, 332, 10)
xy = tms.xy(*ul)
expected = (-1017529.7205322663, 7044436.526761846)
for a, b in zip(expected, xy):
Expand Down

0 comments on commit 3a8bed8

Please sign in to comment.