model.depot =========== .. py:module:: model.depot Classes ------- .. autoapisummary:: model.depot.Depot model.depot.Plan model.depot.AreaType model.depot.Area model.depot.Process model.depot.AssocPlanProcess model.depot.AssocAreaProcess Functions --------- .. autoapisummary:: model.depot.validate_duration_and_power Module Contents --------------- .. py:class:: Depot Bases: :py:obj:`eflips.model.Base` The Depot represents a palce where vehicles not engaged in a schedule are parked, processed and dispatched. .. py:attribute:: __tablename__ :value: 'Depot' .. py:attribute:: id :type: sqlalchemy.orm.Mapped[int] The unique idenfitier of the depot. Auto-incremented. .. py:attribute:: scenario_id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the scenario. Foreign key to :attr:`Scenario.id`. .. py:attribute:: scenario :type: sqlalchemy.orm.Mapped[eflips.model.Scenario] The scenario this depot belongs to. .. py:attribute:: name :type: sqlalchemy.orm.Mapped[str] A name for the depot. .. py:attribute:: name_short :type: sqlalchemy.orm.Mapped[str] An optional short name for the depot. .. py:attribute:: bounding_box The bounding box of the depot as a PostGIS Polygon. Uses WGS84 coordinate system (SRID 4326). .. py:attribute:: station_id :type: sqlalchemy.orm.Mapped[int] The station where the depot is located. This depot handles :attr:`Rotation` starting and ending at this station. Foreign key to :attr:`Station.id`. .. py:attribute:: station :type: sqlalchemy.orm.Mapped[eflips.model.Station] The station where the depot is located. This depot handles :attr:`Rotation` starting and ending at this station. .. py:attribute:: default_plan_id :type: sqlalchemy.orm.Mapped[int] The default plan of this depot. Foreign key to :attr:`Plan.id`. .. py:attribute:: default_plan :type: sqlalchemy.orm.Mapped[Plan] .. py:attribute:: areas :type: sqlalchemy.orm.Mapped[List[Area]] The areas of this depot. .. py:attribute:: __table_args__ .. py:method:: __repr__() .. py:property:: local_projection :type: Optional[Tuple[pyproj.CRS, pyproj.Transformer, pyproj.Transformer]] Creates a local metric coordinate system centered at the centroid of the depot's bounding box. Returns: A tuple containing: - The pyproj CRS object for the local projection - Transformer from WGS84 to local - Transformer from local to WGS84 Returns None if no bounding box is defined. .. py:method:: global_to_local(polygon) Converts a shapely polygon from the global WGS84 coordinate system to the depot's local coordinate system. Args: polygon: A shapely polygon in WGS84 coordinates (EPSG:4326) Returns: A shapely polygon with coordinates in the local metric system, or None if no bounding box is defined. .. py:method:: local_to_global(polygon) Converts a shapely polygon from the depot's local coordinate system to the global WGS84 coordinate system. Args: polygon: A shapely polygon in the depot's local metric coordinates Returns: A shapely polygon with coordinates in WGS84 (EPSG:4326), or None if no bounding box is defined. .. py:property:: bounding_box_global :type: Optional[shapely.geometry.Polygon] Returns the bounding box of the area as a shapely Polygon. Returns: A shapely Polygon representing the bounding box in WGS84 coordinates, or None if no bounding box is defined. .. py:property:: bounding_box_local :type: Optional[shapely.geometry.Polygon] Returns the bounding box of the area in the depot's local coordinate system. Returns: A shapely Polygon with coordinates in the local metric system, or None if no bounding box is defined. .. py:method:: validate_bounding_box() Validates that the depot's bounding box is valid. Returns: True if the bounding box is valid or None, False otherwise. .. py:method:: generate_svg(width = 800, height = 800, margin = 20, draw_labels = True, draw_area_info = True, draw_parking_spaces = True) Generates an SVG visualization of the depot, including areas and parking spaces. **NOTE: This method requires the `svgwrite` library to be installed.** Args: width: The width of the SVG in pixels height: The height of the SVG in pixels margin: Margin around the depot in pixels draw_labels: Whether to draw labels for areas and parking spaces draw_area_info: Whether to draw information about each area draw_parking_spaces: Whether to draw individual parking spaces Returns: The SVG as a string :raise ImportError: If svgwrite is not installed .. py:class:: Plan Bases: :py:obj:`eflips.model.Base` The Plan represents a certain order of processes, which are executed on vehicles in a depot. .. py:attribute:: __tablename__ :value: 'Plan' .. py:attribute:: id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the plan. Auto-incremented. .. py:attribute:: scenario_id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the scenario. Foreign key to :attr:`Scenario.id`. .. py:attribute:: scenario :type: sqlalchemy.orm.Mapped[eflips.model.Scenario] The scenario this plan belongs to. .. py:attribute:: name :type: sqlalchemy.orm.Mapped[str] A name for the plan. .. py:attribute:: depot :type: sqlalchemy.orm.Mapped[Depot] .. py:attribute:: asssoc_plan_process :type: sqlalchemy.orm.Mapped[List[AssocPlanProcess]] The association between this plan and its processes. Here, the ordinal of the process can be set. .. py:attribute:: processes :type: sqlalchemy.orm.Mapped[List[Process]] .. py:method:: __repr__() .. py:class:: AreaType(*args, **kwds) Bases: :py:obj:`enum.Enum` This class represents the type of area in eFLIPS-Depot .. py:attribute:: DIRECT_ONESIDE A direct area where vehicles drive in form one side only. .. py:attribute:: DIRECT_TWOSIDE A direct area where vehicles drive in form both sides. Also called a "herringbone" configuration. .. py:attribute:: LINE A line area where vehicles are parked in a line. There might be one or more rows in the area. .. py:class:: Area Bases: :py:obj:`eflips.model.Base` An Area represents a certain area in a depot, where at least one process is available. All slots in the area may be directly accessible, or the area may be a line area where vehicles are parked in a line. In such an area, only the first vehicle in the line is directly accessible, the second vehicle can only be removed after the first vehicle has been removed, and so on. However vehicles can only been added to the end of the line. So if it's filled up, *all* vehicles have to be removed to add a new one. If there's one slot left and one vehicle is removed, there's still only one slot left, not two. .. py:attribute:: __tablename__ :value: 'Area' .. py:attribute:: _table_args_list :type: List[sqlalchemy.Constraint] :value: [] .. py:attribute:: id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the area. Auto-incremented. .. py:attribute:: scenario_id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the scenario. Foreign key to :attr:`Scenario.id`. .. py:attribute:: scenario :type: sqlalchemy.orm.Mapped[eflips.model.Scenario] The scenario this area belongs to. .. py:attribute:: depot_id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the depot. Foreign key to :attr:`Depot.id`. .. py:attribute:: depot :type: sqlalchemy.orm.Mapped[Depot] .. py:attribute:: vehicle_type_id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the vehicle type. Foreign key to :attr:`VehicleType.id`. If set, only vehicles of this type can be parked in this area. If null, all vehicle types can be parked. .. py:attribute:: vehicle_type :type: sqlalchemy.orm.Mapped[eflips.model.VehicleType] The vehicle type which can park in this area. .. py:attribute:: area_type The type of the area. See :class:`depot.AreaType`. .. py:attribute:: name :type: sqlalchemy.orm.Mapped[str] An optional name for the area. If set, it must be unique within the scenario. .. py:attribute:: name_short :type: sqlalchemy.orm.Mapped[str] An optional short name for the area. .. py:attribute:: capacity :type: sqlalchemy.orm.Mapped[int] The capacity of the area. Must be set. .. py:attribute:: row_count :type: sqlalchemy.orm.Mapped[int] Number of side-by-side rows in a LINE area. Must be set for areas of type LINE. .. py:attribute:: charging_point_type_id :type: sqlalchemy.orm.Mapped[int] If this is a charging area, this is the type of charging point. Used for TCO/LCA calculations. .. py:attribute:: charging_point_type :type: sqlalchemy.orm.Mapped[eflips.model.ChargingPointType] The type of charging point in this area. .. py:attribute:: bounding_box The bounding box of the area as a PostGIS Polygon. Uses WGS84 coordinate system (SRID 4326). .. py:attribute:: capacity_constraint .. py:attribute:: rectangular_constraint .. py:attribute:: processes :type: sqlalchemy.orm.Mapped[List[Process]] .. py:attribute:: events :type: sqlalchemy.orm.Mapped[List[eflips.model.Event]] The events that happened in this area. .. py:attribute:: assoc_area_processes :type: sqlalchemy.orm.Mapped[List[AssocAreaProcess]] The association between this area and its processes. .. py:attribute:: __table_args__ :value: () .. py:attribute:: spacing :value: 0.5 The spacing between vehicles when parked, in meters. .. py:attribute:: direct_area_angle The angle of the direct area, in radians. .. py:property:: length :type: None | float Calculates the length of the area. For a line area, this is the vehicles behind each other in a row. for a direct area, this is the length of the side that needs to have road access. .. py:property:: width :type: None | float Calculates the width of the area. For a line area, this is the width of the side that needs to have road access. .. py:method:: _coordinates() Gets the x, and y coordinates of the area's first point in the local coordinate system. Also returns the angle of the area in the local coordinate system. :return: A tuple containing the x, y coordinates and the angle of the area in the local coordinate system. .. py:property:: x :type: Optional[float] Represents the X (East (+) - West (-)) coordinate of the area in the depot's local coordinate system. This is the coordinate of the first corner of the area in the local coordinate system. :return: A float representing the X coordinate of the area in the local coordinate system. .. py:property:: y :type: Optional[float] Represents the Y (North (+) - South (-)) coordinate of the area in the depot's local coordinate system. This is the coordinate of the bottom left corner of the area in the local coordinate system. :return: A float representing the Y coordinate of the area in the local coordinate system. .. py:property:: alpha :type: Optional[float] Represents the angle of the area in the depot's local coordinate system. This is the angle of the bottom left edge of the area in the local coordinate system. :return: A float representing the angle of the area in the local coordinate system, in radians. .. py:method:: __repr__() .. py:method:: set_bounding_box_from_local(origin, angle) Sets the bounding box of the area based on a rectangle defined by: - An origin point in the local coordinate system - An angle in radians for the orientation of the rectangle - The width and length properties of the area Args: origin: A shapely Point in the local coordinate system representing the origin corner angle: The angle in radians for the orientation of the rectangle Returns: None Raises: ValueError: If width or length properties return None, or if the depot has no bounding box .. py:property:: bounding_box_global :type: Optional[shapely.geometry.Polygon] Returns the bounding box of the area as a shapely Polygon. Returns: A shapely Polygon representing the bounding box in WGS84 coordinates, or None if no bounding box is defined. .. py:property:: bounding_box_local :type: Optional[shapely.geometry.Polygon] Returns the bounding box of the area in the depot's local coordinate system. Returns: A shapely Polygon with coordinates in the local metric system, or None if no bounding box is defined. .. py:method:: generate_parking_spaces() Generates polygons representing the individual parking spaces within the area. Returns: A list of shapely Polygons representing each parking space in local coordinates, or None if the area has no bounding box or vehicle type defined. .. py:method:: validate_bounding_box() Validates that the area's bounding box is valid: - Must be rectangular (4 vertices forming right angles) - Must be within the depot's bounding box - Must have positive area Returns: True if the bounding box meets all constraints or is None, False otherwise. .. py:class:: Process Bases: :py:obj:`eflips.model.Base` A Process represents a certain action that can be executed on a vehicle. .. py:attribute:: __tablename__ :value: 'Process' .. py:attribute:: _table_args_list :type: List[sqlalchemy.Constraint] :value: [] .. py:attribute:: id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the process. Auto-incremented. .. py:attribute:: scenario_id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the scenario. Foreign key to :attr:`Scenario.id`. .. py:attribute:: scenario :type: sqlalchemy.orm.Mapped[eflips.model.Scenario] The scenario. .. py:attribute:: name :type: sqlalchemy.orm.Mapped[str] A name for the process. If set, it must be unique within the scenario. .. py:attribute:: name_short :type: sqlalchemy.orm.Mapped[str] An optional short name for the process. .. py:attribute:: dispatchable :type: sqlalchemy.orm.Mapped[bool] Whether the bus is ready for departure. .. py:attribute:: duration :type: sqlalchemy.orm.Mapped[datetime.timedelta] The duration of this process in seconds. .. py:attribute:: electric_power :type: sqlalchemy.orm.Mapped[float] The peak electric power required by this process in kW. Actual power consumption might be lower. It implies the charging equipment to be provided. .. py:attribute:: availability :type: sqlalchemy.orm.Mapped[List[Tuple[datetime.datetime, datetime.datetime]]] Temporal availability of this process represented by a list of start and end times. Null means this process is always available. .. py:attribute:: plans :type: sqlalchemy.orm.Mapped[List[Plan]] .. py:attribute:: areas :type: sqlalchemy.orm.Mapped[List[Area]] .. py:attribute:: assoc_area_processes :type: sqlalchemy.orm.Mapped[List[AssocAreaProcess]] .. py:attribute:: __table_args__ :value: () .. py:method:: __repr__() .. py:function:: validate_duration_and_power(_, __, target) Validates the duration and electric power of a Process before inserting or updating it in the database. :param _: Unused parameter, typically the mapper or class being listened to. :param __: Unused parameter, typically the instance being inserted or updated. :param target: The Process instance being validated. :return: None. Raises ValueError if validation fails. .. py:class:: AssocPlanProcess Bases: :py:obj:`eflips.model.Base` The association table for the many-to-many relationship between :class:`Plan` and :class:`Process`. .. py:attribute:: __tablename__ :value: 'AssocPlanProcess' .. py:attribute:: id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the association. Auto-incremented. Needed for django. .. py:attribute:: scenario_id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the scenario. Foreign key to :attr:`Scenario.id`. .. py:attribute:: scenario :type: sqlalchemy.orm.Mapped[eflips.model.Scenario] The scenario. .. py:attribute:: plan_id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the plan. Foreign key to :attr:`Plan.id`. .. py:attribute:: plan :type: sqlalchemy.orm.Mapped[Plan] The plan. .. py:attribute:: process_id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the process. Foreign key to :attr:`Process.id`. .. py:attribute:: process :type: sqlalchemy.orm.Mapped[Process] The process. .. py:attribute:: ordinal :type: sqlalchemy.orm.Mapped[int] The ordinal of the process in the plan. .. py:method:: __repr__() .. py:class:: AssocAreaProcess Bases: :py:obj:`eflips.model.Base` The association table for the many-to-many relationship between :class:`Area` and :class:`Process`. .. py:attribute:: __tablename__ :value: 'AssocAreaProcess' .. py:attribute:: id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the association. Auto-incremented. Needed for django. .. py:attribute:: area_id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the area. Foreign key to :attr:`Area.id`. .. py:attribute:: area :type: sqlalchemy.orm.Mapped[Area] The area. .. py:attribute:: process_id :type: sqlalchemy.orm.Mapped[int] The unique identifier of the process. Foreign key to :attr:`Process.id`. .. py:attribute:: process :type: sqlalchemy.orm.Mapped[Process] The process. .. py:method:: __repr__()