Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 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 <microsim/MSEdge.h>
31 : #include <microsim/MSLane.h>
32 : #include <microsim/MSNet.h>
33 : #include <microsim/logging/FunctionBinding.h>
34 : #include <utils/common/MsgHandler.h>
35 : #include <utils/common/ToString.h>
36 : #include <utils/geom/Boundary.h>
37 : #include <utils/geom/GeomHelper.h>
38 : #include <utils/geom/PositionVector.h>
39 : #include <utils/gui/div/GLHelper.h>
40 : #include <utils/gui/div/GUIGlobalSelection.h>
41 : #include <utils/gui/div/GUIParameterTableWindow.h>
42 : #include <utils/gui/globjects/GLIncludes.h>
43 : #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
44 : #include <utils/gui/windows/GUIAppEnum.h>
45 :
46 : #include "GUINet.h"
47 : #include "GUIEdge.h"
48 : #include "GUIContainer.h"
49 : #include "GUIParkingArea.h"
50 :
51 :
52 : // ===========================================================================
53 : // method definitions
54 : // ===========================================================================
55 706 : GUIParkingArea::GUIParkingArea(const std::string& id, const std::vector<std::string>& lines,
56 : const std::vector<std::string>& badges, MSLane& lane, double frompos, double topos,
57 : unsigned int capacity, double width, double length, double angle, const std::string& name,
58 : bool onRoad,
59 : const std::string& departPos,
60 706 : bool lefthand) :
61 : MSParkingArea(id, lines, badges, lane, frompos, topos, capacity, width, length, angle, name, onRoad, departPos, lefthand),
62 706 : GUIGlObject_AbstractAdd(GLO_PARKING_AREA, id, GUIIconSubSys::getIcon(GUIIcon::PARKINGAREA)) {
63 706 : const double offsetSign = (MSGlobals::gLefthand || lefthand) ? -1 : 1;
64 706 : myShapeRotations.reserve(myShape.size() - 1);
65 706 : myShapeLengths.reserve(myShape.size() - 1);
66 706 : int e = (int) myShape.size() - 1;
67 1576 : for (int i = 0; i < e; ++i) {
68 870 : const Position& f = myShape[i];
69 870 : const Position& s = myShape[i + 1];
70 870 : myShapeLengths.push_back(f.distanceTo(s));
71 870 : myShapeRotations.push_back((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double) M_PI);
72 : }
73 : PositionVector tmp = myShape;
74 706 : tmp.move2side((lane.getWidth() + myWidth) * offsetSign);
75 706 : mySignPos = tmp.getLineCenter();
76 706 : mySignRot = 0;
77 706 : if (tmp.length() != 0) {
78 706 : mySignRot = myShape.rotationDegreeAtOffset(double((myShape.length() / 2.)));
79 706 : const double rotSign = MSGlobals::gLefthand ? -1 : 1;
80 706 : mySignRot -= 90 * rotSign;
81 : }
82 706 : myBoundary = myShape.getBoxBoundary();
83 706 : myBoundary.grow(20);
84 706 : }
85 :
86 1412 : GUIParkingArea::~GUIParkingArea() {}
87 :
88 :
89 : GUIGLObjectPopupMenu*
90 0 : GUIParkingArea::getPopUpMenu(GUIMainWindow& app,
91 : GUISUMOAbstractView& parent) {
92 0 : GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
93 0 : buildPopupHeader(ret, app);
94 0 : buildCenterPopupEntry(ret);
95 0 : buildNameCopyPopupEntry(ret);
96 0 : buildSelectionPopupEntry(ret);
97 0 : buildShowParamsPopupEntry(ret);
98 0 : buildPositionCopyEntry(ret, app);
99 0 : return ret;
100 : }
101 :
102 :
103 : GUIParameterTableWindow*
104 0 : GUIParkingArea::getParameterWindow(GUIMainWindow& app,
105 : GUISUMOAbstractView&) {
106 : GUIParameterTableWindow* ret =
107 0 : new GUIParameterTableWindow(app, *this);
108 : // add items
109 0 : ret->mkItem(TL("name"), false, getMyName());
110 0 : ret->mkItem(TL("begin position [m]"), false, myBegPos);
111 0 : ret->mkItem(TL("end position [m]"), false, myEndPos);
112 0 : ret->mkItem(TL("occupancy [#]"), true, getOccupancy());
113 0 : ret->mkItem(TL("capacity [#]"), false, getCapacity());
114 0 : ret->mkItem(TL("alternatives [#]"), false, getNumAlternatives());
115 0 : ret->mkItem(TL("access badges"), false, joinToString(myAcceptedBadges, " "));
116 : // close building
117 0 : ret->closeBuilding();
118 0 : return ret;
119 : }
120 :
121 :
122 : void
123 12045 : GUIParkingArea::drawGL(const GUIVisualizationSettings& s) const {
124 12045 : GLHelper::pushName(getGlID());
125 12045 : GLHelper::pushMatrix();
126 12045 : RGBColor grey(177, 184, 186, 171);
127 12045 : RGBColor blue(83, 89, 172, 255);
128 12045 : RGBColor red(255, 0, 0, 255);
129 12045 : RGBColor green(0, 255, 0, 255);
130 : // draw the area
131 12045 : glTranslated(0, 0, getType());
132 12045 : GLHelper::setColor(blue);
133 12045 : const double exaggeration = getExaggeration(s);
134 24090 : GLHelper::drawBoxLines(myShape, myShapeRotations, myShapeLengths, myWidth / 2. * MIN2(1.0, exaggeration));
135 : // draw details unless zoomed out to far
136 12045 : if (s.scale * exaggeration >= 1) {
137 : // draw the lots
138 9525 : glTranslated(0, 0, .1);
139 : // calculate shape lengt
140 : double ShapeLength = 0;
141 19207 : for (const auto& length : myShapeLengths) {
142 9682 : ShapeLength += length;
143 : }
144 : // calculate index Updater
145 9525 : int indexUpdater = (int)((double)mySpaceOccupancies.size() / ShapeLength);
146 : // check if indexUpdater is 0
147 9525 : if (indexUpdater == 0 || (myCapacity != myRoadSideCapacity)) {
148 : indexUpdater = 1;
149 : }
150 : // draw spaceOccupancies
151 26859 : for (int i = 0; i < (int)mySpaceOccupancies.size(); i += indexUpdater) {
152 17334 : GLHelper::drawSpaceOccupancies(exaggeration, mySpaceOccupancies.at(i).position, mySpaceOccupancies.at(i).rotation,
153 17334 : mySpaceOccupancies.at(i).width, mySpaceOccupancies.at(i).length, mySpaceOccupancies.at(i).vehicle ? true : false);
154 : }
155 9525 : GLHelper::setColor(blue);
156 : // draw the lines
157 9525 : for (size_t i = 0; i != myLines.size(); ++i) {
158 : // push a new matrix for every line
159 0 : GLHelper::pushMatrix();
160 : // traslate and rotate
161 0 : glTranslated(mySignPos.x(), mySignPos.y(), 0);
162 0 : glRotated(180, 1, 0, 0);
163 0 : glRotated(mySignRot, 0, 0, 1);
164 : // draw line
165 0 : GLHelper::drawText(myLines[i].c_str(), Position(1.2, (double)i), .1, 1.f, RGBColor(76, 170, 50), 0, FONS_ALIGN_LEFT);
166 : // pop matrix for every line
167 0 : GLHelper::popMatrix();
168 :
169 : }
170 : // draw the sign
171 9525 : glTranslated(mySignPos.x(), mySignPos.y(), 0);
172 : int noPoints = 9;
173 9525 : if (s.scale * exaggeration > 25) {
174 0 : noPoints = MIN2((int)(9.0 + (s.scale * exaggeration) / 10.0), 36);
175 : }
176 9525 : glScaled(exaggeration, exaggeration, 1);
177 9525 : GLHelper::drawFilledCircle((double) 1.1, noPoints);
178 9525 : glTranslated(0, 0, .1);
179 9525 : GLHelper::setColor(grey);
180 9525 : GLHelper::drawFilledCircle((double) 0.9, noPoints);
181 9525 : if (s.drawDetail(10, exaggeration)) {
182 56 : GLHelper::drawText("P", Position(), .1, 1.6, blue, mySignRot);
183 : }
184 : }
185 12045 : GLHelper::popMatrix();
186 12045 : if (s.addFullName.show(this) && getMyName() != "") {
187 0 : GLHelper::drawTextSettings(s.addFullName, getMyName(), mySignPos, s.scale, s.getTextAngle(mySignRot), GLO_MAX - getType());
188 : }
189 12045 : GLHelper::popName();
190 12045 : drawName(getCenteringBoundary().getCenter(), s.scale, s.addName, s.angle);
191 12045 : if (myCapacity != myRoadSideCapacity) {
192 : // draw parking vehicles (their lane might not be within drawing range. if it is, they are drawn twice)
193 110 : myLane.getVehiclesSecure();
194 255 : for (const MSBaseVehicle* const v : myLane.getParkingVehicles()) {
195 145 : static_cast<const GUIVehicle*>(v)->drawGL(s);
196 : }
197 110 : myLane.releaseVehicles();
198 : }
199 12045 : }
200 :
201 : void
202 79 : GUIParkingArea::addLotEntry(double x, double y, double z,
203 : double width, double length,
204 : double angle, double slope) {
205 79 : MSParkingArea::addLotEntry(x, y, z, width, length, angle, slope);
206 79 : Boundary b;
207 79 : b.add(Position(x, y));
208 79 : b.grow(MAX2(width, length) + 5);
209 79 : myBoundary.add(b);
210 79 : }
211 :
212 :
213 : double
214 12045 : GUIParkingArea::getExaggeration(const GUIVisualizationSettings& s) const {
215 12045 : return s.addSize.getExaggeration(s, this);
216 : }
217 :
218 :
219 : Boundary
220 12751 : GUIParkingArea::getCenteringBoundary() const {
221 12751 : return myBoundary;
222 : }
223 :
224 :
225 : const std::string
226 0 : GUIParkingArea::getOptionalName() const {
227 0 : return myName;
228 : }
229 :
230 :
231 : /****************************************************************************/
|