rawanessam's picture
Upload 39 files
26f7fa0 verified
"""
MLSTRUCT-FP - DB - C
Base FP components.
"""
__all__ = ['BaseComponent', 'BasePolyComponent', 'BasePolyObj']
import abc
import matplotlib.pyplot as plt
import plotly.graph_objects as go
from MLStructFP.utils import GeomPoint2D
from MLStructFP._types import List, TYPE_CHECKING, VectorInstance, NumberType, Dict
if TYPE_CHECKING:
from MLStructFP.db._floor import Floor
class BaseComponent(abc.ABC):
"""
Floor plan base component.
"""
_floor: 'Floor'
_id: int
_points: List['GeomPoint2D'] # The coordinates of the object
def __init__(
self,
component_id: int,
x: List[float],
y: List[float],
floor: 'Floor'
) -> None:
"""
Constructor.
:param component_id: ID of the component
:param x: List of coordinates within x-axis
:param y: List of coordinates within y-axis
:param floor: Floor object
"""
assert isinstance(component_id, int) and component_id > 0
assert isinstance(x, VectorInstance) and len(x) > 0
assert isinstance(y, VectorInstance) and len(y) == len(x)
self._floor = floor
self._id = component_id
self._points = []
for i in range(len(x)):
self._points.append(GeomPoint2D(float(x[i]), float(y[i])))
@property
def floor(self) -> 'Floor':
return self._floor
@property
def id(self) -> int:
return self._id
@property
def points(self) -> List['GeomPoint2D']:
return [p for p in self._points]
def plot_plotly(self, *args, **kwargs) -> None:
"""
Plot rect.
"""
raise NotImplementedError
def plot_matplotlib(self, *args, **kwargs) -> None:
"""
Plot simple using matplotlib.
"""
raise NotImplementedError
class BasePolyComponent(BaseComponent, abc.ABC):
"""
Polygonal-type base component.
"""
def __svg_path(self, dx: NumberType = 0, dy: NumberType = 0) -> str:
"""
Get svg path for plotting the object.
:return: SVG path string
:param dx: X displacement
:param dy: Y displacement
"""
px, py = [p.x for p in self._points], [p.y for p in self._points]
for i in range(len(px)): # Adds displacement (dx, dy)
px[i] += dx
py[i] += dy
svg = f'M {px[0]},{py[0]}'
for i in range(1, len(px)):
svg += f' L{px[i]},{py[i]}'
svg += ' Z'
return svg
# noinspection PyUnusedLocal
def plot_plotly(
self,
fig: 'go.Figure',
dx: NumberType,
dy: NumberType,
opacity: NumberType,
color: str,
name: str,
**kwargs
) -> None:
"""
Plot polygon object.
:param fig: Figure object
:param dx: X displacement
:param dy: Y displacement
:param opacity: Object opacity
:param color: Color
:param name: Object name
:param kwargs: Optional keyword arguments
"""
_path = self.__svg_path(dx=dx, dy=dy)
fig.add_shape(
fillcolor=color,
line_color=color,
name=name,
opacity=opacity,
path=_path,
type='path'
)
def plot_matplotlib(
self,
ax: 'plt.Axes',
linewidth: NumberType,
alpha: NumberType,
color: str,
fill: bool
) -> None:
"""
Plot simple using matplotlib.
:param ax: Matplotlib axes reference
:param linewidth: Plot linewidth
:param alpha: Alpha transparency value (0-1)
:param color: Plot color
:param fill: Fill object
"""
px, py = [p.x for p in self._points], [p.y for p in self._points]
px.append(px[0])
py.append(py[0])
if fill:
ax.fill(px, py, color=color, lw=None, alpha=alpha)
else:
ax.plot(px, py, '-', color=color, linewidth=linewidth, alpha=alpha)
class BasePolyObj(BasePolyComponent, abc.ABC):
"""
FP base polygon object.
"""
__basename: str
__color: str
_category: int
_category_name: str
def __init__(
self,
ctx: Dict[int, 'BasePolyObj'],
basename: str,
obj_id: int,
floor: 'Floor',
x: List[float],
y: List[float],
color: str,
category: int,
category_name: str,
) -> None:
"""
Constructor.
:param ctx: Polygon object context
:param basename: Basename
:param obj_id: ID of the object
:param floor: Floor object
:param x: List of coordinates within x-axis
:param y: List of coordinates within y-axis
:param color: Object color
:param category: Object category
:param category_name: Object category name
"""
BasePolyComponent.__init__(self, obj_id, x, y, floor)
ctx[obj_id] = self
self.__basename = basename
self.__color = color
self._category_name = category_name
self._category = category
@property
def category(self) -> int:
return self._category
@property
def category_name(self) -> str:
return self._category_name
# noinspection PyUnusedLocal
def plot_plotly(
self,
fig: 'go.Figure',
dx: NumberType = 0,
dy: NumberType = 0,
postname: str = '',
opacity: NumberType = 0.2,
color: str = '',
name: str = '',
**kwargs
) -> None:
if name != '':
name = f'{name} '
super().plot_plotly(
fig, dx, dy, opacity, self.__color if color == '' else color,
'' if self.category_name == '' else f'[{self.category}] ' + f'{self.__basename} {name}ID{self.id}{postname}',
**kwargs)
def plot_matplotlib(
self,
ax: 'plt.Axes',
linewidth: NumberType = 2.0,
alpha: NumberType = 1.0,
color: str = '',
fill: bool = True
) -> None:
super().plot_matplotlib(ax, linewidth, alpha, self.__color if color == '' else color, fill)