torch-geopooling 1.2.0__cp312-cp312-manylinux_2_28_aarch64.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.
Potentially problematic release.
This version of torch-geopooling might be problematic. Click here for more details.
- torch_geopooling/_C.cpython-312-aarch64-linux-gnu.so +0 -0
- torch_geopooling/__bind__/python_module.cc +28 -0
- torch_geopooling/__init__.py +3 -0
- torch_geopooling/functional/__init__.py +2 -0
- torch_geopooling/functional/embedding.py +92 -0
- torch_geopooling/functional/embedding_test.py +32 -0
- torch_geopooling/functional/pooling.py +354 -0
- torch_geopooling/functional/pooling_test.py +100 -0
- torch_geopooling/nn/__init__.py +2 -0
- torch_geopooling/nn/embedding.py +102 -0
- torch_geopooling/nn/embedding_test.py +48 -0
- torch_geopooling/nn/pooling.py +396 -0
- torch_geopooling/nn/pooling_test.py +158 -0
- torch_geopooling/py.typed +0 -0
- torch_geopooling/return_types.py +29 -0
- torch_geopooling/tiling.py +97 -0
- torch_geopooling/transforms.py +103 -0
- torch_geopooling/transforms_test.py +37 -0
- torch_geopooling-1.2.0.dist-info/METADATA +786 -0
- torch_geopooling-1.2.0.dist-info/RECORD +24 -0
- torch_geopooling-1.2.0.dist-info/WHEEL +5 -0
- torch_geopooling-1.2.0.dist-info/dependency_links.txt +1 -0
- torch_geopooling-1.2.0.dist-info/licenses/LICENSE +674 -0
- torch_geopooling-1.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Copyright (C) 2024, Yakau Bubnou
|
|
2
|
+
#
|
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
15
|
+
|
|
16
|
+
from typing import NamedTuple
|
|
17
|
+
|
|
18
|
+
from torch import Tensor
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class quad_pool2d(NamedTuple):
|
|
22
|
+
tiles: Tensor
|
|
23
|
+
weight: Tensor
|
|
24
|
+
values: Tensor
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class adaptive_quad_pool2d(NamedTuple):
|
|
28
|
+
weight: Tensor
|
|
29
|
+
values: Tensor
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections import deque
|
|
4
|
+
from itertools import product
|
|
5
|
+
from typing import Iterator, NamedTuple, Tuple
|
|
6
|
+
|
|
7
|
+
from shapely.geometry import Polygon
|
|
8
|
+
|
|
9
|
+
__all__ = ["Exterior", "ExteriorTuple", "Tile", "regular_tiling"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Tile(NamedTuple):
|
|
13
|
+
z: int
|
|
14
|
+
x: int
|
|
15
|
+
y: int
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def root(cls) -> Tile:
|
|
19
|
+
return cls(0, 0, 0)
|
|
20
|
+
|
|
21
|
+
def child(self, x: int, y: int) -> Tile:
|
|
22
|
+
return Tile(self.z + 1, self.x * 2 + x, self.y * 2 + y)
|
|
23
|
+
|
|
24
|
+
def children(self) -> Iterator[Tile]:
|
|
25
|
+
for x, y in product(range(2), range(2)):
|
|
26
|
+
yield self.child(x, y)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
ExteriorTuple = Tuple[float, float, float, float]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Exterior(NamedTuple):
|
|
33
|
+
xmin: float
|
|
34
|
+
ymin: float
|
|
35
|
+
width: float
|
|
36
|
+
height: float
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def from_tuple(cls, exterior_tuple: ExteriorTuple) -> Exterior:
|
|
40
|
+
return cls(*exterior_tuple)
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def xmax(self) -> float:
|
|
44
|
+
return self.xmin + self.width
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def ymax(self) -> float:
|
|
48
|
+
return self.ymin + self.height
|
|
49
|
+
|
|
50
|
+
def slice(self, tile: Tile) -> Exterior:
|
|
51
|
+
w = self.width / (1 << tile.z)
|
|
52
|
+
h = self.height / (1 << tile.z)
|
|
53
|
+
return Exterior(self.xmin + tile.x * w, self.ymin + tile.y * h, w, h)
|
|
54
|
+
|
|
55
|
+
def as_polygon(self) -> Polygon:
|
|
56
|
+
return Polygon(
|
|
57
|
+
[
|
|
58
|
+
(self.xmin, self.ymin),
|
|
59
|
+
(self.xmax, self.ymin),
|
|
60
|
+
(self.xmax, self.ymax),
|
|
61
|
+
(self.xmin, self.ymax),
|
|
62
|
+
]
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def regular_tiling(
|
|
67
|
+
polygon: Polygon, exterior: Exterior, z: int, internal: bool = False
|
|
68
|
+
) -> Iterator[Tile]:
|
|
69
|
+
"""Returns a regular quad-tiling (tiles of the same size).
|
|
70
|
+
|
|
71
|
+
Method returns all tiles of level (z) that have a common intersection with a specified
|
|
72
|
+
polygon.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
polygon: A polygon to cover with tiles.
|
|
76
|
+
exterior: Exterior (bounding box) of the quadtree. For example, for geospatial
|
|
77
|
+
coordinates, this will be `(-180.0, -90.0, 360.0, 180.0)`.
|
|
78
|
+
z: Zoom level of the tiles.
|
|
79
|
+
internal: When `True`, returns internal tiles (nodes) of the quadtree up to a root
|
|
80
|
+
tile (0,0,0).
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
Iterator of tiles.
|
|
84
|
+
"""
|
|
85
|
+
queue = deque([Tile.root()])
|
|
86
|
+
|
|
87
|
+
while len(queue) > 0:
|
|
88
|
+
tile = queue.pop()
|
|
89
|
+
|
|
90
|
+
tile_poly = exterior.slice(tile).as_polygon()
|
|
91
|
+
if not tile_poly.intersects(polygon):
|
|
92
|
+
continue
|
|
93
|
+
|
|
94
|
+
if internal or tile.z >= z:
|
|
95
|
+
yield tile
|
|
96
|
+
if tile.z < z:
|
|
97
|
+
queue.extend(tile.children())
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Copyright (C) 2024, Yakau Bubnou
|
|
2
|
+
#
|
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from typing import Iterator, Tuple
|
|
19
|
+
|
|
20
|
+
from torch import Tensor
|
|
21
|
+
|
|
22
|
+
from torch_geopooling.tiling import Tile
|
|
23
|
+
|
|
24
|
+
__all__ = ["TileWKT"]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class _TileSet(set):
|
|
28
|
+
def __init__(self, tiles: Tensor) -> None:
|
|
29
|
+
super().__init__(Tile(*tile.detach().tolist()) for tile in tiles)
|
|
30
|
+
|
|
31
|
+
def is_terminal(self, tile: Tile) -> bool:
|
|
32
|
+
return (
|
|
33
|
+
(tile.child(0, 0) not in self)
|
|
34
|
+
and (tile.child(0, 1) not in self)
|
|
35
|
+
and (tile.child(1, 0) not in self)
|
|
36
|
+
and (tile.child(1, 1) not in self)
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class TileWKT:
|
|
41
|
+
"""Convert a Tile to a WKT polygon given the exterior of the whole geometry.
|
|
42
|
+
|
|
43
|
+
Module returns a tile geometry in WKT format, which comprises a polygon.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
exterior: Exterior coordinates in (X, Y, W, H) format. The exterior is used to calculate
|
|
47
|
+
boundaries of a tile to produce a final WKT.
|
|
48
|
+
precision: A precision of the resulting geometry, digits after the decimal point.
|
|
49
|
+
internal: When `True`, output includes internal nodes of the quadtree tiles.
|
|
50
|
+
Otherwise (default) returns only geometry of terminal nodes.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
def __init__(
|
|
54
|
+
self,
|
|
55
|
+
exterior: Tuple[float, float, float, float],
|
|
56
|
+
precision: int = 7,
|
|
57
|
+
internal: bool = False,
|
|
58
|
+
) -> None:
|
|
59
|
+
self.exterior = tuple(map(float, exterior))
|
|
60
|
+
self.precision = precision
|
|
61
|
+
self.internal = internal
|
|
62
|
+
|
|
63
|
+
self._xmin, self._ymin, self._width, self._height = exterior
|
|
64
|
+
if self._width <= 0:
|
|
65
|
+
raise ValueError(f"exterior width should be >0, got {self._width}")
|
|
66
|
+
if self._height <= 0:
|
|
67
|
+
raise ValueError(f"exterior height should be >0, got {self._height}")
|
|
68
|
+
|
|
69
|
+
def __call__(self, tiles: Tensor) -> Iterator[str]:
|
|
70
|
+
if len(tiles.size()) != 2:
|
|
71
|
+
raise ValueError(f"tiles tensor must be a 2D tensor, got {tiles.size()} shape")
|
|
72
|
+
|
|
73
|
+
if tiles.size(1) != 3:
|
|
74
|
+
raise ValueError(
|
|
75
|
+
f"tiles should be triplets of (z, x, y), got tensor of shape {tiles.size()}"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
tileset = _TileSet(tiles)
|
|
79
|
+
|
|
80
|
+
for tile in tiles:
|
|
81
|
+
z, x, y = tile.detach().tolist()
|
|
82
|
+
width = self._width / (1 << z)
|
|
83
|
+
height = self._height / (1 << z)
|
|
84
|
+
|
|
85
|
+
if (not self.internal) and (not tileset.is_terminal(Tile(z, x, y))):
|
|
86
|
+
continue
|
|
87
|
+
|
|
88
|
+
xmin = self._xmin + width * x
|
|
89
|
+
xmax = round(xmin + width, self.precision)
|
|
90
|
+
xmin = round(xmin, self.precision)
|
|
91
|
+
|
|
92
|
+
ymin = self._ymin + height * y
|
|
93
|
+
ymax = round(ymin + height, self.precision)
|
|
94
|
+
ymin = round(ymin, self.precision)
|
|
95
|
+
|
|
96
|
+
yield (
|
|
97
|
+
"POLYGON (("
|
|
98
|
+
f"{xmin} {ymin}, {xmax} {ymin}, {xmax} {ymax}, {xmin} {ymax}, {xmin} {ymin}"
|
|
99
|
+
"))"
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
def __repr__(self) -> str:
|
|
103
|
+
return f"{self.__class__.__name__}(exterior={self.exterior})"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Copyright (C) 2024, Yakau Bubnou
|
|
2
|
+
#
|
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
15
|
+
|
|
16
|
+
import torch
|
|
17
|
+
|
|
18
|
+
from torch_geopooling.transforms import TileWKT
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_tile_wkt() -> None:
|
|
22
|
+
tile_wkt4 = TileWKT(exterior=(0.0, 0.0, 10.0, 10.0), internal=False)
|
|
23
|
+
tile_wkt5 = TileWKT(exterior=(0.0, 0.0, 10.0, 10.0), internal=True)
|
|
24
|
+
|
|
25
|
+
tiles = torch.tensor(
|
|
26
|
+
[
|
|
27
|
+
[0, 0, 0],
|
|
28
|
+
[1, 0, 0],
|
|
29
|
+
[1, 0, 1],
|
|
30
|
+
[1, 1, 0],
|
|
31
|
+
[1, 1, 1],
|
|
32
|
+
],
|
|
33
|
+
dtype=torch.int32,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
assert len(list(tile_wkt4(tiles))) == 4
|
|
37
|
+
assert len(list(tile_wkt5(tiles))) == 5
|