ProfileXYZ.py 4.48 KiB
# -*- coding: utf-8 -*-

import numpy as np
import pandas as pd
from typing import List

from Model.Geometry.Profile import Profile
from Model.Geometry.PointXYZ import PointXYZ

class ProfileXYZ(Profile):
    def __init__(self, num: int = 0,
                 code1: int = 0, code2: int = 0,
                 kp: float = 0., name: str = ""):
        """ProfileXYZ constructor

        Args:
            num: The number of this profile
            code1: The interpolation code 1
            code2: The interpolation code 2
            kp: Kilometer point
            name: The name of profile

        Returns:
            Nothing.
        """
        super(ProfileXYZ, self).__init__(
            num = num,
            name = name,
            kp = kp,
            code1 = code1, code2 = code2,
            _type = "XYZ",
        )

    def __repr__(self):
        df = pd.DataFrame(columns=["X", "Y", "Z", "Name"],
                          data=[[p.x, p.y, p.z, p.name] for p in self._list_points])
        return f"\nProfileXYZ : {self.name}\n{df}"

    @property
    def header(self):
        """
        Returns:
            Profile header.
        """
        return np.array(
            [self._num, self._code1, self._code2,
             self.nb_points(), self._kp, self._name]
        )

    def import_points(self, list_points: list):
        """Import a list of points to profile

        Args:
            list_points: Liste of PointXYZ

        Returns:
            Nothing.
        """
        for point in list_points:
            pt = PointXYZ(*point)
            self._list_points.append(pt)

    def get_point_i(self, index: int) -> PointXYZ:
        """Get point at index.

        Args:
            index: Index of point.

        Returns:
            The point.
        """
        try:
            return self._list_points[index]
        except IndexError:
            raise IndexError(f"Invalid point index: {index}")

    def add(self):
        """Add a new PointXYZ to profile.

        Returns:
            Nothing.
        """
        point_xyz = PointXYZ(0., 0., 0.)
        self._list_points.append(point_xyz)

    def delete(self, index: int):
        """Delete the point at index

        Args:
            index: Index of point.

        Returns:
            Nothing.
        """
        try:
            self._list_points.pop(index)
        except IndexError:
            raise IndexError(f"Invalid point index: {index}")

    def insert(self, index: int):
        """Insert a new profile at index.

        Args:
            index: The index of new profile.

        Returns:
            Nothing.
        """
        profile = ProfileXYZ()
        self._list_points.insert(index, profile)

    def delete1(self, list_index: list):
        """Delete a list of points

        Args:
            list_index: Indexes list.

        Returns:
            Nothing.
        """
        try:
            if list_index:
                indices = sorted(list(set(list_index)), reverse=True)
                for idx in indices:
                    # if idx < len(self._list_profiles) :
                    try:
                        self._list_points.pop(idx)
                    except IndexError:
                        print("Empty list, nothing to delete")
        except TypeError:
            if isinstance(list_index, int):
                self._list_points.pop(list_index)
                print(f"\n{list_index} is not a list\n")
            else:
                raise TypeError(
                    f"{list_index} is instance of unexpected type '{type(list_index)}'"
                )

    def filter_isnan(self, lst):
        """Returns the input list without 'nan' element

        Args:
            lst: The list to filter

        Returns:
            The list without 'nan'
        """
        return [x for x in lst if not np.isnan(x)]

    def x(self):
        return [point.x for point in self._list_points]

    def y(self):
        return [point.y for point in self._list_points]

    def z(self):
        return [point.z for point in self._list_points]

    def names(self):
        return [point.name for point in self._list_points]

    def x_max(self):
        return max(self.filter_isnan(self.x))

    def x_min(self):
        return min(self.filter_isnan(self.x))

    def y_max(self):
        return max(self.filter_isnan(self.y))

    def y_min(self):
        return min(self.filter_isnan(self.y))

    def z_max(self):
        return max(self.filter_isnan(self.z))

    def z_min(self):
        return min(self.filter_isnan(self.z))