From 05eb7a5c9bcff45045fd5f5833d4889f08e4a4c9 Mon Sep 17 00:00:00 2001 From: Daniel Sparber Date: Thu, 26 Oct 2023 13:25:46 +0200 Subject: [PATCH] webmercator_tile_info.py: added parent and ancestors --- tiles/tests/test_webmercator_tile_info.py | 6 ++++++ tiles/webmercator_tile_info.py | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/tiles/tests/test_webmercator_tile_info.py b/tiles/tests/test_webmercator_tile_info.py index 5c92137..3a4133b 100644 --- a/tiles/tests/test_webmercator_tile_info.py +++ b/tiles/tests/test_webmercator_tile_info.py @@ -88,5 +88,11 @@ def test_descendants(self) -> None: set(root.descendants(max_zoom=1)), {root}.union(root.children) ) + def test_ancestors(self) -> None: + switzerland = WebmercatorTileInfo(zoom=6, x=33, y=22) + self.assertEqual(WebmercatorTileInfo(zoom=5, x=16, y=11), switzerland.parent) + ancestors = set(switzerland.ancestors()) + self.assertEqual(len(ancestors), 7) + def test_path(self) -> None: self.assertEqual(WebmercatorTileInfo(zoom=3, x=2, y=1).path, "3/2/1") diff --git a/tiles/webmercator_tile_info.py b/tiles/webmercator_tile_info.py index 8eb9980..2128288 100644 --- a/tiles/webmercator_tile_info.py +++ b/tiles/webmercator_tile_info.py @@ -57,6 +57,10 @@ def children(self) -> set[WebmercatorTileInfo]: WebmercatorTileInfo(zoom=zoom, x=x0 + 1, y=y0 + 1), } + @property + def parent(self) -> WebmercatorTileInfo: + return WebmercatorTileInfo(zoom=self.zoom - 1, x=self.x // 2, y=self.y // 2) + def descendants(self, max_zoom: int, min_zoom: int = 0) -> Iterable[TileInfo]: if self.zoom > max_zoom: return [] @@ -67,3 +71,17 @@ def descendants(self, max_zoom: int, min_zoom: int = 0) -> Iterable[TileInfo]: for child in self.children: for descendant in child.descendants(min_zoom=min_zoom, max_zoom=max_zoom): yield descendant + + def ancestors(self, min_zoom: int = 0, max_zoom: int = 30) -> Iterable[TileInfo]: + if self.zoom <= max_zoom: + yield self + + if self.zoom > min_zoom: + yield self.parent + for ancestor in self.parent.ancestors(min_zoom, max_zoom): + yield ancestor + + def overlapping(self, min_zoom: int = 0, max_zoom: int = 30) -> Iterable[TileInfo]: + return set(self.ancestors(min_zoom=min_zoom, max_zoom=max_zoom)).union( + self.descendants(min_zoom=min_zoom, max_zoom=max_zoom) + )