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 293 : GUIChargingStation::GUIChargingStation(const std::string& id, MSLane& lane, double frompos, double topos, const std::string& name,
57 : double chargingPower, double efficiency, bool chargeInTransit, SUMOTime chargeDelay,
58 293 : const std::string& chargeType, SUMOTime waitingTime) :
59 : MSChargingStation(id, lane, frompos, topos, name, chargingPower, efficiency, chargeInTransit, chargeDelay, chargeType, waitingTime),
60 293 : GUIGlObject_AbstractAdd(GLO_CHARGING_STATION, id, GUIIconSubSys::getIcon(GUIIcon::CHARGINGSTATION)) {
61 293 : initAppearance(lane, frompos, topos);
62 293 : }
63 :
64 :
65 3 : GUIChargingStation::GUIChargingStation(const std::string& id, MSParkingArea* parkingArea, const std::string& name,
66 : double chargingPower, double efficiency, bool chargeInTransit, SUMOTime chargeDelay,
67 3 : const std::string& chargeType, SUMOTime waitingTime) :
68 : MSChargingStation(id, parkingArea, name, chargingPower, efficiency, chargeInTransit, chargeDelay, chargeType, waitingTime),
69 3 : GUIGlObject_AbstractAdd(GLO_CHARGING_STATION, id, GUIIconSubSys::getIcon(GUIIcon::CHARGINGSTATION)) {
70 3 : initAppearance(const_cast<MSLane&>(parkingArea->getLane()), parkingArea->getBeginLanePosition(), parkingArea->getEndLanePosition());
71 3 : }
72 :
73 :
74 592 : GUIChargingStation::~GUIChargingStation() {
75 592 : }
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, myChargingPower);
89 0 : ret->mkItem(TL("charging efficiency [#]"), false, myEfficiency);
90 0 : ret->mkItem(TL("charge in transit [true/false]"), false, myChargeInTransit);
91 0 : ret->mkItem(TL("charge delay [s]"), false, STEPS2TIME(myChargeDelay));
92 0 : ret->mkItem(TL("charge type"), false, chargeTypeToString(myChargeType));
93 0 : ret->mkItem(TL("waiting time [s]"), false, STEPS2TIME(myWaitingTime));
94 : // close building
95 0 : ret->closeBuilding();
96 0 : return ret;
97 : }
98 :
99 :
100 : GUIGLObjectPopupMenu*
101 0 : GUIChargingStation::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {
102 0 : GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
103 0 : buildPopupHeader(ret, app);
104 0 : buildCenterPopupEntry(ret);
105 0 : buildNameCopyPopupEntry(ret);
106 0 : buildSelectionPopupEntry(ret);
107 0 : buildShowParamsPopupEntry(ret);
108 0 : buildPositionCopyEntry(ret, app);
109 0 : return ret;
110 : }
111 :
112 :
113 : double
114 7094 : GUIChargingStation::getExaggeration(const GUIVisualizationSettings& s) const {
115 7094 : return s.addSize.getExaggeration(s, this);
116 : }
117 :
118 :
119 : Boundary
120 7686 : GUIChargingStation::getCenteringBoundary() const {
121 7686 : Boundary b = myFGShape.getBoxBoundary();
122 7686 : b.grow(20);
123 7686 : return b;
124 : }
125 :
126 :
127 : void
128 7094 : GUIChargingStation::drawGL(const GUIVisualizationSettings& s) const {
129 : // Draw Charging Station
130 7094 : GLHelper::pushName(getGlID());
131 7094 : GLHelper::pushMatrix();
132 :
133 : // draw the area depending if the vehicle is charging
134 7094 : glTranslated(0, 0, getType());
135 :
136 :
137 :
138 : // set color depending if charging station is charging
139 7094 : RGBColor csColor = (myChargingVehicle)? s.colorSettings.chargingStationColorCharge : s.colorSettings.chargingStationColor;
140 7094 : GLHelper::setColor(csColor);
141 :
142 7094 : const double exaggeration = getExaggeration(s);
143 :
144 7094 : if(myParkingArea != nullptr) {
145 : // draw space background with charging station colors
146 32 : const std::vector<MSParkingArea::LotSpaceDefinition>& spaces = myParkingArea->getSpaceOccupancies();
147 70 : for(const auto& space : spaces) {
148 : // draw box lines
149 38 : GLHelper::drawBoxLine(space.position, space.rotation - 180., space.length, 0.5 * space.width);
150 : }
151 :
152 : // redraw spaces from parking area
153 32 : GLHelper::pushMatrix();
154 32 : glTranslated(0, 0, .1);
155 70 : for(const auto& space : spaces) {
156 38 : GLHelper::drawSpaceOccupancies(exaggeration, space.position, space.rotation,
157 38 : space.width, space.length, space.vehicle ? true : false);
158 : }
159 32 : GLHelper::popMatrix();
160 : } else {
161 7062 : GLHelper::drawBoxLines(myFGShape, myFGShapeRotations, myFGShapeLengths, MIN2(1.0, exaggeration));
162 : }
163 :
164 : // reset color because it may have changed due to redrawing occupied spaces
165 7094 : GLHelper::setColor(csColor);
166 :
167 : // draw details unless zoomed out to far
168 7094 : if (s.drawDetail(10, exaggeration)) {
169 : // push charging power matrix
170 0 : GLHelper::pushMatrix();
171 : // translate and rotate
172 0 : const double rotSign = MSGlobals::gLefthand ? 1 : -1;
173 0 : const double lineAngle = s.getTextAngle(myFGSignRot);
174 0 : glTranslated(myFGSignPos.x(), myFGSignPos.y(), 0.2);
175 0 : glRotated(-lineAngle, 0, 0, 1);
176 : // draw charging power
177 0 : const double textOffset = s.flippedTextAngle(rotSign * myFGSignRot) ? -0.5 : -0.1;
178 0 : GLHelper::drawText((toString(myChargingPower) + " W").c_str(), Position(1.2, textOffset), .1, 1.f, s.colorSettings.chargingStationColor, 0, FONS_ALIGN_LEFT);
179 : // pop charging power matrix
180 0 : GLHelper::popMatrix();
181 :
182 0 : GLHelper::pushMatrix();
183 : // draw the sign
184 0 : glTranslated(myFGSignPos.x(), myFGSignPos.y(), 0.2);
185 : int noPoints = 9;
186 0 : if (s.scale * exaggeration > 25) {
187 0 : noPoints = MIN2((int)(9.0 + (s.scale * exaggeration) / 10.0), 36);
188 : }
189 :
190 0 : glScaled(exaggeration, exaggeration, 1);
191 0 : GLHelper::drawFilledCircle((double) 1.1, noPoints);
192 0 : glTranslated(0, 0, .1);
193 :
194 0 : GLHelper::setColor(s.colorSettings.chargingStationColorSign);
195 0 : GLHelper::drawFilledCircle((double) 0.9, noPoints);
196 0 : GLHelper::drawText("C", Position(), .1, 1.6, s.colorSettings.chargingStationColor, myFGSignRot);
197 :
198 : //glTranslated(5, 0, 0);
199 0 : GLHelper::popMatrix();
200 :
201 : }
202 7094 : if (s.addFullName.show(this) && getMyName() != "") {
203 0 : GLHelper::drawTextSettings(s.addFullName, getMyName(), myFGSignPos, s.scale, s.getTextAngle(myFGSignRot), GLO_MAX - getType());
204 : }
205 7094 : GLHelper::popMatrix();
206 7094 : GLHelper::popName();
207 7094 : drawName(getCenteringBoundary().getCenter(), s.scale, s.addName, s.angle);
208 7094 : }
209 :
210 :
211 : void
212 296 : GUIChargingStation::initAppearance(MSLane& lane, double frompos, double topos) {
213 : myFGShape = lane.getShape();
214 592 : myFGShape = myFGShape.getSubpart(
215 : lane.interpolateLanePosToGeometryPos(frompos),
216 : lane.interpolateLanePosToGeometryPos(topos));
217 296 : myFGShapeRotations.reserve(myFGShape.size() - 1);
218 296 : myFGShapeLengths.reserve(myFGShape.size() - 1);
219 296 : int e = (int)myFGShape.size() - 1;
220 598 : for (int i = 0; i < e; ++i) {
221 302 : const Position& f = myFGShape[i];
222 302 : const Position& s = myFGShape[i + 1];
223 302 : myFGShapeLengths.push_back(f.distanceTo(s));
224 302 : myFGShapeRotations.push_back((double)atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double)M_PI);
225 : }
226 296 : PositionVector tmp = (myParkingArea != nullptr) ? myParkingArea->getShape() : myFGShape;
227 296 : const double rotSign = MSGlobals::gLefthand ? -1 : 1;
228 296 : const double offset = (myParkingArea != nullptr)? lane.getWidth() : 1.5;
229 296 : tmp.move2side(offset * rotSign);
230 296 : myFGSignPos = tmp.getLineCenter();
231 296 : myFGSignRot = 0;
232 296 : if (tmp.length() != 0) {
233 296 : myFGSignRot = myFGShape.rotationDegreeAtOffset(double((tmp.length() / 2.)));
234 296 : myFGSignRot -= 90 * rotSign;
235 : }
236 296 : }
237 :
238 :
239 : const std::string
240 0 : GUIChargingStation::getOptionalName() const {
241 0 : return myName;
242 : }
243 :
244 :
245 : /****************************************************************************/
|