Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file GUIChargingStation.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @author Tamas Kurczveil
19 : /// @author Pablo Alvarez Lopez
20 : /// @author Mirko Barthauer
21 : /// @date 20-12-13
22 : ///
23 : // A lane area vehicles can halt at (gui-version)
24 : /****************************************************************************/
25 : #include <config.h>
26 :
27 : #include <foreign/fontstash/fontstash.h>
28 : #include <gui/GUIApplicationWindow.h>
29 : #include <gui/GUIGlobals.h>
30 : #include <microsim/MSEdge.h>
31 : #include <microsim/MSLane.h>
32 : #include <microsim/MSNet.h>
33 : #include <microsim/MSParkingArea.h>
34 : #include <microsim/logging/FunctionBinding.h>
35 : #include <utils/common/MsgHandler.h>
36 : #include <utils/common/ToString.h>
37 : #include <utils/geom/Boundary.h>
38 : #include <utils/geom/GeomHelper.h>
39 : #include <utils/geom/PositionVector.h>
40 : #include <utils/gui/div/GLHelper.h>
41 : #include <utils/gui/div/GUIGlobalSelection.h>
42 : #include <utils/gui/div/GUIParameterTableWindow.h>
43 : #include <utils/gui/globjects/GLIncludes.h>
44 : #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
45 : #include <utils/gui/windows/GUIAppEnum.h>
46 :
47 : #include "GUINet.h"
48 : #include "GUIEdge.h"
49 : #include "GUIPerson.h"
50 : #include "GUIChargingStation.h"
51 :
52 :
53 : // ===========================================================================
54 : // method definitions
55 : // ===========================================================================
56 295 : GUIChargingStation::GUIChargingStation(const std::string& id, MSLane& lane, double frompos, double topos, const std::string& name,
57 : double chargingPower, double totalPower, double efficiency, bool chargeInTransit, SUMOTime chargeDelay,
58 295 : const std::string& chargeType, SUMOTime waitingTime) :
59 : MSChargingStation(id, lane, frompos, topos, name, chargingPower, totalPower, efficiency, chargeInTransit, chargeDelay, chargeType, waitingTime),
60 295 : GUIGlObject_AbstractAdd(GLO_CHARGING_STATION, id, GUIIconSubSys::getIcon(GUIIcon::CHARGINGSTATION)) {
61 295 : initAppearance(lane, frompos, topos);
62 295 : }
63 :
64 :
65 5 : GUIChargingStation::GUIChargingStation(const std::string& id, MSParkingArea* parkingArea, const std::string& name,
66 : double chargingPower, double totalPower, double efficiency, bool chargeInTransit, SUMOTime chargeDelay,
67 5 : const std::string& chargeType, SUMOTime waitingTime) :
68 : MSChargingStation(id, parkingArea, name, chargingPower, totalPower, efficiency, chargeInTransit, chargeDelay, chargeType, waitingTime),
69 5 : GUIGlObject_AbstractAdd(GLO_CHARGING_STATION, id, GUIIconSubSys::getIcon(GUIIcon::CHARGINGSTATION)) {
70 5 : initAppearance(const_cast<MSLane&>(parkingArea->getLane()), parkingArea->getBeginLanePosition(), parkingArea->getEndLanePosition());
71 5 : }
72 :
73 :
74 600 : GUIChargingStation::~GUIChargingStation() {
75 600 : }
76 :
77 :
78 : GUIParameterTableWindow*
79 0 : GUIChargingStation::getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView&) {
80 : // Create table items
81 0 : GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
82 : // add items
83 0 : ret->mkItem(TL("name"), false, getMyName());
84 0 : ret->mkItem(TL("begin position [m]"), false, myBegPos);
85 0 : ret->mkItem(TL("end position [m]"), false, myEndPos);
86 0 : ret->mkItem(TL("stopped vehicles [#]"), true, new FunctionBinding<GUIChargingStation, int>(this, &MSStoppingPlace::getStoppedVehicleNumber));
87 0 : ret->mkItem(TL("last free pos [m]"), true, new FunctionBinding<GUIChargingStation, double>(this, &MSStoppingPlace::getLastFreePos));
88 0 : ret->mkItem(TL("charging power [W]"), false, myNominalChargingPower);
89 0 : ret->mkItem(TL("total charging power [W]"), false, myTotalChargingPower);
90 0 : ret->mkItem(TL("charging efficiency [#]"), false, myEfficiency);
91 0 : ret->mkItem(TL("charge in transit [true/false]"), false, myChargeInTransit);
92 0 : ret->mkItem(TL("charge delay [s]"), false, STEPS2TIME(myChargeDelay));
93 0 : ret->mkItem(TL("charge type"), false, chargeTypeToString(myChargeType));
94 0 : ret->mkItem(TL("waiting time [s]"), false, STEPS2TIME(myWaitingTime));
95 : // close building
96 0 : ret->closeBuilding();
97 0 : return ret;
98 : }
99 :
100 :
101 : GUIGLObjectPopupMenu*
102 0 : GUIChargingStation::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {
103 0 : GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
104 0 : buildPopupHeader(ret, app);
105 0 : buildCenterPopupEntry(ret);
106 0 : buildNameCopyPopupEntry(ret);
107 0 : buildSelectionPopupEntry(ret);
108 0 : buildShowParamsPopupEntry(ret);
109 0 : buildPositionCopyEntry(ret, app);
110 0 : return ret;
111 : }
112 :
113 :
114 : double
115 10026 : GUIChargingStation::getExaggeration(const GUIVisualizationSettings& s) const {
116 10026 : return s.addSize.getExaggeration(s, this);
117 : }
118 :
119 :
120 : Boundary
121 10626 : GUIChargingStation::getCenteringBoundary() const {
122 10626 : Boundary b = myFGShape.getBoxBoundary();
123 10626 : b.grow(20);
124 10626 : return b;
125 : }
126 :
127 :
128 : void
129 10026 : GUIChargingStation::drawGL(const GUIVisualizationSettings& s) const {
130 : // Draw Charging Station
131 10026 : GLHelper::pushName(getGlID());
132 10026 : GLHelper::pushMatrix();
133 :
134 : // draw the area depending if the vehicle is charging
135 10026 : glTranslated(0, 0, getType());
136 :
137 :
138 :
139 : // set color depending if charging station is charging
140 10026 : RGBColor csColor = (myChargingVehicle)? s.colorSettings.chargingStationColorCharge : s.colorSettings.chargingStationColor;
141 10026 : GLHelper::setColor(csColor);
142 :
143 10026 : const double exaggeration = getExaggeration(s);
144 :
145 10026 : if(myParkingArea != nullptr) {
146 : // draw space background with charging station colors
147 122 : const std::vector<MSParkingArea::LotSpaceDefinition>& spaces = myParkingArea->getSpaceOccupancies();
148 302 : for(const auto& space : spaces) {
149 : // draw box lines
150 180 : GLHelper::drawBoxLine(space.position, space.rotation - 180., space.length, 0.5 * space.width);
151 : }
152 :
153 : // redraw spaces from parking area
154 122 : GLHelper::pushMatrix();
155 122 : glTranslated(0, 0, .1);
156 302 : for(const auto& space : spaces) {
157 180 : GLHelper::drawSpaceOccupancies(exaggeration, space.position, space.rotation,
158 180 : space.width, space.length, space.vehicle ? true : false);
159 : }
160 122 : GLHelper::popMatrix();
161 : } else {
162 9904 : GLHelper::drawBoxLines(myFGShape, myFGShapeRotations, myFGShapeLengths, MIN2(1.0, exaggeration));
163 : }
164 :
165 : // reset color because it may have changed due to redrawing occupied spaces
166 10026 : GLHelper::setColor(csColor);
167 :
168 : // draw details unless zoomed out to far
169 10026 : if (s.drawDetail(10, exaggeration)) {
170 : // push charging power matrix
171 0 : GLHelper::pushMatrix();
172 : // translate and rotate
173 0 : const double rotSign = MSGlobals::gLefthand ? 1 : -1;
174 0 : const double lineAngle = s.getTextAngle(myFGSignRot);
175 0 : glTranslated(myFGSignPos.x(), myFGSignPos.y(), 0.2);
176 0 : glRotated(-lineAngle, 0, 0, 1);
177 : // draw charging power
178 0 : const double textOffset = s.flippedTextAngle(rotSign * myFGSignRot) ? -0.5 : -0.1;
179 0 : GLHelper::drawText((toString(myNominalChargingPower) + " W").c_str(), Position(1.2, textOffset), .1, 1.f, s.colorSettings.chargingStationColor, 0, FONS_ALIGN_LEFT);
180 : // pop charging power matrix
181 0 : GLHelper::popMatrix();
182 :
183 0 : GLHelper::pushMatrix();
184 : // draw the sign
185 0 : glTranslated(myFGSignPos.x(), myFGSignPos.y(), 0.2);
186 : int noPoints = 9;
187 0 : if (s.scale * exaggeration > 25) {
188 0 : noPoints = MIN2((int)(9.0 + (s.scale * exaggeration) / 10.0), 36);
189 : }
190 :
191 0 : glScaled(exaggeration, exaggeration, 1);
192 0 : GLHelper::drawFilledCircle((double) 1.1, noPoints);
193 0 : glTranslated(0, 0, .1);
194 :
195 0 : GLHelper::setColor(s.colorSettings.chargingStationColorSign);
196 0 : GLHelper::drawFilledCircle((double) 0.9, noPoints);
197 0 : GLHelper::drawText("C", Position(), .1, 1.6, s.colorSettings.chargingStationColor, myFGSignRot);
198 :
199 : //glTranslated(5, 0, 0);
200 0 : GLHelper::popMatrix();
201 :
202 : }
203 10026 : if (s.addFullName.show(this) && getMyName() != "") {
204 0 : GLHelper::drawTextSettings(s.addFullName, getMyName(), myFGSignPos, s.scale, s.getTextAngle(myFGSignRot), GLO_MAX - getType());
205 : }
206 10026 : GLHelper::popMatrix();
207 10026 : GLHelper::popName();
208 10026 : drawName(getCenteringBoundary().getCenter(), s.scale, s.addName, s.angle);
209 10026 : }
210 :
211 :
212 : void
213 300 : GUIChargingStation::initAppearance(MSLane& lane, double frompos, double topos) {
214 : myFGShape = lane.getShape();
215 600 : myFGShape = myFGShape.getSubpart(
216 : lane.interpolateLanePosToGeometryPos(frompos),
217 : lane.interpolateLanePosToGeometryPos(topos));
218 300 : myFGShapeRotations.reserve(myFGShape.size() - 1);
219 300 : myFGShapeLengths.reserve(myFGShape.size() - 1);
220 300 : int e = (int)myFGShape.size() - 1;
221 606 : for (int i = 0; i < e; ++i) {
222 306 : const Position& f = myFGShape[i];
223 306 : const Position& s = myFGShape[i + 1];
224 306 : myFGShapeLengths.push_back(f.distanceTo(s));
225 306 : myFGShapeRotations.push_back((double)atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double)M_PI);
226 : }
227 300 : PositionVector tmp = (myParkingArea != nullptr) ? myParkingArea->getShape() : myFGShape;
228 300 : const double rotSign = MSGlobals::gLefthand ? -1 : 1;
229 300 : const double offset = (myParkingArea != nullptr)? lane.getWidth() : 1.5;
230 300 : tmp.move2side(offset * rotSign);
231 300 : myFGSignPos = tmp.getLineCenter();
232 300 : myFGSignRot = 0;
233 300 : if (tmp.length() != 0) {
234 300 : myFGSignRot = myFGShape.rotationDegreeAtOffset(double((tmp.length() / 2.)));
235 300 : myFGSignRot -= 90 * rotSign;
236 : }
237 300 : }
238 :
239 :
240 : const std::string
241 0 : GUIChargingStation::getOptionalName() const {
242 0 : return myName;
243 : }
244 :
245 :
246 : /****************************************************************************/
|