Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2026 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 GUIParkingArea.cpp
15 : /// @author Mirco Sturari
16 : /// @author Jakob Erdmann
17 : /// @author Mirko Barthauer
18 : /// @date Tue, 19.01.2016
19 : ///
20 : // A area where vehicles can park next to the road (gui version)
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #include <string>
25 : #include <foreign/fontstash/fontstash.h>
26 : #include <gui/GUIApplicationWindow.h>
27 : #include <gui/GUIGlobals.h>
28 : #include <guisim/GUIParkingArea.h>
29 : #include <guisim/GUIVehicle.h>
30 : #include <mesogui/GUIMEVehicle.h>
31 : #include <microsim/MSEdge.h>
32 : #include <microsim/MSLane.h>
33 : #include <microsim/MSNet.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 "GUIContainer.h"
50 : #include "GUIParkingArea.h"
51 :
52 :
53 : // ===========================================================================
54 : // method definitions
55 : // ===========================================================================
56 873 : GUIParkingArea::GUIParkingArea(const std::string& id, const std::vector<std::string>& lines,
57 : const std::vector<std::string>& badges, MSLane& lane, double frompos, double topos,
58 : unsigned int capacity, double width, double length, double angle, const std::string& name,
59 : bool onRoad,
60 : const std::string& departPos,
61 873 : bool lefthand, bool reservable) :
62 : MSParkingArea(id, lines, badges, lane, frompos, topos, capacity, width, length, angle, name, onRoad, departPos, lefthand, reservable),
63 873 : GUIGlObject_AbstractAdd(GLO_PARKING_AREA, id, GUIIconSubSys::getIcon(GUIIcon::PARKINGAREA)) {
64 873 : const double offsetSign = (MSGlobals::gLefthand || lefthand) ? -1 : 1;
65 873 : myShapeRotations.reserve(myShape.size() - 1);
66 873 : myShapeLengths.reserve(myShape.size() - 1);
67 873 : int e = (int) myShape.size() - 1;
68 1911 : for (int i = 0; i < e; ++i) {
69 1038 : const Position& f = myShape[i];
70 1038 : const Position& s = myShape[i + 1];
71 1038 : myShapeLengths.push_back(f.distanceTo(s));
72 1038 : myShapeRotations.push_back((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double) M_PI);
73 : }
74 : PositionVector tmp = myShape;
75 873 : tmp.move2side((lane.getWidth() + myWidth) * offsetSign);
76 873 : mySignPos = tmp.getLineCenter();
77 873 : mySignRot = 0;
78 873 : if (tmp.length() != 0) {
79 873 : mySignRot = myShape.rotationDegreeAtOffset(double((myShape.length() / 2.)));
80 873 : const double rotSign = MSGlobals::gLefthand ? -1 : 1;
81 873 : mySignRot -= 90 * rotSign;
82 : }
83 873 : myBoundary = myShape.getBoxBoundary();
84 873 : myBoundary.grow(20);
85 873 : }
86 :
87 1746 : GUIParkingArea::~GUIParkingArea() {}
88 :
89 :
90 : GUIGLObjectPopupMenu*
91 0 : GUIParkingArea::getPopUpMenu(GUIMainWindow& app,
92 : GUISUMOAbstractView& parent) {
93 0 : GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
94 0 : buildPopupHeader(ret, app);
95 0 : buildCenterPopupEntry(ret);
96 0 : buildNameCopyPopupEntry(ret);
97 0 : buildSelectionPopupEntry(ret);
98 0 : buildShowParamsPopupEntry(ret);
99 0 : buildPositionCopyEntry(ret, app);
100 0 : return ret;
101 : }
102 :
103 :
104 : GUIParameterTableWindow*
105 0 : GUIParkingArea::getParameterWindow(GUIMainWindow& app,
106 : GUISUMOAbstractView&) {
107 : GUIParameterTableWindow* ret =
108 0 : new GUIParameterTableWindow(app, *this);
109 : // add items
110 0 : ret->mkItem(TL("name"), false, getMyName());
111 0 : ret->mkItem(TL("begin position [m]"), false, myBegPos);
112 0 : ret->mkItem(TL("end position [m]"), false, myEndPos);
113 0 : ret->mkItem(TL("occupancy [#]"), true, getOccupancy());
114 0 : ret->mkItem(TL("capacity [#]"), false, getCapacity());
115 0 : ret->mkItem(TL("alternatives [#]"), false, getNumAlternatives());
116 0 : ret->mkItem(TL("access badges"), false, joinToString(myAcceptedBadges, " "));
117 0 : if (isReservable()) {
118 0 : ret->mkItem(TL("reservations [#]"), true, getNumReservations());
119 0 : ret->mkItem(TL("reservation ids"), true, getReservationString());
120 : }
121 : // close building
122 0 : ret->closeBuilding();
123 0 : return ret;
124 : }
125 :
126 :
127 : void
128 24971 : GUIParkingArea::drawGL(const GUIVisualizationSettings& s) const {
129 24971 : GLHelper::pushName(getGlID());
130 24971 : GLHelper::pushMatrix();
131 24971 : RGBColor grey(177, 184, 186, 171);
132 24971 : RGBColor blue(83, 89, 172, 255);
133 24971 : RGBColor red(255, 0, 0, 255);
134 24971 : RGBColor green(0, 255, 0, 255);
135 : // draw the area
136 24971 : glTranslated(0, 0, getType());
137 24971 : GLHelper::setColor(blue);
138 24971 : const double exaggeration = getExaggeration(s);
139 49942 : GLHelper::drawBoxLines(myShape, myShapeRotations, myShapeLengths, myWidth / 2. * MIN2(1.0, exaggeration));
140 : // draw details unless zoomed out to far
141 24971 : if (s.scale * exaggeration >= 1) {
142 : // draw the lots
143 22295 : glTranslated(0, 0, .1);
144 : // calculate shape length
145 : double ShapeLength = 0;
146 44815 : for (const auto& length : myShapeLengths) {
147 22520 : ShapeLength += length;
148 : }
149 : // calculate index Updater
150 22295 : int indexUpdater = (int)((double)mySpaceOccupancies.size() / ShapeLength);
151 : // check if indexUpdater is 0
152 22295 : if (indexUpdater == 0 || (myCapacity != myRoadSideCapacity)) {
153 : indexUpdater = 1;
154 : }
155 : // draw spaceOccupancies
156 73362 : for (int i = 0; i < (int)mySpaceOccupancies.size(); i += indexUpdater) {
157 51067 : GLHelper::drawSpaceOccupancies(exaggeration, mySpaceOccupancies.at(i).position, mySpaceOccupancies.at(i).rotation,
158 51067 : mySpaceOccupancies.at(i).width, mySpaceOccupancies.at(i).length, mySpaceOccupancies.at(i).vehicle ? true : false);
159 : }
160 22295 : GLHelper::setColor(blue);
161 : // draw the lines
162 22295 : for (size_t i = 0; i != myLines.size(); ++i) {
163 : // push a new matrix for every line
164 0 : GLHelper::pushMatrix();
165 : // traslate and rotate
166 0 : glTranslated(mySignPos.x(), mySignPos.y(), 0);
167 0 : glRotated(180, 1, 0, 0);
168 0 : glRotated(mySignRot, 0, 0, 1);
169 : // draw line
170 0 : GLHelper::drawText(myLines[i].c_str(), Position(1.2, (double)i), .1, 1.f, RGBColor(76, 170, 50), 0, FONS_ALIGN_LEFT);
171 : // pop matrix for every line
172 0 : GLHelper::popMatrix();
173 :
174 : }
175 : // draw the sign
176 22295 : glTranslated(mySignPos.x(), mySignPos.y(), 0);
177 : int noPoints = 9;
178 22295 : if (s.scale * exaggeration > 25) {
179 0 : noPoints = MIN2((int)(9.0 + (s.scale * exaggeration) / 10.0), 36);
180 : }
181 22295 : glScaled(exaggeration, exaggeration, 1);
182 22295 : GLHelper::drawFilledCircle((double) 1.1, noPoints);
183 22295 : glTranslated(0, 0, .1);
184 22295 : GLHelper::setColor(grey);
185 22295 : GLHelper::drawFilledCircle((double) 0.9, noPoints);
186 22295 : if (s.drawDetail(10, exaggeration)) {
187 68 : GLHelper::drawText("P", Position(), .1, 1.6, blue, mySignRot);
188 : }
189 : }
190 24971 : GLHelper::popMatrix();
191 24971 : if (s.addFullName.show(this) && getMyName() != "") {
192 0 : GLHelper::drawTextSettings(s.addFullName, getMyName(), mySignPos, s.scale, s.getTextAngle(mySignRot), GLO_MAX - getType());
193 : }
194 24971 : GLHelper::popName();
195 24971 : drawName(getCenteringBoundary().getCenter(), s.scale, s.addName, s.angle);
196 24971 : if (myCapacity != myRoadSideCapacity) {
197 : // draw parking vehicles (their lane might not be within drawing range. if it is, they are drawn twice)
198 229 : myLane.getVehiclesSecure();
199 403 : for (const MSBaseVehicle* const v : myLane.getParkingVehicles()) {
200 174 : if (MSGlobals::gUseMesoSim) {
201 6 : static_cast<const GUIMEVehicle*>(v)->drawGL(s);
202 : } else {
203 168 : static_cast<const GUIVehicle*>(v)->drawGL(s);
204 : }
205 : }
206 229 : myLane.releaseVehicles();
207 : }
208 24971 : }
209 :
210 : void
211 95 : GUIParkingArea::addLotEntry(double x, double y, double z,
212 : double width, double length,
213 : double angle, double slope) {
214 95 : MSParkingArea::addLotEntry(x, y, z, width, length, angle, slope);
215 95 : Boundary b;
216 95 : b.add(Position(x, y));
217 95 : b.grow(MAX2(width, length) + 5);
218 95 : myBoundary.add(b);
219 95 : }
220 :
221 :
222 : double
223 24971 : GUIParkingArea::getExaggeration(const GUIVisualizationSettings& s) const {
224 24971 : return s.addSize.getExaggeration(s, this);
225 : }
226 :
227 :
228 : Boundary
229 25844 : GUIParkingArea::getCenteringBoundary() const {
230 25844 : return myBoundary;
231 : }
232 :
233 :
234 : const std::string
235 0 : GUIParkingArea::getOptionalName() const {
236 0 : return myName;
237 : }
238 :
239 : int
240 0 : GUIParkingArea::getNumReservations() const {
241 0 : return (int)getRemoteReservedVehicles().size();
242 : }
243 :
244 : const std::string
245 0 : GUIParkingArea::getReservationString() const {
246 0 : return toString(getRemoteReservedVehicles());
247 : }
248 :
249 : /****************************************************************************/
|