20#include "../forms/TextForm.h"
22#include "../simulation/ElectricCalculation.h"
35#include "../utils/DegreesAndRadians.h"
40 m_elementType = TYPE_TEXT;
44Text::Text(wxPoint2DDouble position, wxString fontName,
int fontSize) :
GraphicalElement()
46 m_elementType = TYPE_TEXT;
47 m_position = position;
48 m_fontName = fontName;
49 m_fontSize = fontSize;
65 return m_rect.Contains(ptR);
103void Text::DrawDC(wxPoint2DDouble translation,
double scale, wxGraphicsContext* gc)
106 if (m_updateTextRectangle) {
107 for (
GCText* gcText : m_gcTextList) {
108 if (gcText)
delete gcText;
110 m_gcTextList.clear();
112 m_numberOfLines = m_text.Freq(
'\n') + 1;
113 if (m_numberOfLines > 1) m_isMultlineText =
true;
116 wxString multText = m_text;
117 for (
int i = 0; i < m_numberOfLines; ++i) {
119 wxString currentLine = multText.BeforeFirst(
'\n', &nextLine);
123 wxFont font = wxFont(m_fontSize,
124 wxFONTFAMILY_DEFAULT,
129 gcText->SetFont(font);
130 m_gcTextList.push_back(gcText);
132 gc->SetFont(font, *wxBLACK);
135 gc->GetTextExtent(currentLine, &w, &h);
137 if (w > m_width) m_width = w;
141 m_updateTextRectangle =
false;
149 gc->Translate(m_position.m_x, m_position.m_y);
150 gc->Rotate(wxDegToRad(m_angle));
151 gc->Translate(-m_position.m_x, -m_position.m_y);
155 gc->SetPen(*wxTRANSPARENT_PEN);
156 if (m_useAltSelectionColour) gc->SetBrush(wxBrush(wxColour(0, 230, 0, 125)));
157 else gc->SetBrush(wxBrush(wxColour(0, 125, 255, 125)));
159 wxPoint2DDouble pos = m_position - wxPoint2DDouble(m_borderSize / 2.0 + m_width / 2, m_borderSize / 2.0 + m_height / 2);
160 gc->DrawRectangle(pos.m_x, pos.m_y, m_rect.m_width, m_rect.m_height);
166 wxPoint2DDouble pos = m_position - wxPoint2DDouble(m_width / 2, m_height / 2);
167 if (m_isMultlineText) {
168 for (
unsigned int i = 0; i < m_gcTextList.size(); ++i) {
169 m_gcTextList[i]->Draw(
171 wxPoint2DDouble(0.0, (m_height *
static_cast<double>(i) /
static_cast<double>(m_numberOfLines))), gc);
174 else if (m_gcTextList.size() > 0) {
175 m_gcTextList[0]->Draw(pos, gc);
180void Text::DrawDC(wxPoint2DDouble translation,
double scale, wxDC& dc)
183 if (m_updateTextRectangle) {
184 for (
GCText* gcText : m_gcTextList) {
185 if (gcText)
delete gcText;
187 m_gcTextList.clear();
189 m_numberOfLines = m_text.Freq(
'\n') + 1;
190 if (m_numberOfLines > 1) m_isMultlineText =
true;
193 wxString multText = m_text;
194 for (
int i = 0; i < m_numberOfLines; ++i) {
196 wxString currentLine = multText.BeforeFirst(
'\n', &nextLine);
200 wxFont font = wxFont(m_fontSize,
201 wxFONTFAMILY_UNKNOWN,
206 gcText->SetFont(font);
207 m_gcTextList.push_back(gcText);
210 wxSize txtSize = dc.GetTextExtent(currentLine);
212 if (txtSize.GetWidth() > m_width) m_width = txtSize.GetWidth();
213 m_height += txtSize.GetHeight();
216 m_updateTextRectangle =
false;
221 dc.SetPen(*wxTRANSPARENT_PEN);
222 if (m_useAltSelectionColour) dc.SetBrush(wxBrush(wxColour(0, 230, 0, 125)));
223 else dc.SetBrush(wxBrush(wxColour(0, 125, 255, 125)));
225 DrawDCRectangle(m_position, m_rect.m_width, m_rect.m_height, m_angle, dc);
230 if (m_isMultlineText) {
231 for (
unsigned int i = 0; i < m_gcTextList.size(); ++i) {
232 m_gcTextList[i]->Draw(
234 wxPoint2DDouble(0.0, (m_height *
static_cast<double>(i) /
static_cast<double>(m_numberOfLines))), m_width, m_height, dc, m_angle);
237 else if (m_gcTextList.size() > 0) {
238 m_gcTextList[0]->Draw(m_position, m_width, m_height, dc, m_angle);
244 if (m_angle == 0.0 || m_angle == 180.0)
return m_rect.Intersects(rect);
248void Text::SetText(wxString text)
251 m_updateTextRectangle =
true;
256 if (!m_allowRotation)
return;
258 double rotAngle = m_rotationAngle;
259 if (!clockwise) rotAngle = -m_rotationAngle;
262 if (m_angle >= 360 || m_angle <= -360) m_angle = 0.0;
265bool Text::ShowForm(wxWindow* parent, std::vector<Element*> elementList)
267 TextForm textForm(parent,
this, elementList);
268 if (textForm.ShowModal() == wxID_OK) {
274void Text::UpdateText(
double systemPowerBase)
276 switch (m_elementTypeText) {
281 Bus* bus =
static_cast<Bus*
>(m_element);
284 double baseVoltage = data.nominalVoltage;
286 double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
288 switch (m_dataType) {
290 SetText(bus->GetElectricalData().name);
293 double voltage = std::abs(data.voltage);
296 SetText(wxString::FromDouble(voltage, m_decimalPlaces) +
" p.u.");
299 SetText(wxString::FromDouble(voltage * baseVoltage, m_decimalPlaces) +
" V");
302 SetText(wxString::FromDouble(voltage * baseVoltage / 1e3, m_decimalPlaces) +
" kV");
309 double angle = std::arg(data.voltage);
312 SetText(wxString::FromDouble(angle, m_decimalPlaces) +
" rad");
315 SetText(wxString::FromDouble(wxRadToDeg(angle), m_decimalPlaces) + (wxString)L
'\u00B0');
321 case DATA_SC_CURRENT: {
322 double faultCurrent[3] = { std::abs(data.faultCurrent[0]), std::abs(data.faultCurrent[1]),
323 std::abs(data.faultCurrent[2]) };
327 "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) +
" p.u.";
328 str +=
"\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) +
" p.u.";
329 str +=
"\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) +
" p.u.";
334 "Ia = " + wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
337 wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) +
" A";
339 wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) +
" A";
345 wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) +
" kA";
347 wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
350 wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
358 case DATA_SC_VOLTAGE: {
359 double faultVoltage[3] = { std::abs(data.faultVoltage[0]), std::abs(data.faultVoltage[1]),
360 std::abs(data.faultVoltage[2]) };
364 "Va = " + wxString::FromDouble(faultVoltage[0], m_decimalPlaces) +
" p.u.";
365 str +=
"\nVb = " + wxString::FromDouble(faultVoltage[1], m_decimalPlaces) +
" p.u.";
366 str +=
"\nVc = " + wxString::FromDouble(faultVoltage[2], m_decimalPlaces) +
" p.u.";
371 "Va = " + wxString::FromDouble(faultVoltage[0] * baseVoltage, m_decimalPlaces) +
374 wxString::FromDouble(faultVoltage[1] * baseVoltage, m_decimalPlaces) +
" V";
376 wxString::FromDouble(faultVoltage[2] * baseVoltage, m_decimalPlaces) +
" V";
382 wxString::FromDouble(faultVoltage[0] * baseVoltage / 1e3, m_decimalPlaces) +
" kV";
384 wxString::FromDouble(faultVoltage[1] * baseVoltage / 1e3, m_decimalPlaces) +
387 wxString::FromDouble(faultVoltage[2] * baseVoltage / 1e3, m_decimalPlaces) +
395 case DATA_SC_POWER: {
396 double scPower = data.scPower;
397 if (!data.isConnected) scPower = 0.0;
400 SetText(wxString::FromDouble(scPower, m_decimalPlaces) +
" p.u.");
403 SetText(wxString::FromDouble(scPower * systemPowerBase, m_decimalPlaces) +
" VA");
406 SetText(wxString::FromDouble(scPower * systemPowerBase / 1e3, m_decimalPlaces) +
410 SetText(wxString::FromDouble(scPower * systemPowerBase / 1e6, m_decimalPlaces) +
418 SetText(_(
"THD = ") + wxString::FromDouble(data.thd, m_decimalPlaces) +
"%");
425 case TYPE_SYNC_GENERATOR: {
429 double baseVoltage = syncGenerator->GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
430 double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
431 bool busParentOnline =
false;
433 if (parentList.size() == 1) {
434 Bus* busParent =
dynamic_cast<Bus*
>(parentList[0]);
435 if (busParent) busParentOnline = busParent->GetElectricalData().isConnected;
437 switch (m_dataType) {
441 case DATA_ACTIVE_POWER: {
442 double activePower = data.activePower;
443 if (!syncGenerator->
IsOnline() || !busParentOnline) activePower = 0.0;
446 SetText(wxString::FromDouble(activePower, m_decimalPlaces) +
" p.u.");
449 SetText(wxString::FromDouble(activePower * systemPowerBase, m_decimalPlaces) +
" W");
452 SetText(wxString::FromDouble(activePower * systemPowerBase / 1e3, m_decimalPlaces) +
456 SetText(wxString::FromDouble(activePower * systemPowerBase / 1e6, m_decimalPlaces) +
463 case DATA_REACTIVE_POWER: {
464 double reactivePower = data.reactivePower;
465 if (!syncGenerator->
IsOnline() || !busParentOnline) reactivePower = 0.0;
468 SetText(wxString::FromDouble(reactivePower, m_decimalPlaces) +
" p.u.");
471 SetText(wxString::FromDouble(reactivePower * systemPowerBase, m_decimalPlaces) +
475 SetText(wxString::FromDouble(reactivePower * systemPowerBase / 1e3, m_decimalPlaces) +
479 SetText(wxString::FromDouble(reactivePower * systemPowerBase / 1e6, m_decimalPlaces) +
486 case DATA_SC_CURRENT: {
487 double faultCurrent[3] = { std::abs(data.faultCurrent[0]), std::abs(data.faultCurrent[1]),
488 std::abs(data.faultCurrent[2]) };
492 "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) +
" p.u.";
493 str +=
"\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) +
" p.u.";
494 str +=
"\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) +
" p.u.";
499 "Ia = " + wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
502 wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) +
" A";
504 wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) +
" A";
510 wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) +
" kA";
512 wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
515 wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
529 Line* line =
static_cast<Line*
>(m_element);
532 double baseVoltage = data.nominalVoltage;
534 double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
535 bool busParentOnline =
false;
537 if (parentList.size() == 2) {
538 Bus* busParent1 =
dynamic_cast<Bus*
>(parentList[0]);
539 Bus* busParent2 =
dynamic_cast<Bus*
>(parentList[1]);
540 if (busParent1 && busParent2) {
541 if (busParent1->GetElectricalData().isConnected && busParent1->GetElectricalData().isConnected)
542 busParentOnline =
true;
545 switch (m_dataType) {
549 case DATA_PF_ACTIVE: {
550 double activePF = std::real(data.powerFlow[m_direction]);
551 if (!line->
IsOnline() || !busParentOnline) activePF = 0.0;
554 SetText(wxString::FromDouble(activePF, m_decimalPlaces) +
" p.u.");
557 SetText(wxString::FromDouble(activePF * systemPowerBase, m_decimalPlaces) +
" W");
560 SetText(wxString::FromDouble(activePF * systemPowerBase / 1e3, m_decimalPlaces) +
564 SetText(wxString::FromDouble(activePF * systemPowerBase / 1e6, m_decimalPlaces) +
571 case DATA_PF_REACTIVE: {
572 double reactivePF = std::imag(data.powerFlow[m_direction]);
573 if (!line->
IsOnline() || !busParentOnline) reactivePF = 0.0;
576 SetText(wxString::FromDouble(reactivePF, m_decimalPlaces) +
" p.u.");
579 SetText(wxString::FromDouble(reactivePF * systemPowerBase, m_decimalPlaces) +
" var");
582 SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e3, m_decimalPlaces) +
586 SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e6, m_decimalPlaces) +
593 case DATA_PF_LOSSES: {
594 double losses = std::abs(std::real(data.powerFlow[0]) + std::real(data.powerFlow[1]));
595 if (!line->
IsOnline() || !busParentOnline) losses = 0.0;
598 SetText(wxString::FromDouble(losses, m_decimalPlaces) +
" p.u.");
601 SetText(wxString::FromDouble(losses * systemPowerBase, m_decimalPlaces) +
" W");
604 SetText(wxString::FromDouble(losses * systemPowerBase / 1e3, m_decimalPlaces) +
" kW");
607 SetText(wxString::FromDouble(losses * systemPowerBase / 1e6, m_decimalPlaces) +
" MW");
613 case DATA_PF_CURRENT: {
614 double current = std::abs(data.current[m_direction]);
615 if (!line->
IsOnline() || !busParentOnline) current = 0.0;
618 SetText(wxString::FromDouble(current, m_decimalPlaces) +
" p.u.");
621 SetText(wxString::FromDouble(current * baseCurrent, m_decimalPlaces) +
" A");
624 SetText(wxString::FromDouble(current * baseCurrent / 1e3, m_decimalPlaces) +
" kA");
630 case DATA_SC_CURRENT: {
631 double faultCurrent[3] = { std::abs(data.faultCurrent[m_direction][0]),
632 std::abs(data.faultCurrent[m_direction][1]),
633 std::abs(data.faultCurrent[m_direction][2]) };
634 if (!line->
IsOnline()) faultCurrent[0] = faultCurrent[1] = faultCurrent[2] = 0.0;
638 "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) +
" p.u.";
639 str +=
"\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) +
" p.u.";
640 str +=
"\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) +
" p.u.";
645 "Ia = " + wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
648 wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) +
" A";
650 wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) +
" A";
656 wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) +
" kA";
658 wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
661 wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
674 case TYPE_TRANSFORMER: {
678 double baseVoltage[2] = { data.primaryNominalVoltage, data.secondaryNominalVoltage };
679 bool busParentOnline =
false;
681 if (parentList.size() == 2) {
682 Bus* busParent1 =
dynamic_cast<Bus*
>(parentList[0]);
683 Bus* busParent2 =
dynamic_cast<Bus*
>(parentList[1]);
684 if (busParent1 && busParent2) {
685 if (busParent1->GetElectricalData().isConnected && busParent1->GetElectricalData().isConnected)
686 busParentOnline =
true;
693 double baseCurrent[2] = { systemPowerBase / (std::sqrt(3.0) * baseVoltage[0]),
694 systemPowerBase / (std::sqrt(3.0) * baseVoltage[1]) };
695 switch (m_dataType) {
699 case DATA_PF_ACTIVE: {
700 double activePF = std::real(data.powerFlow[m_direction]);
701 if (!transformer->
IsOnline() || !busParentOnline) activePF = 0.0;
704 SetText(wxString::FromDouble(activePF, m_decimalPlaces) +
" p.u.");
707 SetText(wxString::FromDouble(activePF * systemPowerBase, m_decimalPlaces) +
" W");
710 SetText(wxString::FromDouble(activePF * systemPowerBase / 1e3, m_decimalPlaces) +
714 SetText(wxString::FromDouble(activePF * systemPowerBase / 1e6, m_decimalPlaces) +
721 case DATA_PF_REACTIVE: {
722 double reactivePF = std::imag(data.powerFlow[m_direction]);
723 if (!transformer->
IsOnline() || !busParentOnline) reactivePF = 0.0;
726 SetText(wxString::FromDouble(reactivePF, m_decimalPlaces) +
" p.u.");
729 SetText(wxString::FromDouble(reactivePF * systemPowerBase, m_decimalPlaces) +
" var");
732 SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e3, m_decimalPlaces) +
736 SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e6, m_decimalPlaces) +
743 case DATA_PF_LOSSES: {
744 double losses = std::abs(std::real(data.powerFlow[0]) + std::real(data.powerFlow[1]));
745 if (!transformer->
IsOnline() || !busParentOnline) losses = 0.0;
748 SetText(wxString::FromDouble(losses, m_decimalPlaces) +
" p.u.");
751 SetText(wxString::FromDouble(losses * systemPowerBase, m_decimalPlaces) +
" W");
754 SetText(wxString::FromDouble(losses * systemPowerBase / 1e3, m_decimalPlaces) +
" kW");
757 SetText(wxString::FromDouble(losses * systemPowerBase / 1e6, m_decimalPlaces) +
" MW");
763 case DATA_PF_CURRENT: {
764 double current = std::abs(data.current[m_direction]);
765 if (!transformer->
IsOnline() || !busParentOnline) current = 0.0;
768 SetText(wxString::FromDouble(current, m_decimalPlaces) +
" p.u.");
771 SetText(wxString::FromDouble(current * baseCurrent[m_direction], m_decimalPlaces) +
776 wxString::FromDouble(current * baseCurrent[m_direction] / 1e3, m_decimalPlaces) +
783 case DATA_SC_CURRENT: {
784 double faultCurrent[3] = { std::abs(data.faultCurrent[m_direction][0]),
785 std::abs(data.faultCurrent[m_direction][1]),
786 std::abs(data.faultCurrent[m_direction][2]) };
787 if (!transformer->
IsOnline()) faultCurrent[0] = faultCurrent[1] = faultCurrent[2] = 0.0;
791 "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) +
" p.u.";
792 str +=
"\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) +
" p.u.";
793 str +=
"\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) +
" p.u.";
799 wxString::FromDouble(faultCurrent[0] * baseCurrent[m_direction], m_decimalPlaces) +
803 wxString::FromDouble(faultCurrent[1] * baseCurrent[m_direction], m_decimalPlaces) +
807 wxString::FromDouble(faultCurrent[2] * baseCurrent[m_direction], m_decimalPlaces) +
812 wxString str =
"Ia = " +
813 wxString::FromDouble(faultCurrent[0] * baseCurrent[m_direction] / 1e3,
817 wxString::FromDouble(faultCurrent[1] * baseCurrent[m_direction] / 1e3,
821 wxString::FromDouble(faultCurrent[2] * baseCurrent[m_direction] / 1e3,
836 Load* load =
static_cast<Load*
>(m_element);
839 std::complex<double> sPower(data.activePower, data.reactivePower);
840 if (data.loadType == CONST_IMPEDANCE && load->
IsOnline()) {
841 std::complex<double> v =
static_cast<Bus*
>(load->
GetParentList()[0])->GetElectricalData().voltage;
842 sPower = std::pow(std::abs(v), 2) * sPower;
844 bool busParentOnline =
false;
846 if (parentList.size() == 1) {
847 Bus* busParent =
dynamic_cast<Bus*
>(parentList[0]);
849 busParentOnline = busParent->GetElectricalData().isConnected;
852 if (!load->
IsOnline() || !busParentOnline) sPower = std::complex<double>(0.0, 0.0);
853 switch (m_dataType) {
857 case DATA_ACTIVE_POWER: {
860 SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) +
" p.u.");
863 SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) +
" W");
866 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
870 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
877 case DATA_REACTIVE_POWER: {
880 SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) +
" p.u.");
883 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
887 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
891 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
903 case TYPE_SYNC_MOTOR: {
908 bool busParentOnline =
false;
910 if (parentList.size() == 1) {
911 Bus* busParent =
dynamic_cast<Bus*
>(parentList[0]);
913 busParentOnline = busParent->GetElectricalData().isConnected;
915 std::complex<double> sPower(data.activePower, data.reactivePower);
916 if (!syncMotor->
IsOnline() || !busParentOnline) sPower = std::complex<double>(0.0, 0.0);
917 switch (m_dataType) {
921 case DATA_ACTIVE_POWER: {
924 SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) +
" p.u.");
927 SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) +
" W");
930 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
934 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
941 case DATA_REACTIVE_POWER: {
944 SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) +
" p.u.");
947 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
951 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
955 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
967 case TYPE_IND_MOTOR: {
971 bool busParentOnline =
false;
973 if (parentList.size() == 1) {
974 Bus* busParent =
dynamic_cast<Bus*
>(parentList[0]);
976 busParentOnline = busParent->GetElectricalData().isConnected;
978 std::complex<double> sPower(data.activePower, data.reactivePower);
979 if (!indMotor->
IsOnline() || !busParentOnline) sPower = std::complex<double>(0.0, 0.0);
980 switch (m_dataType) {
984 case DATA_ACTIVE_POWER: {
987 SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) +
" p.u.");
990 SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) +
" W");
993 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
997 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
1004 case DATA_REACTIVE_POWER: {
1007 SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) +
" p.u.");
1010 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
1014 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
1018 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
1030 case TYPE_CAPACITOR: {
1034 double reativePower = data.reactivePower;
1036 bool busParentOnline =
false;
1038 if (parentList.size() == 1) {
1039 Bus* busParent =
dynamic_cast<Bus*
>(parentList[0]);
1041 busParentOnline = busParent->GetElectricalData().isConnected;
1044 if (!capacitor->
IsOnline() || !busParentOnline)
1047 std::complex<double> v =
1048 static_cast<Bus*
>(capacitor->
GetParentList()[0])->GetElectricalData().voltage;
1049 reativePower *= std::pow(std::abs(v), 2);
1051 switch (m_dataType) {
1055 case DATA_REACTIVE_POWER: {
1058 SetText(wxString::FromDouble(reativePower, m_decimalPlaces) +
" p.u.");
1061 SetText(wxString::FromDouble(reativePower * systemPowerBase, m_decimalPlaces) +
" var");
1064 SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e3, m_decimalPlaces) +
1068 SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e6, m_decimalPlaces) +
1080 case TYPE_INDUCTOR: {
1084 double reativePower = data.reactivePower;
1086 bool busParentOnline =
false;
1088 if (parentList.size() == 1) {
1089 Bus* busParent =
dynamic_cast<Bus*
>(parentList[0]);
1091 busParentOnline = busParent->GetElectricalData().isConnected;
1094 if (!inductor->
IsOnline() || !busParentOnline)
1097 std::complex<double> v =
1098 static_cast<Bus*
>(inductor->
GetParentList()[0])->GetElectricalData().voltage;
1099 reativePower *= std::pow(std::abs(v), 2);
1101 switch (m_dataType) {
1105 case DATA_REACTIVE_POWER: {
1108 SetText(wxString::FromDouble(reativePower, m_decimalPlaces) +
" p.u.");
1111 SetText(wxString::FromDouble(reativePower * systemPowerBase, m_decimalPlaces) +
" var");
1114 SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e3, m_decimalPlaces) +
1118 SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e6, m_decimalPlaces) +
1130 case TYPE_HARMCURRENT: {
1133 auto data = harmCurrent->GetElectricalData();
1134 switch (m_dataType) {
1150 std::vector<GCText*> copyList;
1151 for (
auto it = m_gcTextList.begin(), itEnd = m_gcTextList.end(); it != itEnd; ++it) {
1152 copyList.push_back((*it)->GetCopy());
1154 copy->m_gcTextList = copyList;
1167rapidxml::xml_node<>* Text::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
1169 auto elementNode = XMLParser::AppendNode(doc, elementListNode,
"Text");
1170 XMLParser::SetNodeAttribute(doc, elementNode,
"ID", m_elementID);
1172 SaveCADProperties(doc, elementNode);
1174 auto textProperties = XMLParser::AppendNode(doc, elementNode,
"TextProperties");
1175 auto elementType = XMLParser::AppendNode(doc, textProperties,
"ElementType");
1176 XMLParser::SetNodeValue(doc, elementType, m_elementTypeText);
1177 auto elementNumber = XMLParser::AppendNode(doc, textProperties,
"ElementNumber");
1178 XMLParser::SetNodeValue(doc, elementNumber, m_elementNumber);
1179 auto dataType = XMLParser::AppendNode(doc, textProperties,
"DataType");
1180 XMLParser::SetNodeValue(doc, dataType, m_dataType);
1181 auto dataUnit = XMLParser::AppendNode(doc, textProperties,
"DataUnit");
1182 XMLParser::SetNodeValue(doc, dataUnit,
static_cast<int>(m_unit));
1183 auto direction = XMLParser::AppendNode(doc, textProperties,
"Direction");
1184 XMLParser::SetNodeValue(doc, direction, m_direction);
1185 auto decimalPlaces = XMLParser::AppendNode(doc, textProperties,
"DecimalPlaces");
1186 XMLParser::SetNodeValue(doc, decimalPlaces, m_decimalPlaces);
1191bool Text::OpenElement(rapidxml::xml_node<>* elementNode)
1193 if (!OpenCADProperties(elementNode))
return false;
1195 auto textProperties = elementNode->first_node(
"TextProperties");
1196 if (!textProperties)
return false;
1198 SetElementTypeText(
static_cast<ElementType
>(XMLParser::GetNodeValueDouble(textProperties,
"ElementType")));
1199 SetDataType(
static_cast<DataType
>(XMLParser::GetNodeValueDouble(textProperties,
"DataType")));
1200 SetUnit(
static_cast<ElectricalUnit>(XMLParser::GetNodeValueDouble(textProperties,
"DataUnit")));
1201 SetDirection(XMLParser::GetNodeValueDouble(textProperties,
"Direction"));
1202 SetDecimalPlaces(XMLParser::GetNodeValueDouble(textProperties,
"DecimalPlaces"));
1203 SetElementNumber(XMLParser::GetNodeValueInt(textProperties,
"ElementNumber"));
ElectricalUnit
Electrical units.
Node for power elements. All others power elements are connected through this.
Shunt capactior power element.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
virtual bool RotatedRectanglesIntersects(wxRect2DDouble rect1, wxRect2DDouble rect2, double angle1, double angle2) const
Check if two roteted rectangles intersect.
virtual std::vector< Element * > GetParentList() const
Get the parent list.
bool IsOnline() const
Checks if the element is online or offline.
virtual void DrawDCRectangle(wxPoint2DDouble position, double width, double height, double angle, wxDC &dc) const
Draw a circle.
void SetPosition(const wxPoint2DDouble position)
Set the element position and update the rectangle.
virtual wxPoint2DDouble RotateAtPosition(wxPoint2DDouble pointToRotate, double angle, bool degrees=true) const
Rotate a point as element position being the origin.
void SetInserted(bool inserted=true)
Set if the element is properly inserted in the workspace.
Class to draw text on Graphics Context using wxWidgets.
Abstract class for graphical elements shown with power elements in workspace.
Shunt Harmonic Corrent Source.
Induction motor power element.
Inductor shunt power element.
Loas shunt power element.
Synchronous generator power element.
Synchronous motor (synchronous compensator) power element.
Form to edit the text graphical data.
Element that shows power element informations in workspace.
virtual Element * GetCopy()
Get a the element copy.
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element's rect intersects other rect.
virtual void Rotate(bool clockwise=true)
Rotate the element.