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;
61 for (
auto& gcText : m_gcTextList) {
62 if (gcText)
delete gcText;
70 return m_rect.Contains(ptR);
108void Text::DrawDC(wxPoint2DDouble translation,
double scale, wxGraphicsContext* gc)
111 if (m_updateTextRectangle) {
112 for (
GCText* gcText : m_gcTextList) {
113 if (gcText)
delete gcText;
115 m_gcTextList.clear();
117 m_numberOfLines = m_text.Freq(
'\n') + 1;
118 m_isMultlineText = m_numberOfLines > 1;
121 wxFont font = wxFont(m_fontSize,
122 wxFONTFAMILY_DEFAULT,
127 gc->SetFont(font, *wxBLACK);
129 wxString multText = m_text;
130 for (
int i = 0; i < m_numberOfLines; ++i) {
132 wxString currentLine = multText.BeforeFirst(
'\n', &nextLine);
136 gc->GetTextExtent(currentLine, &w, &h);
138 if (w > m_width) m_width = w;
142 gcText->SetFont(font);
143 gcText->
SetText(currentLine, wxSize(
static_cast<int>(w),
static_cast<int>(h)));
144 m_gcTextList.push_back(gcText);
147 m_updateTextRectangle =
false;
155 gc->Translate(m_position.m_x, m_position.m_y);
156 gc->Rotate(wxDegToRad(m_angle));
157 gc->Translate(-m_position.m_x, -m_position.m_y);
161 gc->SetPen(*wxTRANSPARENT_PEN);
162 if (m_useAltSelectionColour) gc->SetBrush(wxBrush(wxColour(0, 230, 0, 125)));
163 else gc->SetBrush(wxBrush(wxColour(0, 125, 255, 125)));
165 wxPoint2DDouble pos = m_position - wxPoint2DDouble(m_borderSize / 2.0 + m_width / 2, m_borderSize / 2.0 + m_height / 2);
166 gc->DrawRectangle(pos.m_x, pos.m_y, m_rect.m_width, m_rect.m_height);
172 wxPoint2DDouble pos = m_position - wxPoint2DDouble(m_width / 2, m_height / 2);
173 if (m_isMultlineText) {
174 for (
unsigned int i = 0; i < m_gcTextList.size(); ++i) {
175 m_gcTextList[i]->Draw(
177 wxPoint2DDouble(0.0, (m_height *
static_cast<double>(i) /
static_cast<double>(m_numberOfLines))), gc);
180 else if (m_gcTextList.size() > 0) {
181 m_gcTextList[0]->Draw(pos, gc);
186void Text::DrawDC(wxPoint2DDouble translation,
double scale, wxDC& dc)
189 if (m_updateTextRectangle) {
190 for (
GCText* gcText : m_gcTextList) {
191 if (gcText)
delete gcText;
193 m_gcTextList.clear();
195 m_numberOfLines = m_text.Freq(
'\n') + 1;
196 m_isMultlineText = m_numberOfLines > 1;
199 wxFont font = wxFont(m_fontSize,
200 wxFONTFAMILY_DEFAULT,
207 wxString multText = m_text;
208 for (
int i = 0; i < m_numberOfLines; ++i) {
210 wxString currentLine = multText.BeforeFirst(
'\n', &nextLine);
213 wxSize txtSize = dc.GetTextExtent(currentLine);
215 if (txtSize.GetWidth() > m_width) m_width = txtSize.GetWidth();
216 m_height += txtSize.GetHeight();
219 gcText->SetFont(font);
220 gcText->
SetText(currentLine, txtSize);
221 m_gcTextList.push_back(gcText);
224 m_updateTextRectangle =
false;
229 dc.SetPen(*wxTRANSPARENT_PEN);
230 if (m_useAltSelectionColour) dc.SetBrush(wxBrush(wxColour(0, 230, 0, 125)));
231 else dc.SetBrush(wxBrush(wxColour(0, 125, 255, 125)));
233 DrawDCRectangle(m_position, m_rect.m_width, m_rect.m_height, m_angle, dc);
238 if (m_isMultlineText) {
239 for (
unsigned int i = 0; i < m_gcTextList.size(); ++i) {
240 m_gcTextList[i]->Draw(
242 wxPoint2DDouble(0.0, (m_height *
static_cast<double>(i) /
static_cast<double>(m_numberOfLines))), m_width, m_height, dc, m_angle);
245 else if (m_gcTextList.size() > 0) {
246 m_gcTextList[0]->Draw(m_position, m_width, m_height, dc, m_angle);
252 if (m_angle == 0.0 || m_angle == 180.0)
return m_rect.Intersects(rect);
256void Text::SetText(wxString text)
258 if (m_text == text)
return;
261 m_updateTextRectangle =
true;
266 if (!m_allowRotation)
return;
268 double rotAngle = m_rotationAngle;
269 if (!clockwise) rotAngle = -m_rotationAngle;
272 if (m_angle >= 360 || m_angle <= -360) m_angle = 0.0;
275bool Text::ShowForm(wxWindow* parent, std::vector<Element*> elementList)
277 TextForm textForm(parent,
this, elementList);
278 if (textForm.ShowModal() == wxID_OK) {
284void Text::UpdateText(
double systemPowerBase)
286 switch (m_elementTypeText) {
291 Bus* bus =
static_cast<Bus*
>(m_element);
294 double baseVoltage = data.nominalVoltage;
296 double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
298 switch (m_dataType) {
300 SetText(bus->GetElectricalData().name);
303 double voltage = std::abs(data.voltage);
306 SetText(wxString::FromDouble(voltage, m_decimalPlaces) +
" p.u.");
309 SetText(wxString::FromDouble(voltage * baseVoltage, m_decimalPlaces) +
" V");
312 SetText(wxString::FromDouble(voltage * baseVoltage / 1e3, m_decimalPlaces) +
" kV");
319 double angle = std::arg(data.voltage);
322 SetText(wxString::FromDouble(angle, m_decimalPlaces) +
" rad");
325 SetText(wxString::FromDouble(wxRadToDeg(angle), m_decimalPlaces) + (wxString)L
'\u00B0');
331 case DATA_SC_CURRENT: {
332 double faultCurrent[3] = { std::abs(data.faultCurrent[0]), std::abs(data.faultCurrent[1]),
333 std::abs(data.faultCurrent[2]) };
337 "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) +
" p.u.";
338 str +=
"\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) +
" p.u.";
339 str +=
"\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) +
" p.u.";
344 "Ia = " + wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
347 wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) +
" A";
349 wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) +
" A";
355 wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) +
" kA";
357 wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
360 wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
368 case DATA_SC_VOLTAGE: {
369 double faultVoltage[3] = { std::abs(data.faultVoltage[0]), std::abs(data.faultVoltage[1]),
370 std::abs(data.faultVoltage[2]) };
374 "Va = " + wxString::FromDouble(faultVoltage[0], m_decimalPlaces) +
" p.u.";
375 str +=
"\nVb = " + wxString::FromDouble(faultVoltage[1], m_decimalPlaces) +
" p.u.";
376 str +=
"\nVc = " + wxString::FromDouble(faultVoltage[2], m_decimalPlaces) +
" p.u.";
381 "Va = " + wxString::FromDouble(faultVoltage[0] * baseVoltage, m_decimalPlaces) +
384 wxString::FromDouble(faultVoltage[1] * baseVoltage, m_decimalPlaces) +
" V";
386 wxString::FromDouble(faultVoltage[2] * baseVoltage, m_decimalPlaces) +
" V";
392 wxString::FromDouble(faultVoltage[0] * baseVoltage / 1e3, m_decimalPlaces) +
" kV";
394 wxString::FromDouble(faultVoltage[1] * baseVoltage / 1e3, m_decimalPlaces) +
397 wxString::FromDouble(faultVoltage[2] * baseVoltage / 1e3, m_decimalPlaces) +
405 case DATA_SC_POWER: {
406 double scPower = data.scPower;
407 if (!data.isConnected) scPower = 0.0;
410 SetText(wxString::FromDouble(scPower, m_decimalPlaces) +
" p.u.");
413 SetText(wxString::FromDouble(scPower * systemPowerBase, m_decimalPlaces) +
" VA");
416 SetText(wxString::FromDouble(scPower * systemPowerBase / 1e3, m_decimalPlaces) +
420 SetText(wxString::FromDouble(scPower * systemPowerBase / 1e6, m_decimalPlaces) +
428 SetText(_(
"THD = ") + wxString::FromDouble(data.thd, m_decimalPlaces) +
"%");
435 case TYPE_SYNC_GENERATOR: {
439 double baseVoltage = syncGenerator->GetValueFromUnit(data.nominalVoltage, data.nominalVoltageUnit);
440 double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
441 bool busParentOnline =
false;
443 if (parentList.size() == 1) {
444 Bus* busParent =
dynamic_cast<Bus*
>(parentList[0]);
445 if (busParent) busParentOnline = busParent->GetElectricalData().isConnected;
447 switch (m_dataType) {
451 case DATA_ACTIVE_POWER: {
452 double activePower = data.activePower;
453 if (!syncGenerator->
IsOnline() || !busParentOnline) activePower = 0.0;
456 SetText(wxString::FromDouble(activePower, m_decimalPlaces) +
" p.u.");
459 SetText(wxString::FromDouble(activePower * systemPowerBase, m_decimalPlaces) +
" W");
462 SetText(wxString::FromDouble(activePower * systemPowerBase / 1e3, m_decimalPlaces) +
466 SetText(wxString::FromDouble(activePower * systemPowerBase / 1e6, m_decimalPlaces) +
473 case DATA_REACTIVE_POWER: {
474 double reactivePower = data.reactivePower;
475 if (!syncGenerator->
IsOnline() || !busParentOnline) reactivePower = 0.0;
478 SetText(wxString::FromDouble(reactivePower, m_decimalPlaces) +
" p.u.");
481 SetText(wxString::FromDouble(reactivePower * systemPowerBase, m_decimalPlaces) +
485 SetText(wxString::FromDouble(reactivePower * systemPowerBase / 1e3, m_decimalPlaces) +
489 SetText(wxString::FromDouble(reactivePower * systemPowerBase / 1e6, m_decimalPlaces) +
496 case DATA_SC_CURRENT: {
497 double faultCurrent[3] = { std::abs(data.faultCurrent[0]), std::abs(data.faultCurrent[1]),
498 std::abs(data.faultCurrent[2]) };
502 "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) +
" p.u.";
503 str +=
"\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) +
" p.u.";
504 str +=
"\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) +
" p.u.";
509 "Ia = " + wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
512 wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) +
" A";
514 wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) +
" A";
520 wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) +
" kA";
522 wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
525 wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
539 Line* line =
static_cast<Line*
>(m_element);
542 double baseVoltage = data.nominalVoltage;
544 double baseCurrent = systemPowerBase / (std::sqrt(3.0) * baseVoltage);
545 bool busParentOnline =
false;
547 if (parentList.size() == 2) {
548 Bus* busParent1 =
dynamic_cast<Bus*
>(parentList[0]);
549 Bus* busParent2 =
dynamic_cast<Bus*
>(parentList[1]);
550 if (busParent1 && busParent2) {
551 if (busParent1->GetElectricalData().isConnected && busParent1->GetElectricalData().isConnected)
552 busParentOnline =
true;
555 switch (m_dataType) {
559 case DATA_PF_ACTIVE: {
560 double activePF = std::real(data.powerFlow[m_direction]);
561 if (!line->
IsOnline() || !busParentOnline) activePF = 0.0;
564 SetText(wxString::FromDouble(activePF, m_decimalPlaces) +
" p.u.");
567 SetText(wxString::FromDouble(activePF * systemPowerBase, m_decimalPlaces) +
" W");
570 SetText(wxString::FromDouble(activePF * systemPowerBase / 1e3, m_decimalPlaces) +
574 SetText(wxString::FromDouble(activePF * systemPowerBase / 1e6, m_decimalPlaces) +
581 case DATA_PF_REACTIVE: {
582 double reactivePF = std::imag(data.powerFlow[m_direction]);
583 if (!line->
IsOnline() || !busParentOnline) reactivePF = 0.0;
586 SetText(wxString::FromDouble(reactivePF, m_decimalPlaces) +
" p.u.");
589 SetText(wxString::FromDouble(reactivePF * systemPowerBase, m_decimalPlaces) +
" var");
592 SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e3, m_decimalPlaces) +
596 SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e6, m_decimalPlaces) +
603 case DATA_PF_LOSSES: {
604 double losses = std::abs(std::real(data.powerFlow[0]) + std::real(data.powerFlow[1]));
605 if (!line->
IsOnline() || !busParentOnline) losses = 0.0;
608 SetText(wxString::FromDouble(losses, m_decimalPlaces) +
" p.u.");
611 SetText(wxString::FromDouble(losses * systemPowerBase, m_decimalPlaces) +
" W");
614 SetText(wxString::FromDouble(losses * systemPowerBase / 1e3, m_decimalPlaces) +
" kW");
617 SetText(wxString::FromDouble(losses * systemPowerBase / 1e6, m_decimalPlaces) +
" MW");
623 case DATA_PF_CURRENT: {
624 double current = std::abs(data.current[m_direction]);
625 if (!line->
IsOnline() || !busParentOnline) current = 0.0;
628 SetText(wxString::FromDouble(current, m_decimalPlaces) +
" p.u.");
631 SetText(wxString::FromDouble(current * baseCurrent, m_decimalPlaces) +
" A");
634 SetText(wxString::FromDouble(current * baseCurrent / 1e3, m_decimalPlaces) +
" kA");
640 case DATA_SC_CURRENT: {
641 double faultCurrent[3] = { std::abs(data.faultCurrent[m_direction][0]),
642 std::abs(data.faultCurrent[m_direction][1]),
643 std::abs(data.faultCurrent[m_direction][2]) };
644 if (!line->
IsOnline()) faultCurrent[0] = faultCurrent[1] = faultCurrent[2] = 0.0;
648 "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) +
" p.u.";
649 str +=
"\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) +
" p.u.";
650 str +=
"\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) +
" p.u.";
655 "Ia = " + wxString::FromDouble(faultCurrent[0] * baseCurrent, m_decimalPlaces) +
658 wxString::FromDouble(faultCurrent[1] * baseCurrent, m_decimalPlaces) +
" A";
660 wxString::FromDouble(faultCurrent[2] * baseCurrent, m_decimalPlaces) +
" A";
666 wxString::FromDouble(faultCurrent[0] * baseCurrent / 1e3, m_decimalPlaces) +
" kA";
668 wxString::FromDouble(faultCurrent[1] * baseCurrent / 1e3, m_decimalPlaces) +
671 wxString::FromDouble(faultCurrent[2] * baseCurrent / 1e3, m_decimalPlaces) +
684 case TYPE_TRANSFORMER: {
688 double baseVoltage[2] = { data.primaryNominalVoltage, data.secondaryNominalVoltage };
689 bool busParentOnline =
false;
691 if (parentList.size() == 2) {
692 Bus* busParent1 =
dynamic_cast<Bus*
>(parentList[0]);
693 Bus* busParent2 =
dynamic_cast<Bus*
>(parentList[1]);
694 if (busParent1 && busParent2) {
695 if (busParent1->GetElectricalData().isConnected && busParent1->GetElectricalData().isConnected)
696 busParentOnline =
true;
703 double baseCurrent[2] = { systemPowerBase / (std::sqrt(3.0) * baseVoltage[0]),
704 systemPowerBase / (std::sqrt(3.0) * baseVoltage[1]) };
705 switch (m_dataType) {
709 case DATA_PF_ACTIVE: {
710 double activePF = std::real(data.powerFlow[m_direction]);
711 if (!transformer->
IsOnline() || !busParentOnline) activePF = 0.0;
714 SetText(wxString::FromDouble(activePF, m_decimalPlaces) +
" p.u.");
717 SetText(wxString::FromDouble(activePF * systemPowerBase, m_decimalPlaces) +
" W");
720 SetText(wxString::FromDouble(activePF * systemPowerBase / 1e3, m_decimalPlaces) +
724 SetText(wxString::FromDouble(activePF * systemPowerBase / 1e6, m_decimalPlaces) +
731 case DATA_PF_REACTIVE: {
732 double reactivePF = std::imag(data.powerFlow[m_direction]);
733 if (!transformer->
IsOnline() || !busParentOnline) reactivePF = 0.0;
736 SetText(wxString::FromDouble(reactivePF, m_decimalPlaces) +
" p.u.");
739 SetText(wxString::FromDouble(reactivePF * systemPowerBase, m_decimalPlaces) +
" var");
742 SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e3, m_decimalPlaces) +
746 SetText(wxString::FromDouble(reactivePF * systemPowerBase / 1e6, m_decimalPlaces) +
753 case DATA_PF_LOSSES: {
754 double losses = std::abs(std::real(data.powerFlow[0]) + std::real(data.powerFlow[1]));
755 if (!transformer->
IsOnline() || !busParentOnline) losses = 0.0;
758 SetText(wxString::FromDouble(losses, m_decimalPlaces) +
" p.u.");
761 SetText(wxString::FromDouble(losses * systemPowerBase, m_decimalPlaces) +
" W");
764 SetText(wxString::FromDouble(losses * systemPowerBase / 1e3, m_decimalPlaces) +
" kW");
767 SetText(wxString::FromDouble(losses * systemPowerBase / 1e6, m_decimalPlaces) +
" MW");
773 case DATA_PF_CURRENT: {
774 double current = std::abs(data.current[m_direction]);
775 if (!transformer->
IsOnline() || !busParentOnline) current = 0.0;
778 SetText(wxString::FromDouble(current, m_decimalPlaces) +
" p.u.");
781 SetText(wxString::FromDouble(current * baseCurrent[m_direction], m_decimalPlaces) +
786 wxString::FromDouble(current * baseCurrent[m_direction] / 1e3, m_decimalPlaces) +
793 case DATA_SC_CURRENT: {
794 double faultCurrent[3] = { std::abs(data.faultCurrent[m_direction][0]),
795 std::abs(data.faultCurrent[m_direction][1]),
796 std::abs(data.faultCurrent[m_direction][2]) };
797 if (!transformer->
IsOnline()) faultCurrent[0] = faultCurrent[1] = faultCurrent[2] = 0.0;
801 "Ia = " + wxString::FromDouble(faultCurrent[0], m_decimalPlaces) +
" p.u.";
802 str +=
"\nIb = " + wxString::FromDouble(faultCurrent[1], m_decimalPlaces) +
" p.u.";
803 str +=
"\nIc = " + wxString::FromDouble(faultCurrent[2], m_decimalPlaces) +
" p.u.";
809 wxString::FromDouble(faultCurrent[0] * baseCurrent[m_direction], m_decimalPlaces) +
813 wxString::FromDouble(faultCurrent[1] * baseCurrent[m_direction], m_decimalPlaces) +
817 wxString::FromDouble(faultCurrent[2] * baseCurrent[m_direction], m_decimalPlaces) +
822 wxString str =
"Ia = " +
823 wxString::FromDouble(faultCurrent[0] * baseCurrent[m_direction] / 1e3,
827 wxString::FromDouble(faultCurrent[1] * baseCurrent[m_direction] / 1e3,
831 wxString::FromDouble(faultCurrent[2] * baseCurrent[m_direction] / 1e3,
846 Load* load =
static_cast<Load*
>(m_element);
849 std::complex<double> sPower(data.activePower, data.reactivePower);
850 if (data.loadType == CONST_IMPEDANCE && load->
IsOnline()) {
851 std::complex<double> v =
static_cast<Bus*
>(load->
GetParentList()[0])->GetElectricalData().voltage;
852 sPower = std::pow(std::abs(v), 2) * sPower;
854 bool busParentOnline =
false;
856 if (parentList.size() == 1) {
857 Bus* busParent =
dynamic_cast<Bus*
>(parentList[0]);
859 busParentOnline = busParent->GetElectricalData().isConnected;
862 if (!load->
IsOnline() || !busParentOnline) sPower = std::complex<double>(0.0, 0.0);
863 switch (m_dataType) {
867 case DATA_ACTIVE_POWER: {
870 SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) +
" p.u.");
873 SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) +
" W");
876 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
880 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
887 case DATA_REACTIVE_POWER: {
890 SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) +
" p.u.");
893 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
897 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
901 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
913 case TYPE_SYNC_MOTOR: {
918 bool busParentOnline =
false;
920 if (parentList.size() == 1) {
921 Bus* busParent =
dynamic_cast<Bus*
>(parentList[0]);
923 busParentOnline = busParent->GetElectricalData().isConnected;
925 std::complex<double> sPower(data.activePower, data.reactivePower);
926 if (!syncMotor->
IsOnline() || !busParentOnline) sPower = std::complex<double>(0.0, 0.0);
927 switch (m_dataType) {
931 case DATA_ACTIVE_POWER: {
934 SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) +
" p.u.");
937 SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) +
" W");
940 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
944 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
951 case DATA_REACTIVE_POWER: {
954 SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) +
" p.u.");
957 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
961 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
965 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
977 case TYPE_IND_MOTOR: {
981 bool busParentOnline =
false;
983 if (parentList.size() == 1) {
984 Bus* busParent =
dynamic_cast<Bus*
>(parentList[0]);
986 busParentOnline = busParent->GetElectricalData().isConnected;
988 std::complex<double> sPower(data.activePower, data.reactivePower);
989 if (!indMotor->
IsOnline() || !busParentOnline) sPower = std::complex<double>(0.0, 0.0);
990 switch (m_dataType) {
994 case DATA_ACTIVE_POWER: {
997 SetText(wxString::FromDouble(sPower.real(), m_decimalPlaces) +
" p.u.");
1000 SetText(wxString::FromDouble(sPower.real() * systemPowerBase, m_decimalPlaces) +
" W");
1003 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e3, m_decimalPlaces) +
1007 SetText(wxString::FromDouble(sPower.real() * systemPowerBase / 1e6, m_decimalPlaces) +
1014 case DATA_REACTIVE_POWER: {
1017 SetText(wxString::FromDouble(sPower.imag(), m_decimalPlaces) +
" p.u.");
1020 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase, m_decimalPlaces) +
1024 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e3, m_decimalPlaces) +
1028 SetText(wxString::FromDouble(sPower.imag() * systemPowerBase / 1e6, m_decimalPlaces) +
1040 case TYPE_CAPACITOR: {
1044 double reativePower = data.reactivePower;
1046 bool busParentOnline =
false;
1048 if (parentList.size() == 1) {
1049 Bus* busParent =
dynamic_cast<Bus*
>(parentList[0]);
1051 busParentOnline = busParent->GetElectricalData().isConnected;
1054 if (!capacitor->
IsOnline() || !busParentOnline)
1057 std::complex<double> v =
1058 static_cast<Bus*
>(capacitor->
GetParentList()[0])->GetElectricalData().voltage;
1059 reativePower *= std::pow(std::abs(v), 2);
1061 switch (m_dataType) {
1065 case DATA_REACTIVE_POWER: {
1068 SetText(wxString::FromDouble(reativePower, m_decimalPlaces) +
" p.u.");
1071 SetText(wxString::FromDouble(reativePower * systemPowerBase, m_decimalPlaces) +
" var");
1074 SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e3, m_decimalPlaces) +
1078 SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e6, m_decimalPlaces) +
1090 case TYPE_INDUCTOR: {
1094 double reativePower = data.reactivePower;
1096 bool busParentOnline =
false;
1098 if (parentList.size() == 1) {
1099 Bus* busParent =
dynamic_cast<Bus*
>(parentList[0]);
1101 busParentOnline = busParent->GetElectricalData().isConnected;
1104 if (!inductor->
IsOnline() || !busParentOnline)
1107 std::complex<double> v =
1108 static_cast<Bus*
>(inductor->
GetParentList()[0])->GetElectricalData().voltage;
1109 reativePower *= std::pow(std::abs(v), 2);
1111 switch (m_dataType) {
1115 case DATA_REACTIVE_POWER: {
1118 SetText(wxString::FromDouble(reativePower, m_decimalPlaces) +
" p.u.");
1121 SetText(wxString::FromDouble(reativePower * systemPowerBase, m_decimalPlaces) +
" var");
1124 SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e3, m_decimalPlaces) +
1128 SetText(wxString::FromDouble(reativePower * systemPowerBase / 1e6, m_decimalPlaces) +
1140 case TYPE_HARMCURRENT: {
1143 auto data = harmCurrent->GetElectricalData();
1144 switch (m_dataType) {
1160 copy->m_gcTextList.clear();
1161 copy->m_updateTextRectangle =
true;
1174rapidxml::xml_node<>* Text::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
1176 auto elementNode = XMLParser::AppendNode(doc, elementListNode,
"Text");
1177 XMLParser::SetNodeAttribute(doc, elementNode,
"ID", m_elementID);
1179 SaveCADProperties(doc, elementNode);
1181 auto textProperties = XMLParser::AppendNode(doc, elementNode,
"TextProperties");
1182 auto elementType = XMLParser::AppendNode(doc, textProperties,
"ElementType");
1183 XMLParser::SetNodeValue(doc, elementType, m_elementTypeText);
1184 auto elementNumber = XMLParser::AppendNode(doc, textProperties,
"ElementNumber");
1185 XMLParser::SetNodeValue(doc, elementNumber, m_elementNumber);
1186 auto dataType = XMLParser::AppendNode(doc, textProperties,
"DataType");
1187 XMLParser::SetNodeValue(doc, dataType, m_dataType);
1188 auto dataUnit = XMLParser::AppendNode(doc, textProperties,
"DataUnit");
1189 XMLParser::SetNodeValue(doc, dataUnit,
static_cast<int>(m_unit));
1190 auto direction = XMLParser::AppendNode(doc, textProperties,
"Direction");
1191 XMLParser::SetNodeValue(doc, direction, m_direction);
1192 auto decimalPlaces = XMLParser::AppendNode(doc, textProperties,
"DecimalPlaces");
1193 XMLParser::SetNodeValue(doc, decimalPlaces, m_decimalPlaces);
1198bool Text::OpenElement(rapidxml::xml_node<>* elementNode)
1200 if (!OpenCADProperties(elementNode))
return false;
1202 auto textProperties = elementNode->first_node(
"TextProperties");
1203 if (!textProperties)
return false;
1205 SetElementTypeText(
static_cast<ElementType
>(XMLParser::GetNodeValueDouble(textProperties,
"ElementType")));
1206 SetDataType(
static_cast<DataType
>(XMLParser::GetNodeValueDouble(textProperties,
"DataType")));
1207 SetUnit(
static_cast<ElectricalUnit>(XMLParser::GetNodeValueDouble(textProperties,
"DataUnit")));
1208 SetDirection(XMLParser::GetNodeValueDouble(textProperties,
"Direction"));
1209 SetDecimalPlaces(XMLParser::GetNodeValueDouble(textProperties,
"DecimalPlaces"));
1210 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.
virtual void SetText(wxString text)
Set correctly a new text string.
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.