tree.py 1.42 KB
Newer Older
1
from dataclasses import dataclass
Eric Duminil's avatar
Eric Duminil committed
2
from collections import UserList
3
4
import kdtree

Eric Duminil's avatar
Eric Duminil committed
5

6
7
8
9
10
11
12
13
@dataclass
class Tree:
    x: float
    y: float
    z: float = 0
    height: float = None
    radius: float = None
    type: str = None
Eric Duminil's avatar
Eric Duminil committed
14
    description: str = '?'
Eric Duminil's avatar
Eric Duminil committed
15
    color: str = 'green'
16
17

    def __len__(self):
Eric Duminil's avatar
Eric Duminil committed
18
        return 2  # x & y
19
20
21
22

    def __getitem__(self, i):
        return [self.x, self.y][i]

Eric Duminil's avatar
Eric Duminil committed
23
    def __str__(self):
Eric Duminil's avatar
Eric Duminil committed
24
        return f"{self.type} ({self.description}), {self.radius or '?'} m (X={self.x:.1f}, Y={self.y:.1f})"
Eric Duminil's avatar
Eric Duminil committed
25

26

Eric Duminil's avatar
Eric Duminil committed
27
class Forest(UserList):
28
29
30
31
32
33
    def __init__(self, existing_trees=[]):
        if existing_trees:
            self.kd_tree = kdtree.create(existing_trees, dimensions=2)
        else:
            self.kd_tree = kdtree.create([(0, 0)], dimensions=2)

Eric Duminil's avatar
Eric Duminil committed
34
        self.data = existing_trees
35

Eric Duminil's avatar
Eric Duminil committed
36
    def add_tree_if_possible(self, min_distance_2, x, y, **kparams):
Eric Duminil's avatar
Eric Duminil committed
37
38
39
        _nearest_tree, distance_2 = self.kd_tree.search_nn((x, y))
        if distance_2 > min_distance_2:
            self.kd_tree.add((x, y))
Eric Duminil's avatar
Eric Duminil committed
40
            self.append(Tree(x, y, **kparams))
Eric Duminil's avatar
Eric Duminil committed
41
42

    @property
Eric Duminil's avatar
Eric Duminil committed
43
44
45
    def xs_ys_cs(self):
        xs, ys, colors = [], [], []
        for tree in self:
Eric Duminil's avatar
Eric Duminil committed
46
47
            xs.append(tree.x)
            ys.append(tree.y)
Eric Duminil's avatar
Eric Duminil committed
48
49
            colors.append(tree.color)
        return xs, ys, colors
Eric Duminil's avatar
Eric Duminil committed
50

51
    def __str__(self):
Eric Duminil's avatar
Eric Duminil committed
52
        return f"Forest with {len(self)} trees."
53
54

    def __repr__(self):
Eric Duminil's avatar
Eric Duminil committed
55
        return "\n".join([str(self)] + [str(tree) for tree in self])