Power System Platform  2026w34a-beta
Loading...
Searching...
No Matches
Line Class Reference

Power line element. More...

#include <Line.h>

Inheritance diagram for Line:
Collaboration diagram for Line:

Public Member Functions

 Line (wxString name)
 
virtual bool Contains (wxPoint2DDouble position) const
 Checks if the element contains a position.
 
virtual void DrawDC (GUIColour *guiColour, wxPoint2DDouble translation, double scale, wxGraphicsContext *gc) const
 Draw the element using GDI+.
 
virtual void DrawDC (GUIColour *guiColour, wxPoint2DDouble translation, double scale, wxDC &dc) const
 Draw the element using wxDC.
 
virtual void Move (wxPoint2DDouble position)
 Move the element other position.
 
virtual void AlignToGrid (double gridSize=20.0) override
 
virtual void StartMove (wxPoint2DDouble position)
 Update the element attributes related to the movement.
 
virtual void MoveNode (Element *parent, wxPoint2DDouble position)
 Move a node. StartMove(wxPoint2DDouble position) before start moving.
 
virtual bool SetNodeParent (Element *parent)
 Set a perent to the node. If all conditions are met, a new parent are added to the element and the points related to the nodes will be calculated.
 
virtual wxCursor GetBestPickboxCursor () const
 Get the best cursor to shown to the user when the mouse is above a pickbox.
 
virtual Element * GetCopy ()
 Get a the element copy.
 
virtual bool AddParent (Element *parent, wxPoint2DDouble position, bool isOpening=false)
 Add a parent to the element. This method must be used on power elements that connect to a bus, so the parent must be a bus. The element basic points are calculated in this method, so apply this when the element is being inserted.
 
virtual bool Intersects (wxRect2DDouble rect) const
 Check if the element's rect intersects other rect.
 
virtual void MovePickbox (wxPoint2DDouble position)
 Move the pickbox.
 
virtual bool PickboxContains (wxPoint2DDouble position)
 Check if a pickbox contains a point. If contains the attributes related to pickbox movement will be calculated.
 
virtual void AddPoint (wxPoint2DDouble point)
 Add point to the list of points that connect the element to the bus.
 
virtual bool GetContextMenu (wxMenu &menu)
 Get the element contex menu.
 
virtual wxString GetTipText () const
 Get the tip text.
 
virtual void RemoveNode (wxPoint2DDouble point)
 
virtual void AddNode (wxPoint2DDouble point)
 
virtual void RotateNode (Element *parent, bool clockwise=true)
 Rotate a node.
 
virtual void CalculateBoundaries (wxPoint2DDouble &leftUp, wxPoint2DDouble &rightBottom) const
 Calculate the element boundaries.
 
virtual void SetPowerFlowDirection (PowerFlowDirection pfDirection)
 Set the direction of the power flow.
 
virtual bool ShowForm (wxWindow *parent, Element *element, wxWindow *workspace=nullptr)
 Show element data form.
 
virtual LineElectricalData GetElectricalData () const
 
virtual LineElectricalData & GetElectricalDataRef ()
 
virtual LineElectricalData GetPUElectricalData (double systemBasePower) const
 
virtual void SetElectricalData (LineElectricalData electricalData)
 
virtual void SetNominalVoltage (std::vector< double > nominalVoltage, std::vector< ElectricalUnit > nominalVoltageUnit)
 Set nominal voltage of the element.
 
virtual void SetPointList (std::vector< wxPoint2DDouble > pointList)
 Set the list of points that connect the element to the bus.
 
virtual rapidxml::xml_node * SaveElement (rapidxml::xml_document<> &doc, rapidxml::xml_node<> *elementListNode)
 
virtual bool OpenElement (rapidxml::xml_node<> *elementNode, std::vector< Element * > parentList)
 
- Public Member Functions inherited from Branch
virtual bool NodeContains (wxPoint2DDouble position)
 Check if a node contains a point. If contains, set the attributes related to node movement.
 
virtual void RemoveParent (Element *parent)
 Remove a parent.
 
virtual void UpdateNodes ()
 Update the nodes according to the parents. If a parent is removed, use this method.
 
virtual void UpdateSwitchesPosition ()
 
virtual void UpdateSwitches ()
 Update the switch position.
 
- Public Member Functions inherited from PowerElement
 PowerElement ()
 Constructor.
 
virtual ~PowerElement ()
 Destructor.
 
virtual wxPoint2DDouble GetSwitchPoint (Element *parent, wxPoint2DDouble parentPoint, wxPoint2DDouble secondPoint) const
 Get the correct switch position.
 
virtual bool SwitchesContains (wxPoint2DDouble position) const
 Check if switch contains position.
 
virtual void DrawDCSwitches (GUIColour *guiColour, wxGraphicsContext *gc) const
 Draw switch.
 
virtual void DrawDCSwitches (GUIColour *guiColour, wxDC &dc) const
 
virtual void CalculatePowerFlowPts (std::vector< wxPoint2DDouble > edges)
 Calculate the points of the power flow arrows.
 
virtual void DrawDCPowerFlowPts (GUIColour *guiColour, wxGraphicsContext *gc) const
 Draw power flow arrows.
 
virtual void DrawDCPowerFlowPts (GUIColour *guiColour, wxDC &dc) const
 
virtual void SetSwitchingData (SwitchingData data)
 Set the switching data of the element.
 
virtual SwitchingData GetSwitchingData ()
 Returns the switching data of the element.
 
virtual PowerFlowDirection GetPowerFlowDirection () const
 Return the direction of the power flow.
 
virtual bool GetPlotData (ElementPlotData &plotData, PlotStudy study=PlotStudy::STABILITY)
 Fill the plot data.
 
virtual bool HaveDynamicEvent () const
 Check if the power element have dynamic event.
 
virtual void SetDynamicEvent (bool dynEvent=true)
 Set if the power element have dynamic event.
 
virtual double GetValueFromUnit (double value, ElectricalUnit valueUnit) const
 
virtual void SaveCADProperties (rapidxml::xml_document<> &doc, rapidxml::xml_node<> *elementNode)
 
virtual void SaveSwitchingData (rapidxml::xml_document<> &doc, rapidxml::xml_node<> *electricalNode)
 
virtual bool OpenCADProperties (rapidxml::xml_node<> *elementNode, std::vector< Element * > parentList)
 
virtual bool OpenSwitchingData (rapidxml::xml_node<> *electricalNode)
 
- Public Member Functions inherited from Element
 Element ()
 Constructor.
 
virtual ~Element ()
 Destructor.
 
void SetDragging (bool dragging=true)
 Set if the element are being dragged.
 
void SetHeight (double height)
 Set element height.
 
void SetPosition (const wxPoint2DDouble position)
 Set the element position and update the rectangle.
 
void SetSelected (bool selected=true)
 Set element selection.
 
void SetWidth (double width)
 Set element width.
 
void SetAngle (double angle)
 Set element angle.
 
void ShowPickbox (bool showPickbox=true)
 Set if the pickbox is shown.
 
void SetBorderSize (double borderSize)
 Set the size of the border (shown in selected elements).
 
bool SetOnline (bool online=true)
 Set if the element is online or offline.
 
ElementType GetElementType ()
 
wxRect2DDouble GetRect () const
 Get the element rectangle.
 
wxPoint2DDouble GetPosition () const
 Get the element position.
 
bool IsDragging () const
 Checks if the element is being dragged.
 
double GetHeight () const
 Get the element height.
 
bool IsSelected () const
 Checks if the element is selected.
 
double GetWidth () const
 Get the element width.
 
double GetAngle () const
 Get the element angle.
 
double GetRotationAngle () const
 Get the angle of rotation.
 
bool IsPickboxShown () const
 Checks if the pickbox is shown.
 
bool IsOnline () const
 Checks if the element is online or offline.
 
virtual std::vector< wxPoint2DDouble > GetPointList () const
 Get the list of points that connect the element to bus.
 
virtual std::vector< wxPoint2DDouble > & GetPointListRef ()
 
virtual void AddParent (Element *parent)
 Add a parent to the element.
 
virtual void SetID (int id)
 Set the element ID.
 
virtual int GetID () const
 Get the element ID.
 
virtual void AddChild (Element *child)
 Add a child to the child list.
 
virtual void RemoveChild (Element *child)
 Remove a child from the list.
 
virtual void ReplaceChild (Element *oldChild, Element *newChild)
 Replace a child from the list.
 
virtual void Rotate (bool clockwise=true)
 Rotate the element.
 
void SetParent (Element *parent, int num)
 
void SetChild (Element *child, int num)
 
virtual void ReplaceParent (Element *oldParent, Element *newParent)
 Replace a parent.
 
virtual void ResetPickboxes ()
 Remove the pickboxes.
 
virtual void ResetNodes ()
 Remove the active nodes.
 
virtual wxPoint2DDouble WorldToScreen (wxPoint2DDouble translation, double scale, double offsetX=0.0, double offsetY=0.0) const
 Convert the element position to screen position.
 
virtual wxPoint2DDouble WorldToScreen (wxPoint2DDouble position, wxPoint2DDouble translation, double scale, double offsetX=0.0, double offsetY=0.0) const
 Convert a generic position to screen position.
 
virtual bool RotatedRectanglesIntersects (wxRect2DDouble rect1, wxRect2DDouble rect2, double angle1, double angle2) const
 Check if two roteted rectangles intersect.
 
virtual void DrawDCRectangle (wxPoint2DDouble position, double width, double height, double angle, wxDC &dc) const
 Draw a circle.
 
virtual void DrawDCRoundedRectRotated (wxDC &dc, const wxPoint2DDouble &center, double width, double height, double radius, double angleDeg, int arcSegments=8) const
 
virtual void DrawDCCircle (wxPoint2DDouble position, double radius, int numSegments, wxGraphicsContext *gc) const
 Draw a circle using device context.
 
virtual void DrawDCCircle (wxPoint2DDouble position, double radius, wxDC &dc) const
 
virtual void DrawDCArc (wxPoint2DDouble position, double radius, double initAngle, double finalAngle, int numSegments, wxGraphicsContext *gc) const
 
virtual void DrawDCArc (wxPoint2DDouble position, double radius, double initAngle, double finalAngle, wxDC &dc) const
 
virtual void DrawDCTriangle (std::vector< wxPoint2DDouble > points, wxGraphicsContext *gc) const
 Draw rectangle.
 
virtual void DrawDCTriangle (std::vector< wxPoint > points, wxDC &dc) const
 
virtual void DrawStabilityEventGC (wxGraphicsContext *gc, wxPoint2DDouble translation, double scale, GUIColour *guiColour, bool rotateAnchor=false, wxPoint2DDouble iconPosition=wxPoint2DDouble(-1, -1)) const
 
virtual void DrawDCPickbox (wxPoint2DDouble position, wxGraphicsContext *gc) const
 Draw a point.
 
virtual wxPoint2DDouble RotateAtPosition (wxPoint2DDouble pointToRotate, double angle, bool degrees=true) const
 Rotate a point as element position being the origin.
 
virtual wxPoint2DDouble RotateLocal (wxPoint2DDouble local, double angleDeg) const
 
virtual wxPoint RotateAround (const wxPoint2DDouble &p, const wxPoint2DDouble &center, double angleDeg) const
 
virtual std::vector< Element * > GetParentList () const
 Get the parent list.
 
virtual std::vector< Element * > GetChildList () const
 Get the Child list.
 
virtual wxPoint2DDouble GetMoveStartPosition () const
 
virtual wxPoint2DDouble GetMovePosition () const
 
virtual void GeneralMenuItens (wxMenu &menu)
 Insert general itens to context menu.
 
virtual double PointToLineDistance (wxPoint2DDouble point, int *segmentNumber=nullptr) const
 Calculate the distance between a line (formed by point list) and a point.
 
bool IsInserted () const
 Check if the element is properly inserted in the workspace.
 
void SetInserted (bool inserted=true)
 Set if the element is properly inserted in the workspace.
 
virtual bool OpenElement (rapidxml::xml_node<> *elementNode)
 
void SaveCADProperties (rapidxml::xml_document<> &doc, rapidxml::xml_node<> *elementNode)
 
bool OpenCADProperties (rapidxml::xml_node<> *elementNode)
 

Protected Member Functions

void UpdatePowerFlowArrowsPosition ()
 

Protected Attributes

LineElectricalData m_electricalData
 
- Protected Attributes inherited from PowerElement
SwitchingData m_swData
 
std::vector< std::vector< wxPoint2DDouble > > m_powerFlowArrow
 
PowerFlowDirection m_pfDirection = PowerFlowDirection::PF_NONE
 
wxColour m_busColour
 
wxColour m_onlineElementColour
 
wxColour m_offlineElementColour
 
wxColour m_closedSwitchColour
 
wxColour m_openedSwitchColour
 
wxColour m_powerFlowArrowColour
 
wxColour m_dynamicEventColour
 
bool m_dynEvent = false
 
- Protected Attributes inherited from Element
ElementType m_elementType = ElementType::TYPE_NONE
 
int m_elementID = 0
 
std::vector< Element * > m_parentList
 
std::vector< Element * > m_childList
 
wxRect2DDouble m_rect
 
wxPoint2DDouble m_position
 
double m_width = 0.0
 
double m_height = 0.0
 
double m_angle = 0.0
 
double m_borderSize = 2.0
 
double m_rotationAngle = 45.0
 
double m_switchSize = 10.0
 
std::vector< wxRect2DDouble > m_switchRect
 
bool m_selected = false
 
bool m_dragging = false
 
bool m_showPickbox = false
 
bool m_inserted = false
 
int m_activePickboxID = ID_PB_NONE
 
int m_activeNodeID = 0
 
std::vector< wxPoint2DDouble > m_pointList
 
std::vector< wxPoint2DDouble > m_movePts
 
wxPoint2DDouble m_moveStartPt
 
wxPoint2DDouble m_movePos
 
bool m_online = true
 

Additional Inherited Members

- Static Public Member Functions inherited from Element
static bool DoubleFromString (wxWindow *parent, wxString strValue, double &value, wxString errorMsg)
 Get a double value from a string. Show a error message if the conversion fail.
 
static bool IntFromString (wxWindow *parent, wxString strValue, int &value, wxString errorMsg)
 Convert a string to int. Show a error message if the conversion fail.
 
static wxString StringFromDouble (double value, int minDecimal=1, int maxDecimals=13)
 Convert a double value to string.
 

Detailed Description

Power line element.

Author
Thales Lima Oliveira thale.nosp@m.s@uf.nosp@m.u.br
Date
06/10/2017

Definition at line 63 of file Line.h.

Constructor & Destructor Documentation

◆ Line() [1/2]

Line::Line ( )

Definition at line 21 of file Line.cpp.

21 : Branch()
22{
23 m_elementType = TYPE_LINE;
24 for (int i = 0; i < 2; i++) {
25 for (int j = 0; j < 3; j++) { m_electricalData.faultCurrent[i][j] = std::complex<double>(0.0, 0.0); }
26 }
27}
Abstract class for branch power elements.
Definition Branch.h:32

◆ Line() [2/2]

Line::Line ( wxString  name)

Definition at line 29 of file Line.cpp.

29 : Branch()
30{
31 m_elementType = TYPE_LINE;
32 for (int i = 0; i < 2; i++) {
33 for (int j = 0; j < 3; j++) { m_electricalData.faultCurrent[i][j] = std::complex<double>(0.0, 0.0); }
34 }
35 m_electricalData.name = name;
36}

◆ ~Line()

Line::~Line ( )

Definition at line 37 of file Line.cpp.

37{}

Member Function Documentation

◆ AddNode()

void Line::AddNode ( wxPoint2DDouble  point)
virtual

Definition at line 522 of file Line.cpp.

523{
524 int segmentNumber = 0;
525 PointToLineDistance(point, &segmentNumber);
526 if (segmentNumber > 0 && segmentNumber < (int)m_pointList.size() - 2) {
527 m_pointList.insert(m_pointList.begin() + segmentNumber + 1, point);
528 }
529 UpdateSwitchesPosition();
530 UpdatePowerFlowArrowsPosition();
531}
virtual double PointToLineDistance(wxPoint2DDouble point, int *segmentNumber=nullptr) const
Calculate the distance between a line (formed by point list) and a point.
Definition Element.cpp:616

◆ AddParent()

bool Line::AddParent ( Element *  parent,
wxPoint2DDouble  position,
bool  isOpening = false 
)
virtual

Add a parent to the element. This method must be used on power elements that connect to a bus, so the parent must be a bus. The element basic points are calculated in this method, so apply this when the element is being inserted.

Parameters
parentElement parent.
positionNode position in the parent.

Reimplemented from Element.

Definition at line 306 of file Line.cpp.

307{
308 if (parent) {
309 // First bus.
310 if (m_parentList.size() == 0) {
311 m_position = position;
312 m_parentList.push_back(parent);
313 parent->AddChild(this);
314 wxPoint2DDouble parentPt =
315 parent->RotateAtPosition(position, -parent->GetAngle()); // Rotate click to horizontal position.
316 parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
317 parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle()); // Rotate back.
318 m_pointList.push_back(parentPt); // First point
319 m_pointList.push_back(GetSwitchPoint(parent, parentPt, m_position));
320
321 wxRect2DDouble genRect(0, 0, 0, 0);
322 m_switchRect.push_back(genRect);
324
325 Bus* parentBus = static_cast<Bus*>(parent);
326 m_electricalData.nominalVoltage = parentBus->GetElectricalData().nominalVoltage;
327 m_electricalData.nominalVoltageUnit = parentBus->GetElectricalData().nominalVoltageUnit;
328
329 return false;
330 }
331 // Second bus.
332 else if (parent != m_parentList[0]) {
333 Bus* parentBus = static_cast<Bus*>(parent);
334 if (m_electricalData.nominalVoltage != parentBus->GetElectricalData().nominalVoltage ||
335 m_electricalData.nominalVoltageUnit != parentBus->GetElectricalData().nominalVoltageUnit) {
336 wxMessageDialog msgDialog(nullptr,
337 _("Unable to connect two buses with different nominal voltages.\n"
338 "Use a transformer or edit the bus properties."),
339 _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
340 msgDialog.ShowModal();
341 return false;
342 }
343
344 m_parentList.push_back(parent);
345 parent->AddChild(this);
346 wxPoint2DDouble parentPt =
347 parent->RotateAtPosition(position, -parent->GetAngle()); // Rotate click to horizontal position.
348 parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
349 parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle()); // Rotate back.
350
351 // Set first switch point.
352 wxPoint2DDouble secondPoint = parentPt;
353 if (m_pointList.size() > 2) { secondPoint = m_pointList[2]; }
354 m_pointList[1] = GetSwitchPoint(m_parentList[0], m_pointList[0], secondPoint);
355
356 // Set the second switch point.
357 m_pointList.push_back(GetSwitchPoint(parent, parentPt, m_pointList[m_pointList.size() - 1]));
358
359 m_pointList.push_back(parentPt); // Last point.
360
361 wxRect2DDouble genRect(0, 0, 0, 0);
362 m_switchRect.push_back(genRect);
364
365 SetInserted();
366 UpdatePowerFlowArrowsPosition();
367 return true;
368 }
369 }
370 return false;
371}
virtual void UpdateSwitches()
Update the switch position.
Definition Branch.cpp:179
Node for power elements. All others power elements are connected through this.
Definition Bus.h:87
wxPoint2DDouble GetPosition() const
Get the element position.
Definition Element.h:189
double GetAngle() const
Get the element angle.
Definition Element.h:214
virtual wxPoint2DDouble RotateAtPosition(wxPoint2DDouble pointToRotate, double angle, bool degrees=true) const
Rotate a point as element position being the origin.
Definition Element.cpp:298
virtual void AddChild(Element *child)
Add a child to the child list.
Definition Element.cpp:581
void SetInserted(bool inserted=true)
Set if the element is properly inserted in the workspace.
Definition Element.h:639
virtual wxPoint2DDouble GetSwitchPoint(Element *parent, wxPoint2DDouble parentPoint, wxPoint2DDouble secondPoint) const
Get the correct switch position.
Here is the call graph for this function:

◆ AddPoint()

void Line::AddPoint ( wxPoint2DDouble  point)
virtual

Add point to the list of points that connect the element to the bus.

Parameters
pointPoint to be added.

Reimplemented from Branch.

Definition at line 403 of file Line.cpp.

404{
405 if (m_parentList.size() != 0) { m_pointList.push_back(point); }
406}

◆ AlignToGrid()

void Line::AlignToGrid ( double  gridSize = 20.0)
overridevirtual

Reimplemented from Element.

Definition at line 260 of file Line.cpp.

261{
262 if (gridSize <= 0.0) gridSize = 20.0;
263 if (m_pointList.empty()) return;
264
265 // Snap intermediate points (indices 2 to size - 3)
266 for (size_t i = 2; i + 2 < m_pointList.size(); ++i) {
267 m_pointList[i].m_x = std::round(m_pointList[i].m_x / gridSize) * gridSize;
268 m_pointList[i].m_y = std::round(m_pointList[i].m_y / gridSize) * gridSize;
269 }
270
271 // Snap bus contact points
272 if (m_parentList.size() > 0 && m_parentList[0]) {
273 Element* bus1 = m_parentList[0];
274 wxPoint2DDouble localPt = bus1->RotateAtPosition(m_pointList[0], -bus1->GetAngle());
275 localPt.m_y = bus1->GetPosition().m_y;
276 localPt.m_x = std::round(localPt.m_x / gridSize) * gridSize;
277 double halfW = bus1->GetWidth() / 2.0;
278 if (localPt.m_x < bus1->GetPosition().m_x - halfW) localPt.m_x = bus1->GetPosition().m_x - halfW;
279 if (localPt.m_x > bus1->GetPosition().m_x + halfW) localPt.m_x = bus1->GetPosition().m_x + halfW;
280 m_pointList[0] = bus1->RotateAtPosition(localPt, bus1->GetAngle());
281 }
282 else if (!m_pointList.empty()) {
283 m_pointList[0].m_x = std::round(m_pointList[0].m_x / gridSize) * gridSize;
284 m_pointList[0].m_y = std::round(m_pointList[0].m_y / gridSize) * gridSize;
285 }
286
287 if (m_parentList.size() > 1 && m_parentList[1] && m_pointList.size() > 1) {
288 Element* bus2 = m_parentList[1];
289 wxPoint2DDouble localPt = bus2->RotateAtPosition(m_pointList.back(), -bus2->GetAngle());
290 localPt.m_y = bus2->GetPosition().m_y;
291 localPt.m_x = std::round(localPt.m_x / gridSize) * gridSize;
292 double halfW = bus2->GetWidth() / 2.0;
293 if (localPt.m_x < bus2->GetPosition().m_x - halfW) localPt.m_x = bus2->GetPosition().m_x - halfW;
294 if (localPt.m_x > bus2->GetPosition().m_x + halfW) localPt.m_x = bus2->GetPosition().m_x + halfW;
295 m_pointList.back() = bus2->RotateAtPosition(localPt, bus2->GetAngle());
296 }
297 else if (m_pointList.size() > 1) {
298 m_pointList.back().m_x = std::round(m_pointList.back().m_x / gridSize) * gridSize;
299 m_pointList.back().m_y = std::round(m_pointList.back().m_y / gridSize) * gridSize;
300 }
301
302 UpdateSwitchesPosition();
303 UpdatePowerFlowArrowsPosition();
304}
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition Element.h:115
double GetWidth() const
Get the element width.
Definition Element.h:209

◆ CalculateBoundaries()

void Line::CalculateBoundaries ( wxPoint2DDouble &  leftUp,
wxPoint2DDouble &  rightBottom 
) const
virtual

Calculate the element boundaries.

Parameters
leftUpTop-left position of the element.
rightBottomBottom-right position of the element.

Reimplemented from Element.

Definition at line 533 of file Line.cpp.

534{
535 if (m_pointList.size() > 0) {
536 // Check points list boundaries.
537 leftUp = m_pointList[0];
538 rightBottom = m_pointList[0];
539 for (int i = 1; i < (int)m_pointList.size(); i++) {
540 if (m_pointList[i].m_x < leftUp.m_x) leftUp.m_x = m_pointList[i].m_x;
541 if (m_pointList[i].m_y < leftUp.m_y) leftUp.m_y = m_pointList[i].m_y;
542 if (m_pointList[i].m_x > rightBottom.m_x) rightBottom.m_x = m_pointList[i].m_x;
543 if (m_pointList[i].m_y > rightBottom.m_y) rightBottom.m_y = m_pointList[i].m_y;
544 }
545 }
546}

◆ Contains()

bool Line::Contains ( wxPoint2DDouble  position) const
virtual

Checks if the element contains a position.

Parameters
positionPosition to be checked.

Reimplemented from Branch.

Definition at line 38 of file Line.cpp.

39{
40 if (PointToLineDistance(position) < 5.0) { return true; }
41 return false;
42}
Here is the call graph for this function:

◆ DrawDC() [1/2]

void Line::DrawDC ( GUIColour *  guiColour,
wxPoint2DDouble  translation,
double  scale,
wxDC &  dc 
) const
virtual

Draw the element using wxDC.

Parameters
guiColourColours of the system defined in properties.
translationTranslation of the system.
scaleScale of the system.
dcDevice context.

Reimplemented from Element.

Definition at line 186 of file Line.cpp.

187{
188
189 wxColour elementColour;
190 if (m_online) {
191 if (m_dynEvent)
192 elementColour = guiColour->eventElement;
193 else
194 elementColour = guiColour->enabled;
195 }
196 else
197 elementColour = guiColour->disable;
198
199 std::vector<wxPoint> pointList;
200 for (auto pt : m_pointList) {
201 pointList.emplace_back(pt.m_x, pt.m_y);
202 }
203
204 // Line selected (Layer 1).
205 if (m_selected) {
206 dc.SetPen(wxPen(guiColour->selection, 2 + m_borderSize * 2.0));
207 dc.SetBrush(*wxTRANSPARENT_BRUSH);
208 if (pointList.size() > 0)
209 dc.DrawLines(pointList.size(), &pointList[0]);
210
211 // Draw nodes selection.
212 dc.SetPen(*wxTRANSPARENT_PEN);
213 dc.SetBrush(wxBrush(guiColour->selection));
214 if (pointList.size() > 0) {
215 DrawDCCircle(pointList[0], 5.0 + m_borderSize / scale, dc);
216 if (m_inserted) { DrawDCCircle(pointList[pointList.size() - 1], 5.0 + m_borderSize / scale, dc); }
217 }
218 }
219
220 // Draw line (Layer 2)
221 dc.SetPen(wxPen(elementColour, 2));
222 dc.SetBrush(*wxTRANSPARENT_BRUSH);
223 if (pointList.size() > 0)
224 dc.DrawLines(pointList.size(), &pointList[0]);
225
226 if (m_inserted) {
227 DrawDCSwitches(guiColour, dc);
228 DrawDCPowerFlowPts(guiColour, dc);
229 }
230
231 // Draw nodes.
232 dc.SetPen(*wxTRANSPARENT_PEN);
233 dc.SetBrush(wxBrush(elementColour));
234 if (pointList.size() > 0) {
235 DrawDCCircle(pointList[0], 5.0, dc);
236 if (m_inserted) { DrawDCCircle(pointList[pointList.size() - 1], 5.0, dc); }
237 }
238}
virtual void DrawDCCircle(wxPoint2DDouble position, double radius, int numSegments, wxGraphicsContext *gc) const
Draw a circle using device context.
Definition Element.cpp:173
virtual void DrawDCPowerFlowPts(GUIColour *guiColour, wxGraphicsContext *gc) const
Draw power flow arrows.
virtual void DrawDCSwitches(GUIColour *guiColour, wxGraphicsContext *gc) const
Draw switch.
Here is the call graph for this function:

◆ DrawDC() [2/2]

void Line::DrawDC ( GUIColour *  guiColour,
wxPoint2DDouble  translation,
double  scale,
wxGraphicsContext *  gc 
) const
virtual

Draw the element using GDI+.

Parameters
guiColourColours of the system defined in properties.
translationTranslation of the system.
scaleScale of the system.
gcGraphics context

Reimplemented from Element.

Definition at line 108 of file Line.cpp.

109{
110 //gc->SetBrush(*wxTRANSPARENT_BRUSH);
111
112 wxGraphicsMatrix identityMatrix = gc->GetTransform();
113 identityMatrix.Set(); // Set to identity
114
115 wxColour elementColour;
116 if (m_online) {
117 //if (m_dynEvent)
118 // elementColour = guiColour->eventElement;
119 //else
120 elementColour = guiColour->enabled;
121 }
122 else
123 elementColour = guiColour->disable;
124
125 std::vector<wxPoint2DDouble> pointList = m_pointList;
126 if (!m_inserted && pointList.size() > 0) {
127 wxPoint2DDouble secondPoint = m_position;
128 if (pointList.size() > 2) { secondPoint = pointList[2]; }
129 pointList[1] = GetSwitchPoint(m_parentList[0], pointList[0], secondPoint);
130 pointList.push_back(m_position);
131 }
132
133 // Line selected (Layer 1).
134 if (m_selected) {
135 gc->SetPen(wxPen(guiColour->selection, 2 + m_borderSize * 2.0));
136 gc->SetBrush(*wxTRANSPARENT_BRUSH);
137 if (pointList.size() > 0)
138 gc->StrokeLines(pointList.size(), &pointList[0]);
139
140 // Draw nodes selection.
141 gc->SetPen(*wxTRANSPARENT_PEN);
142 gc->SetBrush(wxBrush(guiColour->selection));
143 if (pointList.size() > 0) {
144 DrawDCCircle(pointList[0], 5.0 + m_borderSize / scale, 10, gc);
145 if (m_inserted) { DrawDCCircle(pointList[pointList.size() - 1], 5.0 + m_borderSize / scale, 10, gc); }
146 }
147 }
148
149 // Draw line (Layer 2)
150 gc->SetPen(wxPen(elementColour, 2));
151 gc->SetBrush(*wxTRANSPARENT_BRUSH);
152 if (pointList.size() > 0)
153 gc->StrokeLines(pointList.size(), &pointList[0]);
154
155 if (m_inserted) {
156 DrawDCSwitches(guiColour, gc);
157 DrawDCPowerFlowPts(guiColour, gc);
158 }
159
160 // Draw nodes.
161 gc->SetPen(*wxTRANSPARENT_PEN);
162 gc->SetBrush(wxBrush(elementColour));
163 if (pointList.size() > 0) {
164 DrawDCCircle(pointList[0], 5.0, 10, gc);
165 if (m_inserted) { DrawDCCircle(pointList[pointList.size() - 1], 5.0, 10, gc); }
166 }
167
168 // Draw pickboxes (Layer 3).
169 if (m_showPickbox) {
170 gc->PushState();
171 gc->SetTransform(identityMatrix);
172
173 for (int i = 2; i < (int)m_pointList.size() - 2; i++) {
174 DrawDCPickbox(WorldToScreen(m_pointList[i], translation - wxPoint2DDouble(4 / scale, 4 / scale), scale), gc);
175 }
176
177 gc->PopState();
178 }
179
180 if (m_dynEvent && m_pointList.size() >= 3) {
181 auto pt = m_pointList[1] / 2.0 + m_pointList[2] / 2.0;
182 DrawStabilityEventGC(gc, translation, scale, guiColour, false, pt);
183 }
184}
virtual void DrawDCPickbox(wxPoint2DDouble position, wxGraphicsContext *gc) const
Draw a point.
Definition Element.cpp:291
virtual wxPoint2DDouble WorldToScreen(wxPoint2DDouble translation, double scale, double offsetX=0.0, double offsetY=0.0) const
Convert the element position to screen position.
Definition Element.cpp:354
Here is the call graph for this function:

◆ GetBestPickboxCursor()

virtual wxCursor Line::GetBestPickboxCursor ( ) const
inlinevirtual

Get the best cursor to shown to the user when the mouse is above a pickbox.

Returns
Cursor.

Reimplemented from Branch.

Definition at line 78 of file Line.h.

78{ return wxCURSOR_SIZING; }

◆ GetContextMenu()

bool Line::GetContextMenu ( wxMenu &  menu)
virtual

Get the element contex menu.

Parameters
menumenu that will be inserted the element itens.
Returns
True if was possible to build the menu, false otherwise.

Reimplemented from Branch.

Definition at line 458 of file Line.cpp.

459{
460 //wxFileName exeFileName(wxStandardPaths::Get().GetExecutablePath());
461 //wxString exePath = exeFileName.GetPath();
462
463 menu.Append(ID_EDIT_ELEMENT, _("Edit line"));
464
465 wxString busName[2] = { "?", "?" };
466 if (m_parentList.size() == 2) {
467 int i = 0;
468 for (Element* element : m_parentList) {
469 if (element) {
470 Bus* bus = static_cast<Bus*>(element);
471 busName[i] = bus->GetElectricalData().name;
472 }
473 i++;
474 }
475 }
476
477 wxMenu* textMenu = new wxMenu();
478
479 textMenu->Append(ID_TXT_NAME, _("Name"));
480 textMenu->Append(ID_TXT_BRANCH_ACTIVE_POWER_1_2, _("Active power (") + busName[0] + _(" to ") + busName[1] + wxT(")"));
481 textMenu->Append(ID_TXT_BRANCH_ACTIVE_POWER_2_1, _("Active power (") + busName[1] + _(" to ") + busName[0] + wxT(")"));
482 textMenu->Append(ID_TXT_BRANCH_REACTIVE_POWER_1_2, _("Reactive power (") + busName[0] + _(" to ") + busName[1] + wxT(")"));
483 textMenu->Append(ID_TXT_BRANCH_REACTIVE_POWER_2_1, _("Reactive power (") + busName[1] + _(" to ") + busName[0] + wxT(")"));
484 textMenu->Append(ID_TXT_BRANCH_LOSSES, _("Losses"));
485 textMenu->Append(ID_TXT_BRANCH_CURRENT_1_2, _("Current (") + busName[0] + _(" to ") + busName[1] + wxT(")"));
486 textMenu->Append(ID_TXT_BRANCH_CURRENT_2_1, _("Current (") + busName[1] + _(" to ") + busName[0] + wxT(")"));
487 textMenu->Append(ID_TXT_BRANCH_FAULT_CURRENT_1_2, _("Fault current (") + busName[0] + _(" to ") + busName[1] + wxT(")"));
488 textMenu->Append(ID_TXT_BRANCH_FAULT_CURRENT_2_1, _("Fault current (") + busName[1] + _(" to ") + busName[0] + wxT(")"));
489 textMenu->SetClientData(menu.GetClientData());
490 menu.AppendSubMenu(textMenu, _("Add text"));
491
492 if (m_activePickboxID == ID_PB_NONE) {
493 wxMenuItem* addNodeItem = new wxMenuItem(&menu, ID_LINE_ADD_NODE, _("Insert node"));
494 addNodeItem->SetBitmap(wxImage(Paths::GetDataPath() + "/images/menu/addNode16.png"));
495 menu.Append(addNodeItem);
496 }
497 else {
498 wxMenuItem* addNodeItem = new wxMenuItem(&menu, ID_LINE_REMOVE_NODE, _("Remove node"));
499 addNodeItem->SetBitmap(wxImage(Paths::GetDataPath() + "/images/menu/removeNode16.png"));
500 menu.Append(addNodeItem);
501 }
502 wxMenuItem* deleteItem = new wxMenuItem(&menu, ID_DELETE, _("Delete"));
503 deleteItem->SetBitmap(wxImage(Paths::GetDataPath() + "/images/menu/delete16.png"));
504 menu.Append(deleteItem);
505 return true;
506}
@ ID_LINE_REMOVE_NODE
Definition Element.h:79
@ ID_DELETE
Definition Element.h:82
@ ID_EDIT_ELEMENT
Definition Element.h:77
@ ID_LINE_ADD_NODE
Definition Element.h:78
@ ID_PB_NONE
Definition Element.h:63

◆ GetCopy()

Element * Line::GetCopy ( )
virtual

Get a the element copy.

Returns
Copy of the element.

Reimplemented from Element.

Definition at line 696 of file Line.cpp.

697{
698 Line* copy = new Line();
699 *copy = *this;
700 return copy;
701}
Power line element.
Definition Line.h:64

◆ GetElectricalData()

virtual LineElectricalData Line::GetElectricalData ( ) const
inlinevirtual

Definition at line 93 of file Line.h.

93{ return m_electricalData; }

◆ GetElectricalDataRef()

virtual LineElectricalData & Line::GetElectricalDataRef ( )
inlinevirtual

Definition at line 94 of file Line.h.

94{ return m_electricalData; }

◆ GetPUElectricalData()

LineElectricalData Line::GetPUElectricalData ( double  systemBasePower) const
virtual

Definition at line 740 of file Line.cpp.

741{
743
744 data.name = m_electricalData.name;
745
746 data.nominalPower = m_electricalData.nominalPower;
747 data.nominalPowerUnit = m_electricalData.nominalPowerUnit;
748
749 data.nominalVoltage = m_electricalData.nominalVoltage;
750 data.nominalVoltageUnit = m_electricalData.nominalVoltageUnit;
751
752 data.useLinePower = m_electricalData.useLinePower;
753
754 data.lineSize = m_electricalData.lineSize;
755
756 data.resistance = m_electricalData.resistance;
757 data.resistanceUnit = m_electricalData.resistanceUnit;
758
759 data.indReactance = m_electricalData.indReactance;
760 data.indReactanceUnit = m_electricalData.indReactanceUnit;
761
762 data.capSusceptance = m_electricalData.capSusceptance;
763 data.capSusceptanceUnit = m_electricalData.capSusceptanceUnit;
764
765 data.zeroResistance = m_electricalData.zeroResistance;
766 data.zeroIndReactance = m_electricalData.zeroIndReactance;
767 data.zeroCapSusceptance = m_electricalData.zeroCapSusceptance;
768
769 data.powerFlow[0] = m_electricalData.powerFlow[0];
770 data.powerFlow[1] = m_electricalData.powerFlow[1];
771
772 data.faultCurrent[0][0] = m_electricalData.faultCurrent[0][0];
773 data.faultCurrent[0][1] = m_electricalData.faultCurrent[0][1];
774 data.faultCurrent[0][2] = m_electricalData.faultCurrent[0][2];
775 data.faultCurrent[1][0] = m_electricalData.faultCurrent[1][0];
776 data.faultCurrent[1][1] = m_electricalData.faultCurrent[1][1];
777 data.faultCurrent[1][2] = m_electricalData.faultCurrent[1][2];
778
779 data.harmonicOrder = m_electricalData.harmonicOrder;
780 data.harmonicCurrent[0] = m_electricalData.harmonicCurrent[0];
781 data.harmonicCurrent[1] = m_electricalData.harmonicCurrent[1];
782
783
784 double lineBasePower = GetValueFromUnit(data.nominalPower, data.nominalPowerUnit);
785 double baseVoltage = GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
786 double systemBaseImpedance = (baseVoltage * baseVoltage) / systemBasePower;
787 double lineBaseImpedance = (baseVoltage * baseVoltage) / lineBasePower;
788
789 // Resistance
790 double r = data.resistance;
791 if (data.resistanceUnit == ElectricalUnit::UNIT_OHM_km) data.resistance = r * data.lineSize / systemBaseImpedance;
792 else if (data.resistanceUnit == ElectricalUnit::UNIT_PU) {
793 if (data.useLinePower) data.resistance = (r * lineBaseImpedance) / systemBaseImpedance;
794 }
795 else { // Ohm
796 data.resistance = r / systemBaseImpedance;
797 }
798 data.resistanceUnit = ElectricalUnit::UNIT_PU;
799
800 // Inductive reactance
801 double x = data.indReactance;
802 if (data.indReactanceUnit == ElectricalUnit::UNIT_OHM_km) data.indReactance = x * data.lineSize / systemBaseImpedance;
803 else if (data.indReactanceUnit == ElectricalUnit::UNIT_PU) {
804 if (data.useLinePower) data.indReactance = (x * lineBaseImpedance) / systemBaseImpedance;
805 }
806 else { // Ohm
807 data.indReactance = x / systemBaseImpedance;
808 }
809 data.indReactanceUnit = ElectricalUnit::UNIT_PU;
810
811 // Capacitive susceptance
812 double b = data.capSusceptance;
813 if (data.capSusceptanceUnit == ElectricalUnit::UNIT_S_km) data.capSusceptance = b * data.lineSize * systemBaseImpedance;
814 else if (data.capSusceptanceUnit == ElectricalUnit::UNIT_PU) {
815 if (data.useLinePower) data.capSusceptance = (b / lineBaseImpedance) * systemBaseImpedance;
816 }
817 else { // S
818 data.capSusceptance = b * systemBaseImpedance;
819 }
820 data.capSusceptanceUnit = ElectricalUnit::UNIT_PU;
821
822 // Fault
823
824 // Zero seq. resistance
825 double r0 = data.zeroResistance;
826 if (data.useLinePower) data.zeroResistance = (r0 * lineBaseImpedance) / systemBaseImpedance;
827
828 // Zero seq. ind. reactance
829 double x0 = data.zeroIndReactance;
830 if (data.useLinePower) data.zeroIndReactance = (x0 * lineBaseImpedance) / systemBaseImpedance;
831
832 // Zero seq. cap. susceptance
833 double b0 = data.zeroCapSusceptance;
834 if (data.useLinePower) data.zeroCapSusceptance = (b0 / lineBaseImpedance) * systemBaseImpedance;
835
836 if (!m_online) {
837 data.powerFlow[0] = std::complex<double>(0, 0);
838 data.powerFlow[1] = std::complex<double>(0, 0);
839 data.faultCurrent[0][0] = std::complex<double>(0, 0);
840 data.faultCurrent[0][1] = std::complex<double>(0, 0);
841 data.faultCurrent[0][2] = std::complex<double>(0, 0);
842 data.faultCurrent[1][0] = std::complex<double>(0, 0);
843 data.faultCurrent[1][1] = std::complex<double>(0, 0);
844 data.faultCurrent[1][2] = std::complex<double>(0, 0);
845 }
846
847 return data;
848}

◆ GetTipText()

wxString Line::GetTipText ( ) const
virtual

Get the tip text.

Returns
Tip text.

Reimplemented from Element.

Definition at line 703 of file Line.cpp.

704{
705 wxString tipText = m_electricalData.name;
706
707 if (m_online) {
708 tipText += "\n";
709 int busNumber[2];
710 busNumber[0] = static_cast<Bus*>(m_parentList[0])->GetElectricalData().number + 1;
711 busNumber[1] = static_cast<Bus*>(m_parentList[1])->GetElectricalData().number + 1;
712
713 tipText += _("\nP") + wxString::Format("(%d-%d) = ", busNumber[0], busNumber[1]) +
714 wxString::FromDouble(m_electricalData.powerFlow[0].real(), 5) + _(" p.u.");
715 tipText += _("\nQ") + wxString::Format("(%d-%d) = ", busNumber[0], busNumber[1]) +
716 wxString::FromDouble(m_electricalData.powerFlow[0].imag(), 5) + _(" p.u.");
717 tipText += _("\nP") + wxString::Format("(%d-%d) = ", busNumber[1], busNumber[0]) +
718 wxString::FromDouble(m_electricalData.powerFlow[1].real(), 5) + _(" p.u.");
719 tipText += _("\nQ") + wxString::Format("(%d-%d) = ", busNumber[1], busNumber[0]) +
720 wxString::FromDouble(m_electricalData.powerFlow[1].imag(), 5) + _(" p.u.");
721
722 if (!m_electricalData.harmonicOrder.empty()) {
723 tipText += _("\n\nHarmonic currents:");
724 int i = 0;
725 for (auto& hCurrent1 : m_electricalData.harmonicCurrent[0]) {
726 auto& hCurrent2 = m_electricalData.harmonicCurrent[1][i];
727 wxString i1, i2;
728 i1.Printf(_("\nIh(%d)(%d-%d) = %.5e%s%.2f%s p.u."), m_electricalData.harmonicOrder[i], busNumber[0], busNumber[1], std::abs(hCurrent1), wxString(L'\u2220'), wxRadToDeg(std::arg(hCurrent1)), wxString(L'\u00B0'));
729 i2.Printf(_("\nIh(%d)(%d-%d) = %.5e%s%.2f%s p.u."), m_electricalData.harmonicOrder[i], busNumber[1], busNumber[0], std::abs(hCurrent2), wxString(L'\u2220'), wxRadToDeg(std::arg(hCurrent2)), wxString(L'\u00B0'));
730
731 tipText += i1 + i2;
732 i++;
733 }
734 }
735 }
736
737 return tipText;
738}

◆ Intersects()

bool Line::Intersects ( wxRect2DDouble  rect) const
virtual

Check if the element's rect intersects other rect.

Parameters
rectRect to check intersection.

Reimplemented from Branch.

Definition at line 372 of file Line.cpp.

373{
374 for (auto it = m_pointList.begin(); it != m_pointList.end(); ++it) {
375 if (rect.Contains(*it)) return true;
376 }
377 return false;
378}

◆ Move()

void Line::Move ( wxPoint2DDouble  position)
virtual

Move the element other position.

Parameters
positionPosition that the element will be moved. Use StartMove(wxPoint2DDouble position) before start moving.

Reimplemented from Branch.

Definition at line 240 of file Line.cpp.

241{
242 if (!m_parentList[0]) {
243 m_pointList[0] = m_movePts[0] + position - m_moveStartPt;
244 UpdateSwitchesPosition();
245 UpdatePowerFlowArrowsPosition();
246 }
247 if (!m_parentList[1]) {
248 m_pointList[m_pointList.size() - 1] = m_movePts[m_pointList.size() - 1] + position - m_moveStartPt;
249 UpdateSwitchesPosition();
250 UpdatePowerFlowArrowsPosition();
251 }
252
253 if (!m_parentList[0] && !m_parentList[1]) {
254 for (int i = 2; i < (int)m_pointList.size() - 2; i++) {
255 m_pointList[i] = m_movePts[i] + position - m_moveStartPt;
256 }
257 }
258}

◆ MoveNode()

void Line::MoveNode ( Element *  parent,
wxPoint2DDouble  position 
)
virtual

Move a node. StartMove(wxPoint2DDouble position) before start moving.

Parameters
parentNode's parent.
positionNew node position.

Reimplemented from Branch.

Definition at line 414 of file Line.cpp.

415{
416 if (parent) {
417 // First bus.
418 if (parent == m_parentList[0]) {
419 m_pointList[0] = m_movePts[0] + position - m_moveStartPt;
420 }
421 // Second bus.
422 else if (parent == m_parentList[1]) {
423 m_pointList[m_pointList.size() - 1] = m_movePts[m_pointList.size() - 1] + position - m_moveStartPt;
424 }
425
426 // If the line is selected, move all the points, except the switches and buses points.
427 if (m_selected) {
428 for (int i = 2; i < (int)m_pointList.size() - 1; i++) {
429 m_pointList[i] = m_movePts[i] + position - m_moveStartPt;
430 }
431 }
432 }
433 else {
434 // If parent is setted to nullptr for the firts time, remove the parent child
435 if (m_activeNodeID == 1) {
436 m_pointList[0] = m_movePts[0] + position - m_moveStartPt;
437 if (m_parentList[0]) {
438 m_parentList[0]->RemoveChild(this);
439 m_parentList[0] = nullptr;
440 m_online = false;
441 }
442 }
443 else if (m_activeNodeID == 2) {
444 m_pointList[m_pointList.size() - 1] = m_movePts[m_pointList.size() - 1] + position - m_moveStartPt;
445 if (m_parentList[1]) {
446 m_parentList[1]->RemoveChild(this);
447 m_parentList[1] = nullptr;
448 m_online = false;
449 }
450 }
451 }
452
453 // Recalculate switches positions
454 UpdateSwitchesPosition();
455 UpdatePowerFlowArrowsPosition();
456}

◆ MovePickbox()

void Line::MovePickbox ( wxPoint2DDouble  position)
virtual

Move the pickbox.

Parameters
positionposition that the pickbox will be moved.

Reimplemented from Branch.

Definition at line 379 of file Line.cpp.

380{
381 if (m_activePickboxID == ID_PB_NONE) return;
382
383 for (int i = 2; i < (int)m_pointList.size() - 2; i++) {
384 if (m_activePickboxID == i) {
385 m_pointList[i] = m_movePts[i] + position - m_moveStartPt;
386 UpdateSwitchesPosition();
387 UpdatePowerFlowArrowsPosition();
388 }
389 }
390}

◆ OpenElement()

bool Line::OpenElement ( rapidxml::xml_node<> *  elementNode,
std::vector< Element * >  parentList 
)
virtual

Reimplemented from PowerElement.

Definition at line 919 of file Line.cpp.

920{
921 auto cadPropNode = elementNode->first_node("CADProperties");
922 if (!cadPropNode) return false;
923
924 // Get nodes points
925 std::vector<wxPoint2DDouble> ptsList;
926 auto nodePosList = cadPropNode->first_node("NodeList");
927 if (!nodePosList) return false;
928 auto nodePos = nodePosList->first_node("Node");
929 while (nodePos) {
930 double nodePosX = XMLParser::GetNodeValueDouble(nodePos, "X");
931 double nodePosY = XMLParser::GetNodeValueDouble(nodePos, "Y");
932 ptsList.push_back(wxPoint2DDouble(nodePosX, nodePosY));
933 nodePos = nodePos->next_sibling("Node");
934 }
935
936 // Get parents IDs
937 auto parentIDList = cadPropNode->first_node("ParentIDList");
938 if (!parentIDList) return false;
939 auto parentNode = parentIDList->first_node("ParentID");
940 long parentID[2] = { -1, -1 };
941 while (parentNode) {
942 long index = 0;
943 wxString(parentNode->first_attribute("ID")->value()).ToCLong(&index);
944 wxString(parentNode->value()).ToCLong(&parentID[index]);
945 parentNode = parentNode->next_sibling("ParentID");
946 }
947
948 std::vector<wxPoint2DDouble> nodePtsList; // List of node points
949 nodePtsList.push_back(ptsList[0]); // First point on the list
950 nodePtsList.push_back(ptsList[ptsList.size() - 1]); // Last point on the list
951
952 // List of dummy buses to set not connected nodes properly
953 std::vector<Bus*> dummyBusList;
954 for (unsigned int i = 0; i < nodePtsList.size(); ++i) {
955 if (parentID[i] == -1) // No parent connected
956 {
957 Bus* dummyBus = new Bus(nodePtsList[i]);
958 dummyBusList.push_back(dummyBus);
959 AddParent(dummyBus, nodePtsList[i]);
960 }
961 else { // Parent connected (necessarily a bus, get from bus list)
962 AddParent(parentList[parentID[i]], nodePtsList[i]);
963 }
964 }
965
966 // Add the others nodes (if exists)
967 std::vector<wxPoint2DDouble> midPts;
968 for (unsigned int i = 1; i < ptsList.size() - 1; i++) midPts.push_back(ptsList[i]);
969 m_pointList.insert(m_pointList.begin() + 2, midPts.begin(), midPts.end());
970 SetPointList(m_pointList);
971
972 // Remove dummy buses
973 for (auto it = dummyBusList.begin(), itEnd = dummyBusList.end(); it != itEnd; ++it) {
974 RemoveParent(*it);
975 delete* it;
976 }
977 dummyBusList.clear();
978
979 auto electricalProp = elementNode->first_node("ElectricalProperties");
980 if (!electricalProp) return false;
981
982 SetOnline(XMLParser::GetNodeValueInt(electricalProp, "IsOnline"));
983 m_electricalData.name = electricalProp->first_node("Name")->value();
984 m_electricalData.nominalVoltage = XMLParser::GetNodeValueDouble(electricalProp, "NominalVoltage");
985 m_electricalData.nominalVoltageUnit =
986 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "NominalVoltage", "UnitID"));
987 m_electricalData.nominalPower = XMLParser::GetNodeValueDouble(electricalProp, "NominalPower");
988 m_electricalData.nominalPowerUnit =
989 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "NominalPower", "UnitID"));
990 m_electricalData.resistance = XMLParser::GetNodeValueDouble(electricalProp, "Resistance");
991 m_electricalData.resistanceUnit =
992 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "Resistance", "UnitID"));
993 m_electricalData.indReactance = XMLParser::GetNodeValueDouble(electricalProp, "IndReactance");
994 m_electricalData.indReactanceUnit =
995 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "IndReactance", "UnitID"));
996 m_electricalData.capSusceptance = XMLParser::GetNodeValueDouble(electricalProp, "CapSusceptance");
997 m_electricalData.capSusceptanceUnit =
998 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp, "CapSusceptance", "UnitID"));
999 m_electricalData.lineSize = XMLParser::GetNodeValueDouble(electricalProp, "LineSize");
1000 m_electricalData.useLinePower = XMLParser::GetNodeValueInt(electricalProp, "UseLinePower");
1001
1002 auto fault = electricalProp->first_node("Fault");
1003 m_electricalData.zeroResistance = XMLParser::GetNodeValueDouble(fault, "ZeroResistance");
1004 m_electricalData.zeroIndReactance = XMLParser::GetNodeValueDouble(fault, "ZeroIndReactance");
1005 m_electricalData.zeroCapSusceptance = XMLParser::GetNodeValueDouble(fault, "ZeroCapSusceptance");
1006
1007 if (!OpenSwitchingData(electricalProp)) return false;
1008 if (m_swData.swTime.size() != 0) SetDynamicEvent(true);
1009 return true;
1010}
virtual void RemoveParent(Element *parent)
Remove a parent.
Definition Branch.cpp:105
bool SetOnline(bool online=true)
Set if the element is online or offline.
Definition Element.cpp:465
virtual bool AddParent(Element *parent, wxPoint2DDouble position, bool isOpening=false)
Add a parent to the element. This method must be used on power elements that connect to a bus,...
Definition Line.cpp:306
virtual void SetPointList(std::vector< wxPoint2DDouble > pointList)
Set the list of points that connect the element to the bus.
Definition Line.cpp:689
virtual void SetDynamicEvent(bool dynEvent=true)
Set if the power element have dynamic event.
std::vector< double > swTime

◆ PickboxContains()

bool Line::PickboxContains ( wxPoint2DDouble  position)
virtual

Check if a pickbox contains a point. If contains the attributes related to pickbox movement will be calculated.

Parameters
positionPosition to be checked.
Returns
True if the element constains the pickbox, false otherwise.

Reimplemented from Branch.

Definition at line 391 of file Line.cpp.

392{
393 for (int i = 2; i < (int)m_pointList.size() - 2; i++) {
394 wxRect2DDouble rect(m_pointList[i].m_x - 5.0, m_pointList[i].m_y - 5.0, 10.0, 10.0);
395 if (rect.Contains(position)) {
396 m_activePickboxID = i;
397 return true;
398 }
399 }
400 return false;
401}

◆ RemoveNode()

void Line::RemoveNode ( wxPoint2DDouble  point)
virtual

Definition at line 508 of file Line.cpp.

509{
510 if (PickboxContains(point)) {
511 for (int i = 2; i < (int)m_pointList.size() - 2; i++) {
512 if (m_activePickboxID == i) {
513 m_pointList.erase(m_pointList.begin() + i);
514 break;
515 }
516 }
517 }
518 UpdateSwitchesPosition();
519 UpdatePowerFlowArrowsPosition();
520}
virtual bool PickboxContains(wxPoint2DDouble position)
Check if a pickbox contains a point. If contains the attributes related to pickbox movement will be c...
Definition Line.cpp:391

◆ RotateNode()

void Line::RotateNode ( Element *  parent,
bool  clockwise = true 
)
virtual

Rotate a node.

Parameters
parentNode's parent.
clockwiseTrue to rotate clockwise, false to rotate counter-clockwise.

Reimplemented from Branch.

Definition at line 674 of file Line.cpp.

675{
676 double rotAngle = m_rotationAngle;
677 if (!clockwise) rotAngle = -m_rotationAngle;
678
679 if (parent == m_parentList[0]) {
680 m_pointList[0] = parent->RotateAtPosition(m_pointList[0], rotAngle);
681 }
682 else if (parent == m_parentList[1]) {
683 m_pointList[m_pointList.size() - 1] = parent->RotateAtPosition(m_pointList[m_pointList.size() - 1], rotAngle);
684 }
685 UpdateSwitchesPosition();
686 UpdatePowerFlowArrowsPosition();
687}
Here is the call graph for this function:

◆ SaveElement()

rapidxml::xml_node * Line::SaveElement ( rapidxml::xml_document<> &  doc,
rapidxml::xml_node<> *  elementListNode 
)
virtual

Reimplemented from Element.

Definition at line 850 of file Line.cpp.

851{
852 auto elementNode = XMLParser::AppendNode(doc, elementListNode, "Line");
853 XMLParser::SetNodeAttribute(doc, elementNode, "ID", m_elementID);
854 auto cadProp = XMLParser::AppendNode(doc, elementNode, "CADProperties");
855 auto nodeList = XMLParser::AppendNode(doc, cadProp, "NodeList");
856 int nodeID = 0;
857 // Parse all the points.
858 for (unsigned int i = 0; i < m_pointList.size(); i++) {
859 // Don't save switch points, the method UpdateSwitchesPosition() calculate these points properly after open the
860 // element
861 if ((i != 1) && (i != m_pointList.size() - 2)) {
862 auto nodePos = XMLParser::AppendNode(doc, nodeList, "Node");
863 XMLParser::SetNodeAttribute(doc, nodePos, "ID", nodeID);
864 auto nodePosX = XMLParser::AppendNode(doc, nodePos, "X");
865 XMLParser::SetNodeValue(doc, nodePosX, m_pointList[i].m_x);
866 auto nodePosY = XMLParser::AppendNode(doc, nodePos, "Y");
867 XMLParser::SetNodeValue(doc, nodePosY, m_pointList[i].m_y);
868 nodeID++;
869 }
870 }
871
872 auto parentIDList = XMLParser::AppendNode(doc, cadProp, "ParentIDList");
873 for (unsigned int i = 0; i < m_parentList.size(); i++) {
874 if (m_parentList[i]) {
875 auto parentID = XMLParser::AppendNode(doc, parentIDList, "ParentID");
876 XMLParser::SetNodeAttribute(doc, parentID, "ID", static_cast<int>(i));
877 XMLParser::SetNodeValue(doc, parentID, m_parentList[i]->GetID());
878 }
879 }
880
881 auto electricalProp = XMLParser::AppendNode(doc, elementNode, "ElectricalProperties");
882 auto isOnline = XMLParser::AppendNode(doc, electricalProp, "IsOnline");
883 XMLParser::SetNodeValue(doc, isOnline, m_online);
884 auto name = XMLParser::AppendNode(doc, electricalProp, "Name");
885 XMLParser::SetNodeValue(doc, name, m_electricalData.name);
886 auto nominalVoltage = XMLParser::AppendNode(doc, electricalProp, "NominalVoltage");
887 XMLParser::SetNodeValue(doc, nominalVoltage, m_electricalData.nominalVoltage);
888 XMLParser::SetNodeAttribute(doc, nominalVoltage, "UnitID", static_cast<int>(m_electricalData.nominalVoltageUnit));
889 auto nominalPower = XMLParser::AppendNode(doc, electricalProp, "NominalPower");
890 XMLParser::SetNodeValue(doc, nominalPower, m_electricalData.nominalPower);
891 XMLParser::SetNodeAttribute(doc, nominalPower, "UnitID", static_cast<int>(m_electricalData.nominalPowerUnit));
892 auto resistance = XMLParser::AppendNode(doc, electricalProp, "Resistance");
893 XMLParser::SetNodeValue(doc, resistance, m_electricalData.resistance);
894 XMLParser::SetNodeAttribute(doc, resistance, "UnitID", static_cast<int>(m_electricalData.resistanceUnit));
895 auto indReactance = XMLParser::AppendNode(doc, electricalProp, "IndReactance");
896 XMLParser::SetNodeValue(doc, indReactance, m_electricalData.indReactance);
897 XMLParser::SetNodeAttribute(doc, indReactance, "UnitID", static_cast<int>(m_electricalData.indReactanceUnit));
898 auto capSusceptance = XMLParser::AppendNode(doc, electricalProp, "CapSusceptance");
899 XMLParser::SetNodeValue(doc, capSusceptance, m_electricalData.capSusceptance);
900 XMLParser::SetNodeAttribute(doc, capSusceptance, "UnitID", static_cast<int>(m_electricalData.capSusceptanceUnit));
901 auto lineSize = XMLParser::AppendNode(doc, electricalProp, "LineSize");
902 XMLParser::SetNodeValue(doc, lineSize, m_electricalData.lineSize);
903 auto useLinePower = XMLParser::AppendNode(doc, electricalProp, "UseLinePower");
904 XMLParser::SetNodeValue(doc, useLinePower, m_electricalData.useLinePower);
905
906 auto fault = XMLParser::AppendNode(doc, electricalProp, "Fault");
907 auto zeroResistance = XMLParser::AppendNode(doc, fault, "ZeroResistance");
908 XMLParser::SetNodeValue(doc, zeroResistance, m_electricalData.zeroResistance);
909 auto zeroIndReactance = XMLParser::AppendNode(doc, fault, "ZeroIndReactance");
910 XMLParser::SetNodeValue(doc, zeroIndReactance, m_electricalData.zeroIndReactance);
911 auto zeroCapSusceptance = XMLParser::AppendNode(doc, fault, "ZeroCapSusceptance");
912 XMLParser::SetNodeValue(doc, zeroCapSusceptance, m_electricalData.zeroCapSusceptance);
913
914 SaveSwitchingData(doc, electricalProp);
915
916 return elementNode;
917}
virtual int GetID() const
Get the element ID.
Definition Element.h:275

◆ SetElectricalData()

virtual void Line::SetElectricalData ( LineElectricalData  electricalData)
inlinevirtual

Definition at line 96 of file Line.h.

96{ m_electricalData = electricalData; }

◆ SetNodeParent()

bool Line::SetNodeParent ( Element *  parent)
virtual

Set a perent to the node. If all conditions are met, a new parent are added to the element and the points related to the nodes will be calculated.

Parameters
parentNode parent.
Returns
True if was possible to set the parent.

Reimplemented from Branch.

Definition at line 566 of file Line.cpp.

567{
568 if (m_activeNodeID == 1 && parent == m_parentList[0]) return false;
569 if (m_activeNodeID == 2 && parent == m_parentList[1]) return false;
570
571 if (parent && m_activeNodeID != 0) {
572 wxRect2DDouble nodeRect(0, 0, 0, 0);
573 if (m_activeNodeID == 1) {
574 nodeRect = wxRect2DDouble(m_pointList[0].m_x - 5.0 - m_borderSize, m_pointList[0].m_y - 5.0 - m_borderSize,
575 10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);
576 }
577 if (m_activeNodeID == 2) {
578 nodeRect = wxRect2DDouble(m_pointList[m_pointList.size() - 1].m_x - 5.0 - m_borderSize,
579 m_pointList[m_pointList.size() - 1].m_y - 5.0 - m_borderSize,
580 10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);
581 }
582
583 if (parent->Intersects(nodeRect)) {
584 // If the line has no parents set the new rated voltage, otherwise check if it's not connecting
585 // two different voltages buses
586 Bus* parentBus = static_cast<Bus*>(parent);
587 if (!m_parentList[0] && !m_parentList[1]) {
588 m_electricalData.nominalVoltage = parentBus->GetElectricalData().nominalVoltage;
589 m_electricalData.nominalVoltageUnit = parentBus->GetElectricalData().nominalVoltageUnit;
590 }
591 else if (m_electricalData.nominalVoltage != parentBus->GetElectricalData().nominalVoltage ||
592 m_electricalData.nominalVoltageUnit != parentBus->GetElectricalData().nominalVoltageUnit) {
593 wxMessageDialog msgDialog(nullptr,
594 _("Unable to connect two buses with different nominal voltages.\n"
595 "Use a transformer or edit the bus properties."),
596 _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
597 msgDialog.ShowModal();
598 m_activeNodeID = 0;
599 return false;
600 }
601
602 if (m_activeNodeID == 1) {
603 // Check if the user is trying to connect the same bus.
604 if (m_parentList[1] == parent) {
605 m_activeNodeID = 0;
606 return false;
607 }
608
609 m_parentList[0] = parent;
610
611 // Centralize the node on bus.
612 wxPoint2DDouble parentPt = parent->RotateAtPosition(
613 m_pointList[0], -parent->GetAngle()); // Rotate click to horizontal position.
614 parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
615 parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle());
616 m_pointList[0] = parentPt;
617
618 UpdateSwitchesPosition();
619 UpdatePowerFlowArrowsPosition();
620 return true;
621 }
622 if (m_activeNodeID == 2) {
623 if (m_parentList[0] == parent) {
624 m_activeNodeID = 0;
625 return false;
626 }
627
628 m_parentList[1] = parent;
629
630 wxPoint2DDouble parentPt =
631 parent->RotateAtPosition(m_pointList[m_pointList.size() - 1], -parent->GetAngle());
632 parentPt.m_y = parent->GetPosition().m_y;
633 parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle());
634 m_pointList[m_pointList.size() - 1] = parentPt;
635
636 UpdateSwitchesPosition();
637 UpdatePowerFlowArrowsPosition();
638 return true;
639 }
640 }
641 else {
642 if (m_activeNodeID == 1) m_parentList[0] = nullptr;
643 if (m_activeNodeID == 2) m_parentList[1] = nullptr;
644 }
645 }
646 return false;
647}
virtual bool Intersects(wxRect2DDouble rect) const =0
Check if the element's rect intersects other rect.
Here is the call graph for this function:

◆ SetNominalVoltage()

void Line::SetNominalVoltage ( std::vector< double >  nominalVoltage,
std::vector< ElectricalUnit >  nominalVoltageUnit 
)
virtual

Set nominal voltage of the element.

Parameters
nominalVoltageValue of the nominal voltage.
nominalVoltageUnitUnit of the nominal voltage.

Reimplemented from PowerElement.

Definition at line 558 of file Line.cpp.

559{
560 if (nominalVoltage.size() > 0) {
561 m_electricalData.nominalVoltage = nominalVoltage[0];
562 m_electricalData.nominalVoltageUnit = nominalVoltageUnit[0];
563 }
564}

◆ SetPointList()

void Line::SetPointList ( std::vector< wxPoint2DDouble >  pointList)
virtual

Set the list of points that connect the element to the bus.

Parameters
pointListList of points.

Reimplemented from Element.

Definition at line 689 of file Line.cpp.

690{
691 m_pointList = pointList;
692 UpdateSwitchesPosition();
693 UpdatePowerFlowArrowsPosition();
694}

◆ SetPowerFlowDirection()

void Line::SetPowerFlowDirection ( PowerFlowDirection  pfDirection)
virtual

Set the direction of the power flow.

Parameters
pfDirectionPower flow direction.

Reimplemented from PowerElement.

Definition at line 649 of file Line.cpp.

650{
651 m_pfDirection = pfDirection;
652 UpdatePowerFlowArrowsPosition();
653}
Here is the caller graph for this function:

◆ ShowForm()

bool Line::ShowForm ( wxWindow *  parent,
Element *  element,
wxWindow *  workspace = nullptr 
)
virtual

Show element data form.

Parameters
parentForm parent
elementElement that will be edited.
Returns
True if the form is shown, false otherwise.

Reimplemented from Element.

Definition at line 548 of file Line.cpp.

549{
550 LineForm lineForm(parent, this);
551 lineForm.CenterOnParent();
552 if (lineForm.ShowModal() == wxID_OK) {
553 return true;
554 }
555 return false;
556}
Form to edit the line power data.
Definition LineForm.h:33

◆ StartMove()

void Line::StartMove ( wxPoint2DDouble  position)
virtual

Update the element attributes related to the movement.

Parameters
positionStart move position.

Reimplemented from Branch.

Definition at line 408 of file Line.cpp.

409{
410 m_moveStartPt = position;
411 m_movePts = m_pointList;
412}

◆ UpdatePowerFlowArrowsPosition()

void Line::UpdatePowerFlowArrowsPosition ( )
protectedvirtual

Reimplemented from PowerElement.

Definition at line 655 of file Line.cpp.

656{
657 std::vector<wxPoint2DDouble> edges;
658 switch (m_pfDirection) {
660 m_powerFlowArrow.clear();
661 } break;
663 for (int i = 1; i < (int)m_pointList.size() - 1; i++) { edges.push_back(m_pointList[i]); }
664 } break;
666 for (int i = (int)m_pointList.size() - 2; i > 0; i--) { edges.push_back(m_pointList[i]); }
667 } break;
668 default:
669 break;
670 }
672}
virtual void CalculatePowerFlowPts(std::vector< wxPoint2DDouble > edges)
Calculate the points of the power flow arrows.

Member Data Documentation

◆ m_electricalData

LineElectricalData Line::m_electricalData
protected

Definition at line 105 of file Line.h.


The documentation for this class was generated from the following files: