๐Ÿ“ฆ Zaczero / osm-budynki-orto-import

๐Ÿ“„ polygon.py ยท 42 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42from base64 import urlsafe_b64encode
from hashlib import sha256
from typing import NamedTuple, Sequence

from box import Box
from latlon import LatLon


class Polygon(NamedTuple):
    points: Sequence[LatLon]

    # def extend(self, meters: float) -> Self:
    #     points_arr = np.array(self.points)
    #     edge_vectors = np.roll(points_arr, -1, axis=0) - points_arr
    #     edge_vectors[-1] = points_arr[0] - points_arr[-1]
    #     normal_vectors = np.stack([-edge_vectors[:, 1], edge_vectors[:, 0]], axis=-1)
    #     normal_vectors /= np.linalg.norm(normal_vectors, axis=1, keepdims=True)
    #     return Polygon(tuple(points_arr + normal_vectors * meters_to_lat(meters)))

    def get_bounding_box(self) -> Box:
        min_lat = min(p.lat for p in self.points)
        max_lat = max(p.lat for p in self.points)
        min_lon = min(p.lon for p in self.points)
        max_lon = max(p.lon for p in self.points)

        return Box(
            point=LatLon(min_lat, min_lon),
            size=LatLon(max_lat - min_lat, max_lon - min_lon),
        )

    def unique_id(self) -> str:
        precision = 0.00003
        rounded_points = (
            f'{(round(p.lat / precision) * precision):.5f},{(round(p.lon / precision) * precision):.5f}'
            for p in self.points)
        return ';'.join(sorted(rounded_points))

    def unique_id_hash(self, size: int = 6) -> str:
        result = sha256(self.unique_id().encode(), usedforsecurity=False).digest()
        result = result[:size]
        return urlsafe_b64encode(result).decode()