1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file    GUIParkingArea.cpp
11 /// @author  Mirco Sturari
12 /// @author  Jakob Erdmann
13 /// @date    Tue, 19.01.2016
14 /// @version $Id$
15 ///
16 // A area where vehicles can park next to the road (gui version)
17 /****************************************************************************/
18 
19 
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #include <config.h>
24 
25 #include <string>
26 #include <utils/common/MsgHandler.h>
27 #include <utils/geom/PositionVector.h>
28 #include <utils/geom/Boundary.h>
29 #include <utils/gui/div/GLHelper.h>
30 #include <utils/common/ToString.h>
31 #include <microsim/MSNet.h>
32 #include <microsim/MSLane.h>
33 #include <microsim/MSEdge.h>
34 #include "GUINet.h"
35 #include "GUIEdge.h"
36 #include "GUIContainer.h"
37 #include "GUIParkingArea.h"
38 #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
39 #include <utils/gui/windows/GUIAppEnum.h>
40 #include <gui/GUIGlobals.h>
41 #include <utils/gui/div/GUIParameterTableWindow.h>
42 #include <gui/GUIApplicationWindow.h>
43 #include <microsim/logging/FunctionBinding.h>
44 #include <utils/gui/div/GUIGlobalSelection.h>
45 #include <utils/geom/GeomHelper.h>
46 #include <guisim/GUIParkingArea.h>
47 #include <guisim/GUIVehicle.h>
48 #include <utils/gui/globjects/GLIncludes.h>
49 #include <foreign/fontstash/fontstash.h>
50 
51 
52 
53 // ===========================================================================
54 // method definitions
55 // ===========================================================================
GUIParkingArea(const std::string & id,const std::vector<std::string> & lines,MSLane & lane,double frompos,double topos,unsigned int capacity,double width,double length,double angle,const std::string & name,bool onRoad)56 GUIParkingArea::GUIParkingArea(const std::string& id, const std::vector<std::string>& lines, MSLane& lane,
57                                double frompos, double topos, unsigned int capacity,
58                                double width, double length, double angle, const std::string& name,
59                                bool onRoad) :
60     MSParkingArea(id, lines, lane, frompos, topos, capacity, width, length, angle, name, onRoad),
61     GUIGlObject_AbstractAdd(GLO_PARKING_AREA, id) {
62     const double offsetSign = MSNet::getInstance()->lefthand() ? -1 : 1;
63     myShapeRotations.reserve(myShape.size() - 1);
64     myShapeLengths.reserve(myShape.size() - 1);
65     int e = (int) myShape.size() - 1;
66     for (int i = 0; i < e; ++i) {
67         const Position& f = myShape[i];
68         const Position& s = myShape[i + 1];
69         myShapeLengths.push_back(f.distanceTo(s));
70         myShapeRotations.push_back((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double) M_PI);
71     }
72     PositionVector tmp = myShape;
73     tmp.move2side((lane.getWidth() + myWidth) * offsetSign);
74     mySignPos = tmp.getLineCenter();
75     mySignRot = 0;
76     if (tmp.length() != 0) {
77         mySignRot = myShape.rotationDegreeAtOffset(double((myShape.length() / 2.)));
78         mySignRot -= 90;
79     }
80     myBoundary = myShape.getBoxBoundary();
81     myBoundary.grow(20);
82 }
83 
~GUIParkingArea()84 GUIParkingArea::~GUIParkingArea() {}
85 
86 
87 GUIGLObjectPopupMenu*
getPopUpMenu(GUIMainWindow & app,GUISUMOAbstractView & parent)88 GUIParkingArea::getPopUpMenu(GUIMainWindow& app,
89                              GUISUMOAbstractView& parent) {
90     GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
91     buildPopupHeader(ret, app);
92     buildCenterPopupEntry(ret);
93     buildNameCopyPopupEntry(ret);
94     buildSelectionPopupEntry(ret);
95     buildShowParamsPopupEntry(ret);
96     buildPositionCopyEntry(ret, false);
97     return ret;
98 }
99 
100 
101 GUIParameterTableWindow*
getParameterWindow(GUIMainWindow & app,GUISUMOAbstractView &)102 GUIParkingArea::getParameterWindow(GUIMainWindow& app,
103                                    GUISUMOAbstractView&) {
104     GUIParameterTableWindow* ret =
105         new GUIParameterTableWindow(app, *this, 5);
106     // add items
107     ret->mkItem("name", false, getMyName());
108     ret->mkItem("begin position [m]", false, myBegPos);
109     ret->mkItem("end position [m]", false, myEndPos);
110     ret->mkItem("occupancy [#]", true, getOccupancy());
111     ret->mkItem("capacity [#]", false, getCapacity());
112     // close building
113     ret->closeBuilding();
114     return ret;
115 }
116 
117 
118 void
drawGL(const GUIVisualizationSettings & s) const119 GUIParkingArea::drawGL(const GUIVisualizationSettings& s) const {
120     glPushName(getGlID());
121     glPushMatrix();
122     RGBColor grey(177, 184, 186, 171);
123     RGBColor blue(83, 89, 172, 255);
124     RGBColor red(255, 0, 0, 255);
125     RGBColor green(0, 255, 0, 255);
126     // draw the area
127     glTranslated(0, 0, getType());
128     GLHelper::setColor(blue);
129     GLHelper::drawBoxLines(myShape, myShapeRotations, myShapeLengths, myWidth / 2.);
130     // draw details unless zoomed out to far
131     const double exaggeration = s.addSize.getExaggeration(s, this);
132     if (s.scale * exaggeration >= 1) {
133         // draw the lots
134         glTranslated(0, 0, .1);
135         for (const auto& lsd : mySpaceOccupancies) {
136             glPushMatrix();
137             glTranslated(lsd.myPosition.x(), lsd.myPosition.y(), lsd.myPosition.z());
138             glRotated(lsd.myRotation, 0, 0, 1);
139             Position pos = lsd.myPosition;
140             PositionVector geom;
141             double w = lsd.myWidth / 2. - 0.1 * exaggeration;
142             double h = lsd.myLength;
143             geom.push_back(Position(- w, + 0, 0.));
144             geom.push_back(Position(+ w, + 0, 0.));
145             geom.push_back(Position(+ w, + h, 0.));
146             geom.push_back(Position(- w, + h, 0.));
147             geom.push_back(Position(- w, + 0, 0.));
148             /*
149             geom.push_back(Position(pos.x(), pos.y(), pos.z()));
150             geom.push_back(Position(pos.x() + (*l).second.myWidth, pos.y(), pos.z()));
151             geom.push_back(Position(pos.x() + (*l).second.myWidth, pos.y() - (*l).second.myLength, pos.z()));
152             geom.push_back(Position(pos.x(), pos.y() - (*l).second.myLength, pos.z()));
153             geom.push_back(Position(pos.x(), pos.y(), pos.z()));
154             */
155             GLHelper::setColor(lsd.vehicle == nullptr ? green : red);
156             GLHelper::drawBoxLines(geom, 0.1 * exaggeration);
157             glPopMatrix();
158         }
159         GLHelper::setColor(blue);
160         // draw the lines
161         for (size_t i = 0; i != myLines.size(); ++i) {
162             // push a new matrix for every line
163             glPushMatrix();
164             // traslate and rotate
165             glTranslated(mySignPos.x(), mySignPos.y(), 0);
166             glRotated(180, 1, 0, 0);
167             glRotated(mySignRot, 0, 0, 1);
168             // draw line
169             GLHelper::drawText(myLines[i].c_str(), Position(1.2, (double)i), .1, 1.f, RGBColor(76, 170, 50), 0, FONS_ALIGN_LEFT);
170             // pop matrix for every line
171             glPopMatrix();
172 
173         }
174         // draw the sign
175         glTranslated(mySignPos.x(), mySignPos.y(), 0);
176         int noPoints = 9;
177         if (s.scale * exaggeration > 25) {
178             noPoints = MIN2((int)(9.0 + (s.scale * exaggeration) / 10.0), 36);
179         }
180         glScaled(exaggeration, exaggeration, 1);
181         GLHelper::drawFilledCircle((double) 1.1, noPoints);
182         glTranslated(0, 0, .1);
183         GLHelper::setColor(grey);
184         GLHelper::drawFilledCircle((double) 0.9, noPoints);
185         if (s.scale * exaggeration >= 4.5) {
186             GLHelper::drawText("P", Position(), .1, 1.6, blue, mySignRot);
187         }
188     }
189     glPopMatrix();
190     if (s.addFullName.show && getMyName() != "") {
191         GLHelper::drawTextSettings(s.addFullName, getMyName(), mySignPos, s.scale, s.getTextAngle(mySignRot), GLO_MAX - getType());
192     }
193     glPopName();
194     drawName(getCenteringBoundary().getCenter(), s.scale, s.addName, s.angle);
195     // draw parking vehicles (their lane might not be within drawing range. if it is, they are drawn twice)
196     myLane.getVehiclesSecure();
197     for (std::set<const MSVehicle*>::const_iterator v = myLane.getParkingVehicles().begin(); v != myLane.getParkingVehicles().end(); ++v) {
198         static_cast<const GUIVehicle* const>(*v)->drawGL(s);
199     }
200     myLane.releaseVehicles();
201 
202 }
203 
204 void
addLotEntry(double x,double y,double z,double width,double length,double angle)205 GUIParkingArea::addLotEntry(double x, double y, double z,
206                             double width, double length, double angle) {
207     MSParkingArea::addLotEntry(x, y, z, width, length, angle);
208     Boundary b;
209     b.add(Position(x, y));
210     b.grow(MAX2(width, length) + 5);
211     myBoundary.add(b);
212 }
213 
214 Boundary
getCenteringBoundary() const215 GUIParkingArea::getCenteringBoundary() const {
216     return myBoundary;
217 }
218 
219 
220 const std::string
getOptionalName() const221 GUIParkingArea::getOptionalName() const {
222     return myName;
223 }
224 
225 /****************************************************************************/
226 
227