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 GUIE2Collector.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @author Laura Bieker
19 : /// @date Okt 2003
20 : ///
21 : // The gui-version of the MSE2Collector
22 : /****************************************************************************/
23 : #include <config.h>
24 :
25 : #include <utils/common/MsgHandler.h>
26 : #include <utils/gui/globjects/GUIGlObject.h>
27 : #include <utils/geom/PositionVector.h>
28 : #include "GUIE2Collector.h"
29 : #include <utils/gui/div/GLHelper.h>
30 : #include <utils/geom/GeomHelper.h>
31 : #include <utils/gui/div/GUIParameterTableWindow.h>
32 : #include <microsim/logging/FunctionBinding.h>
33 : #include "GUIEdge.h"
34 : #include <utils/gui/globjects/GLIncludes.h>
35 :
36 :
37 : // ===========================================================================
38 : // method definitions
39 : // ===========================================================================
40 : /* -------------------------------------------------------------------------
41 : * GUIE2Collector-methods
42 : * ----------------------------------------------------------------------- */
43 234 : GUIE2Collector::GUIE2Collector(const std::string& id, DetectorUsage usage,
44 : MSLane* lane, double startPos, double endPos, double detLength,
45 : SUMOTime haltingTimeThreshold, double haltingSpeedThreshold,
46 : double jamDistThreshold,
47 : const std::string name, const std::string& vTypes,
48 : const std::string& nextEdges,
49 234 : int detectPersons, bool showDetector)
50 : : MSE2Collector(id, usage, lane, startPos, endPos, detLength, haltingTimeThreshold,
51 : haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons),
52 468 : myShow(showDetector) {}
53 :
54 6 : GUIE2Collector::GUIE2Collector(const std::string& id, DetectorUsage usage,
55 : std::vector<MSLane*> lanes, double startPos, double endPos,
56 : SUMOTime haltingTimeThreshold, double haltingSpeedThreshold,
57 : double jamDistThreshold,
58 : const std::string name, const std::string& vTypes,
59 : const std::string& nextEdges,
60 6 : int detectPersons, bool showDetector)
61 : : MSE2Collector(id, usage, lanes, startPos, endPos, haltingTimeThreshold,
62 : haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons),
63 7 : myShow(showDetector) {}
64 :
65 478 : GUIE2Collector::~GUIE2Collector() {}
66 :
67 :
68 : GUIDetectorWrapper*
69 221 : GUIE2Collector::buildDetectorGUIRepresentation() {
70 221 : return new MyWrapper(*this);
71 : }
72 :
73 : // -------------------------------------------------------------------------
74 : // GUIE2Collector::MyWrapper-methods
75 : // -------------------------------------------------------------------------
76 :
77 221 : GUIE2Collector::MyWrapper::MyWrapper(GUIE2Collector& detector) :
78 : GUIDetectorWrapper(GLO_E2DETECTOR, detector.getID(), GUIIconSubSys::getIcon(GUIIcon::E2)),
79 221 : myDetector(detector) {
80 221 : mySupportsOverride = true;
81 : // collect detector shape into one vector (v)
82 221 : const std::vector<MSLane*> lanes = detector.getLanes();
83 500528 : for (std::vector<MSLane*>::const_iterator li = lanes.begin(); li != lanes.end(); ++li) {
84 500307 : PositionVector shape = (*li)->getShape();
85 500307 : double start = (li == lanes.begin() ? lanes.front()->interpolateLanePosToGeometryPos(detector.getStartPos()) : 0);
86 500307 : double end = (li + 1 == lanes.end() ? lanes.back()->interpolateLanePosToGeometryPos(detector.getEndPos()) : shape.length());
87 1000614 : shape = shape.getSubpart(start, end);
88 500307 : myFullGeometry.insert(myFullGeometry.end(), shape.begin(), shape.end());
89 500307 : }
90 : //
91 221 : myShapeRotations.reserve(myFullGeometry.size() - 1);
92 221 : myShapeLengths.reserve(myFullGeometry.size() - 1);
93 221 : int e = (int) myFullGeometry.size() - 1;
94 1000659 : for (int i = 0; i < e; ++i) {
95 1000438 : const Position& f = myFullGeometry[i];
96 1000438 : const Position& s = myFullGeometry[i + 1];
97 1000438 : myShapeLengths.push_back(f.distanceTo(s));
98 1000438 : myShapeRotations.push_back((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double) M_PI);
99 : }
100 : //
101 221 : myBoundary = myFullGeometry.getBoxBoundary();
102 221 : }
103 :
104 :
105 442 : GUIE2Collector::MyWrapper::~MyWrapper() {}
106 :
107 :
108 : double
109 5795 : GUIE2Collector::MyWrapper::getExaggeration(const GUIVisualizationSettings& s) const {
110 5795 : return s.addSize.getExaggeration(s, this);
111 : }
112 :
113 :
114 : Boundary
115 6016 : GUIE2Collector::MyWrapper::getCenteringBoundary() const {
116 : Boundary b(myBoundary);
117 6016 : b.grow(20);
118 6016 : return b;
119 0 : }
120 :
121 :
122 : GUIParameterTableWindow*
123 0 : GUIE2Collector::MyWrapper::getParameterWindow(GUIMainWindow& app,
124 : GUISUMOAbstractView&) {
125 : GUIParameterTableWindow* ret =
126 0 : new GUIParameterTableWindow(app, *this);
127 : // add items
128 : // parameter
129 0 : ret->mkItem(TL("name"), false, myDetector.getName());
130 0 : ret->mkItem(TL("length [m]"), false, myDetector.getLength());
131 0 : ret->mkItem(TL("position [m]"), false, myDetector.getStartPos());
132 0 : ret->mkItem(TL("lane"), false, myDetector.getLane()->getID());
133 0 : if (myDetector.isTyped()) {
134 0 : ret->mkItem(TL("vTypes"), false, toString(myDetector.getVehicleTypes()));
135 : }
136 : // values
137 0 : ret->mkItem(TL("vehicles [#]"), true,
138 0 : new FunctionBinding<MSE2Collector, int>(&myDetector, &MSE2Collector::getCurrentVehicleNumber));
139 0 : ret->mkItem(TL("occupancy [%]"), true,
140 0 : new FunctionBinding<MSE2Collector, double>(&myDetector, &MSE2Collector::getCurrentOccupancy));
141 0 : ret->mkItem(TL("mean speed [m/s]"), true,
142 0 : new FunctionBinding<MSE2Collector, double>(&myDetector, &MSE2Collector::getCurrentMeanSpeed));
143 0 : ret->mkItem(TL("mean vehicle length [m]"), true,
144 0 : new FunctionBinding<MSE2Collector, double>(&myDetector, &MSE2Collector::getCurrentMeanLength));
145 0 : ret->mkItem(TL("jam number [#]"), true,
146 0 : new FunctionBinding<MSE2Collector, int>(&myDetector, &MSE2Collector::getCurrentJamNumber));
147 0 : ret->mkItem(TL("max jam length [veh]"), true,
148 0 : new FunctionBinding<MSE2Collector, int>(&myDetector, &MSE2Collector::getCurrentMaxJamLengthInVehicles));
149 0 : ret->mkItem(TL("max jam length [m]"), true,
150 0 : new FunctionBinding<MSE2Collector, double>(&myDetector, &MSE2Collector::getCurrentMaxJamLengthInMeters));
151 0 : ret->mkItem(TL("jam length sum [veh]"), true,
152 0 : new FunctionBinding<MSE2Collector, int>(&myDetector, &MSE2Collector::getCurrentJamLengthInVehicles));
153 0 : ret->mkItem(TL("jam length sum [m]"), true,
154 0 : new FunctionBinding<MSE2Collector, double>(&myDetector, &MSE2Collector::getCurrentJamLengthInMeters));
155 0 : ret->mkItem(TL("started halts [#]"), true,
156 0 : new FunctionBinding<MSE2Collector, int>(&myDetector, &MSE2Collector::getCurrentStartedHalts));
157 0 : ret->mkItem(TL("interval seen vehicles [#]"), true,
158 0 : new FunctionBinding<MSE2Collector, int>(&myDetector, &MSE2Collector::getIntervalVehicleNumber));
159 0 : ret->mkItem(TL("interval speed [m/s]"), true,
160 0 : new FunctionBinding<MSE2Collector, double>(&myDetector, &MSE2Collector::getIntervalMeanSpeed));
161 0 : ret->mkItem(TL("interval occupancy [%]"), true,
162 0 : new FunctionBinding<MSE2Collector, double>(&myDetector, &MSE2Collector::getIntervalOccupancy));
163 0 : ret->mkItem(TL("interval max jam length [m]"), true,
164 0 : new FunctionBinding<MSE2Collector, double>(&myDetector, &MSE2Collector::getIntervalMaxJamLengthInMeters));
165 0 : ret->mkItem(TL("last interval seen vehicles [#]"), true,
166 0 : new FunctionBinding<MSE2Collector, int>(&myDetector, &MSE2Collector::getLastIntervalVehicleNumber));
167 0 : ret->mkItem(TL("last interval speed [m/s]"), true,
168 0 : new FunctionBinding<MSE2Collector, double>(&myDetector, &MSE2Collector::getLastIntervalMeanSpeed));
169 0 : ret->mkItem(TL("last interval occupancy [%]"), true,
170 0 : new FunctionBinding<MSE2Collector, double>(&myDetector, &MSE2Collector::getLastIntervalOccupancy));
171 0 : ret->mkItem(TL("last interval max jam length [m]"), true,
172 0 : new FunctionBinding<MSE2Collector, double>(&myDetector, &MSE2Collector::getLastIntervalMaxJamLengthInMeters));
173 :
174 :
175 : // close building
176 0 : ret->closeBuilding(&myDetector);
177 0 : return ret;
178 : }
179 :
180 :
181 : void
182 12059 : GUIE2Collector::MyWrapper::drawGL(const GUIVisualizationSettings& s) const {
183 12059 : if (!myDetector.myShow) {
184 : return;
185 : }
186 5795 : GLHelper::pushName(getGlID());
187 5795 : GLHelper::pushMatrix();
188 5795 : glTranslated(0, 0, GLO_JUNCTION + 0.4); // do not draw on top of linkRules
189 : double dwidth = 1;
190 5795 : const double exaggeration = getExaggeration(s);
191 5795 : if (exaggeration > 0) {
192 5795 : if (haveOverride()) {
193 0 : glColor3d(1, 0, 1);
194 5795 : } else if (myDetector.getUsageType() == DU_TL_CONTROL) {
195 0 : glColor3d(0, (double) .6, (double) .8);
196 : } else {
197 5795 : glColor3d(0, (double) .8, (double) .8);
198 : }
199 5795 : if (myDetector.getUsageType() == DU_TL_CONTROL) {
200 : dwidth = (double) 0.3;
201 : }
202 5795 : double width = (double) 2.0 * s.scale;
203 5795 : if (width * exaggeration > 1.0) {
204 4809 : GLHelper::drawBoxLines(myFullGeometry, myShapeRotations, myShapeLengths, dwidth * exaggeration);
205 : } else {
206 986 : int e = (int) myFullGeometry.size() - 1;
207 1972 : for (int i = 0; i < e; ++i) {
208 986 : GLHelper::drawLine(myFullGeometry[i], myShapeRotations[i], myShapeLengths[i]);
209 : }
210 : }
211 : }
212 5795 : GLHelper::popMatrix();
213 5795 : drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
214 5795 : GLHelper::popName();
215 : }
216 :
217 :
218 : GUIE2Collector&
219 0 : GUIE2Collector::MyWrapper::getDetector() {
220 0 : return myDetector;
221 : }
222 :
223 : bool
224 5795 : GUIE2Collector::MyWrapper::haveOverride() const {
225 5795 : return myDetector.getOverrideVehNumber() >= 0;
226 : }
227 :
228 :
229 : void
230 0 : GUIE2Collector::MyWrapper::toggleOverride() const {
231 0 : if (haveOverride()) {
232 0 : myDetector.overrideVehicleNumber(-1);
233 : } else {
234 0 : myDetector.overrideVehicleNumber(1);
235 : }
236 0 : }
237 :
238 :
239 : /****************************************************************************/
|