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 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 849 : 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 849 : bool lefthand) :
62 : MSParkingArea(id, lines, badges, lane, frompos, topos, capacity, width, length, angle, name, onRoad, departPos, lefthand),
63 849 : GUIGlObject_AbstractAdd(GLO_PARKING_AREA, id, GUIIconSubSys::getIcon(GUIIcon::PARKINGAREA)) {
64 849 : const double offsetSign = (MSGlobals::gLefthand || lefthand) ? -1 : 1;
65 849 : myShapeRotations.reserve(myShape.size() - 1);
66 849 : myShapeLengths.reserve(myShape.size() - 1);
67 849 : int e = (int) myShape.size() - 1;
68 1862 : for (int i = 0; i < e; ++i) {
69 1013 : const Position& f = myShape[i];
70 1013 : const Position& s = myShape[i + 1];
71 1013 : myShapeLengths.push_back(f.distanceTo(s));
72 1013 : 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 849 : tmp.move2side((lane.getWidth() + myWidth) * offsetSign);
76 849 : mySignPos = tmp.getLineCenter();
77 849 : mySignRot = 0;
78 849 : if (tmp.length() != 0) {
79 849 : mySignRot = myShape.rotationDegreeAtOffset(double((myShape.length() / 2.)));
80 849 : const double rotSign = MSGlobals::gLefthand ? -1 : 1;
81 849 : mySignRot -= 90 * rotSign;
82 : }
83 849 : myBoundary = myShape.getBoxBoundary();
84 849 : myBoundary.grow(20);
85 849 : }
86 :
87 1698 : 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 : // close building
118 0 : ret->closeBuilding();
119 0 : return ret;
120 : }
121 :
122 :
123 : void
124 19132 : GUIParkingArea::drawGL(const GUIVisualizationSettings& s) const {
125 19132 : GLHelper::pushName(getGlID());
126 19132 : GLHelper::pushMatrix();
127 19132 : RGBColor grey(177, 184, 186, 171);
128 19132 : RGBColor blue(83, 89, 172, 255);
129 19132 : RGBColor red(255, 0, 0, 255);
130 19132 : RGBColor green(0, 255, 0, 255);
131 : // draw the area
132 19132 : glTranslated(0, 0, getType());
133 19132 : GLHelper::setColor(blue);
134 19132 : const double exaggeration = getExaggeration(s);
135 38264 : GLHelper::drawBoxLines(myShape, myShapeRotations, myShapeLengths, myWidth / 2. * MIN2(1.0, exaggeration));
136 : // draw details unless zoomed out to far
137 19132 : if (s.scale * exaggeration >= 1) {
138 : // draw the lots
139 17725 : glTranslated(0, 0, .1);
140 : // calculate shape length
141 : double ShapeLength = 0;
142 35650 : for (const auto& length : myShapeLengths) {
143 17925 : ShapeLength += length;
144 : }
145 : // calculate index Updater
146 17725 : int indexUpdater = (int)((double)mySpaceOccupancies.size() / ShapeLength);
147 : // check if indexUpdater is 0
148 17725 : if (indexUpdater == 0 || (myCapacity != myRoadSideCapacity)) {
149 : indexUpdater = 1;
150 : }
151 : // draw spaceOccupancies
152 56413 : for (int i = 0; i < (int)mySpaceOccupancies.size(); i += indexUpdater) {
153 38688 : GLHelper::drawSpaceOccupancies(exaggeration, mySpaceOccupancies.at(i).position, mySpaceOccupancies.at(i).rotation,
154 38688 : mySpaceOccupancies.at(i).width, mySpaceOccupancies.at(i).length, mySpaceOccupancies.at(i).vehicle ? true : false);
155 : }
156 17725 : GLHelper::setColor(blue);
157 : // draw the lines
158 17725 : for (size_t i = 0; i != myLines.size(); ++i) {
159 : // push a new matrix for every line
160 0 : GLHelper::pushMatrix();
161 : // traslate and rotate
162 0 : glTranslated(mySignPos.x(), mySignPos.y(), 0);
163 0 : glRotated(180, 1, 0, 0);
164 0 : glRotated(mySignRot, 0, 0, 1);
165 : // draw line
166 0 : GLHelper::drawText(myLines[i].c_str(), Position(1.2, (double)i), .1, 1.f, RGBColor(76, 170, 50), 0, FONS_ALIGN_LEFT);
167 : // pop matrix for every line
168 0 : GLHelper::popMatrix();
169 :
170 : }
171 : // draw the sign
172 17725 : glTranslated(mySignPos.x(), mySignPos.y(), 0);
173 : int noPoints = 9;
174 17725 : if (s.scale * exaggeration > 25) {
175 0 : noPoints = MIN2((int)(9.0 + (s.scale * exaggeration) / 10.0), 36);
176 : }
177 17725 : glScaled(exaggeration, exaggeration, 1);
178 17725 : GLHelper::drawFilledCircle((double) 1.1, noPoints);
179 17725 : glTranslated(0, 0, .1);
180 17725 : GLHelper::setColor(grey);
181 17725 : GLHelper::drawFilledCircle((double) 0.9, noPoints);
182 17725 : if (s.drawDetail(10, exaggeration)) {
183 88 : GLHelper::drawText("P", Position(), .1, 1.6, blue, mySignRot);
184 : }
185 : }
186 19132 : GLHelper::popMatrix();
187 19132 : if (s.addFullName.show(this) && getMyName() != "") {
188 0 : GLHelper::drawTextSettings(s.addFullName, getMyName(), mySignPos, s.scale, s.getTextAngle(mySignRot), GLO_MAX - getType());
189 : }
190 19132 : GLHelper::popName();
191 19132 : drawName(getCenteringBoundary().getCenter(), s.scale, s.addName, s.angle);
192 19132 : if (myCapacity != myRoadSideCapacity) {
193 : // draw parking vehicles (their lane might not be within drawing range. if it is, they are drawn twice)
194 189 : myLane.getVehiclesSecure();
195 431 : for (const MSBaseVehicle* const v : myLane.getParkingVehicles()) {
196 242 : if (MSGlobals::gUseMesoSim) {
197 5 : static_cast<const GUIMEVehicle*>(v)->drawGL(s);
198 : } else {
199 237 : static_cast<const GUIVehicle*>(v)->drawGL(s);
200 : }
201 : }
202 189 : myLane.releaseVehicles();
203 : }
204 19132 : }
205 :
206 : void
207 91 : GUIParkingArea::addLotEntry(double x, double y, double z,
208 : double width, double length,
209 : double angle, double slope) {
210 91 : MSParkingArea::addLotEntry(x, y, z, width, length, angle, slope);
211 91 : Boundary b;
212 91 : b.add(Position(x, y));
213 91 : b.grow(MAX2(width, length) + 5);
214 91 : myBoundary.add(b);
215 91 : }
216 :
217 :
218 : double
219 19132 : GUIParkingArea::getExaggeration(const GUIVisualizationSettings& s) const {
220 19132 : return s.addSize.getExaggeration(s, this);
221 : }
222 :
223 :
224 : Boundary
225 19981 : GUIParkingArea::getCenteringBoundary() const {
226 19981 : return myBoundary;
227 : }
228 :
229 :
230 : const std::string
231 0 : GUIParkingArea::getOptionalName() const {
232 0 : return myName;
233 : }
234 :
235 :
236 : /****************************************************************************/
|