Profile.py 5.57 KiB
# -*- coding: utf-8 -*-

from tools import timer

from Model.Geometry.Point import Point
from Model.Except import NotImplementedMethodeError

class Profile(object):
    _id_cnt = 0

    def __init__(self, id:int = -1, num:int = 0,
                 kp:float = 0.0, name:str = "",
                 code1:int = 0, code2:int = 0,
                 _type:str = "", reach = None,
                 status = None):
        super(Profile, self).__init__()

        self._status = status

        if id == -1:
            self.id = Profile._id_cnt
            Profile._id_cnt += 1
        else:
            self.id = id

        self._num = int(num)
        self._code1 = int(code1)
        self._code2 = int(code2)
        self._kp = float(kp)
        self._name = str(name)
        self._reach = reach

        self._points: List[Point] = []

        self._profile_type = _type

    @property
    def number_points(self):
        return len(self._points)

    @property
    def points(self):
        return self._points.copy()

    @property
    def reach(self):
        return self._reach

    @property
    def num(self):
        """
        Returns:
            Number of profile.
        """
        return self._num

    @num.setter
    def num(self, value: int):
        self._num = int(value)
        self._status.modified()

    @property
    def code1(self):
        """
        Returns:
            Interpolation code 1.
        """
        return self._code1

    @code1.setter
    def code1(self, value: int):
        self._code1 = int(value)
        self._status.modified()

    @property
    def code2(self):
        """
        Returns:
            Interpolation code 2.
        """
        return self._code2

    @code2.setter
    def code2(self, value: int):
        self._code2 = int(value)
        self._status.modified()

    @property
    def nb_points(self):
        return len(self._points)

    @property
    def kp(self):
        """
        Returns:
            Kilometer point.
        """
        return self._kp

    @kp.setter
    def kp(self, value: float):
        self._kp = float(value)
        self._status.modified()

    @property
    def name(self):
        """
        Returns:
            Profile name.
        """
        return self._name

    @name.setter
    def name(self, value: str):
        self._name = value.strip()
        self._status.modified()

    @property
    def profile_type(self):
        """
        Returns:
            Profile type.
        """
        return self._profile_type

    @profile_type.setter
    def profile_type(self, value: str):
        self._profile_type = value
        self._status.modified()

    def point(self, i:int):
        if i < len(self._points):
            return self._points[i]

        return None

    def named_points(self):
        """List of named point

        Returns:
            The list of named point
        """
        return [point for point in self._points
                if point.point_is_named()]


    def insert_point(self, index: int, point:Point):
        """Insert point at index.

        Args:
            index: The index of new profile.
            point: The point.

        Returns:
            Nothing.
        """
        self._points.insert(index, point)
        self._status.modified()


    def delete(self, indexes: int):
        """Delete points at index

        Args:
            indexes: List of index of points.

        Returns:
            Nothing.
        """
        points = set(
            map(
                lambda e: e[1],
                filter(
                    lambda e: e[0] in indexes,
                    enumerate(self.points)
                )
            )
        )

        self._points = list(
            filter(
                lambda p: p not in points,
                self.points
            )
        )
        self._status.modified()

    def delete_points(self, points):
        """Delete some elements in profile list

        Args:
            points: The list of profile to delete

        Returns:
            Nothing.
        """
        self._points = list(
            filter(
                lambda p: p not in points,
                self.points
            )
        )
        self._status.modified()

    # Move

    def move_up_point(self, index: int):
        if index < len(self._points):
            next = index - 1

            p = self._points
            p[index], p[next] = p[next], p[index]
            self._status.modified()

    def move_down_point(self, index: int):
        if index >= 0:
            prev = index + 1

            p = self._points
            p[index], p[prev] = p[prev], p[index]
            self._status.modified()

    # Sort

    @timer
    def sort(self, column, is_reversed: bool = False):
        predicate = lambda p: p.x
        if column == 'y':
            predicate = lambda p: p.y
        elif column == 'z':
            predicate = lambda p: p.z

        self._points = sorted(
            self._points,
            key=predicate,
            reverse=is_reversed
        )
        self._status.modified()

    @timer
    def sort_with_indexes(self, indexes: list):
        if len(self._points) != len(indexes):
            print("TODO: CRITICAL ERROR!")

        self._points = list(
            map(
                lambda x: x[1],
                sorted(
                    enumerate(self.points),
                    key=lambda x: indexes[x[0]]
                )
            )
        )
        self._status.modified()

    # Abstract method, must be implemented for in non abstract class
    def get_station(self):
        raise NotImplementedMethodeError(self, self.get_station)