LCOV - code coverage report
Current view: top level - src/guisim - GUIBusStop.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 66.0 % 144 95
Test Date: 2024-11-22 15:46:21 Functions: 66.7 % 12 8

            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    GUIBusStop.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @author  Johannes Rummel
      19              : /// @date    Wed, 07.12.2005
      20              : ///
      21              : // A lane area vehicles can halt at (gui-version)
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <string>
      26              : #include <utils/common/MsgHandler.h>
      27              : #include <utils/common/RGBColor.h>
      28              : #include <utils/geom/PositionVector.h>
      29              : #include <utils/geom/Boundary.h>
      30              : #include <utils/gui/div/GLHelper.h>
      31              : #include <utils/common/ToString.h>
      32              : #include <microsim/MSNet.h>
      33              : #include <microsim/MSLane.h>
      34              : #include <microsim/MSEdge.h>
      35              : #include <microsim/transportables/MSTransportable.h>
      36              : #include <microsim/transportables/MSStageDriving.h>
      37              : #include "GUINet.h"
      38              : #include "GUIEdge.h"
      39              : #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
      40              : #include <utils/gui/windows/GUIAppEnum.h>
      41              : #include <gui/GUIGlobals.h>
      42              : #include <utils/gui/div/GUIParameterTableWindow.h>
      43              : #include <gui/GUIApplicationWindow.h>
      44              : #include <microsim/logging/FunctionBinding.h>
      45              : #include <utils/gui/div/GUIGlobalSelection.h>
      46              : #include <foreign/fontstash/fontstash.h>
      47              : #include <utils/geom/GeomHelper.h>
      48              : #include <guisim/GUIBusStop.h>
      49              : #include <utils/common/MsgHandler.h>
      50              : #include <utils/gui/globjects/GLIncludes.h>
      51              : 
      52              : 
      53              : 
      54              : // ===========================================================================
      55              : // method definitions
      56              : // ===========================================================================
      57         1694 : GUIBusStop::GUIBusStop(const std::string& id, SumoXMLTag element, const std::vector<std::string>& lines, MSLane& lane,
      58              :                        double frompos, double topos, const std::string name, int personCapacity,
      59         1694 :                        double parkingLength, const RGBColor& color) :
      60              :     MSStoppingPlace(id, element, lines, lane, frompos, topos, name, personCapacity, parkingLength, color),
      61         3388 :     GUIGlObject_AbstractAdd(GLO_BUS_STOP, id, GUIIconSubSys::getIcon(GUIIcon::BUSSTOP)) {
      62              :     // see MSVehicleControl defContainerType
      63         1694 :     myWidth = MAX2(1.0, ceil((double)personCapacity / getTransportablesAbreast()) * myTransportableDepth);
      64         1694 :     initShape(myFGShape, myFGShapeRotations, myFGShapeLengths, myFGSignPos, myFGSignRot);
      65         1694 :     if (lane.getShape(true).size() > 0) {
      66         1694 :         initShape(myFGShape2, myFGShapeRotations2, myFGShapeLengths2, myFGSignPos2, myFGSignRot2, true);
      67              :     }
      68         1694 : }
      69              : 
      70              : 
      71         3384 : GUIBusStop::~GUIBusStop() {}
      72              : 
      73              : 
      74              : void
      75         3388 : GUIBusStop::initShape(PositionVector& fgShape,
      76              :                       std::vector<double>& fgShapeRotations, std::vector<double>& fgShapeLengths,
      77              :                       Position& fgSignPos, double& fgSignRot,
      78              :                       bool secondaryShape) {
      79         3388 :     const double offsetSign = MSGlobals::gLefthand ? -1 : 1;
      80         3388 :     const double lgf = myLane.getLengthGeometryFactor(secondaryShape);
      81         3388 :     fgShape = myLane.getShape(secondaryShape);
      82         6776 :     fgShape = fgShape.getSubpart(lgf * myBegPos, lgf * myEndPos);
      83         3388 :     fgShape.move2side(((myLane.getWidth() + myWidth) * 0.5 - 0.2) * offsetSign);
      84         3388 :     fgShapeRotations.reserve(fgShape.size() - 1);
      85         3388 :     fgShapeLengths.reserve(fgShape.size() - 1);
      86         3388 :     int e = (int) fgShape.size() - 1;
      87         8178 :     for (int i = 0; i < e; ++i) {
      88         4790 :         const Position& f = fgShape[i];
      89         4790 :         const Position& s = fgShape[i + 1];
      90         4790 :         fgShapeLengths.push_back(f.distanceTo(s));
      91         4790 :         fgShapeRotations.push_back((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double) M_PI);
      92              :     }
      93              :     PositionVector tmp = fgShape;
      94         3388 :     tmp.move2side(myWidth / 2 * offsetSign);
      95         3388 :     fgSignPos = tmp.getLineCenter();
      96         3388 :     fgSignRot = 0;
      97         3388 :     if (tmp.length() != 0) {
      98         3388 :         fgSignRot = fgShape.rotationDegreeAtOffset(double((fgShape.length() / 2.)));
      99         3388 :         const double rotSign = MSGlobals::gLefthand ? -1 : 1;
     100         3388 :         fgSignRot -= 90 * rotSign;
     101              :     }
     102         3388 : }
     103              : 
     104              : 
     105              : bool
     106          229 : GUIBusStop::addAccess(MSLane* const lane, const double startPos, const double endPos, double length, const MSStoppingPlace::AccessExit exit) {
     107          229 :     const bool added = MSStoppingPlace::addAccess(lane, startPos, endPos, length, exit);
     108          229 :     if (added) {
     109          227 :         myAccessCoords.push_back(lane->geometryPositionAtOffset((startPos + endPos) / 2.));
     110              :     }
     111          229 :     return added;
     112              : }
     113              : 
     114              : 
     115              : GUIGLObjectPopupMenu*
     116            0 : GUIBusStop::getPopUpMenu(GUIMainWindow& app,
     117              :                          GUISUMOAbstractView& parent) {
     118            0 :     GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
     119            0 :     buildPopupHeader(ret, app);
     120            0 :     buildCenterPopupEntry(ret);
     121            0 :     buildNameCopyPopupEntry(ret);
     122            0 :     buildSelectionPopupEntry(ret);
     123            0 :     buildShowParamsPopupEntry(ret);
     124            0 :     buildPositionCopyEntry(ret, app);
     125            0 :     return ret;
     126              : }
     127              : 
     128              : 
     129              : GUIParameterTableWindow*
     130            0 : GUIBusStop::getParameterWindow(GUIMainWindow& app,
     131              :                                GUISUMOAbstractView&) {
     132              :     GUIParameterTableWindow* ret =
     133            0 :         new GUIParameterTableWindow(app, *this);
     134              :     // add items
     135            0 :     ret->mkItem(TL("name"), false, getMyName());
     136            0 :     ret->mkItem(TL("begin position [m]"), false, myBegPos);
     137            0 :     ret->mkItem(TL("end position [m]"), false, myEndPos);
     138            0 :     ret->mkItem(TL("lines"), false, joinToString(myLines, " "));
     139            0 :     ret->mkItem(TL("parking length [m]"), false, (myEndPos - myBegPos) / myParkingFactor);
     140            0 :     const std::string transportable = (myElement == SUMO_TAG_CONTAINER_STOP ? "container" : "person");
     141            0 :     ret->mkItem((transportable + " capacity [#]").c_str(), false, myTransportableCapacity);
     142            0 :     ret->mkItem((transportable + " number [#]").c_str(), true, new FunctionBinding<GUIBusStop, int>(this, &MSStoppingPlace::getTransportableNumber));
     143            0 :     ret->mkItem(TL("stopped vehicles [#]"), true, new FunctionBinding<GUIBusStop, int>(this, &MSStoppingPlace::getStoppedVehicleNumber));
     144            0 :     ret->mkItem(TL("last free pos [m]"), true, new FunctionBinding<GUIBusStop, double>(this, &GUIBusStop::getCroppedLastFreePos));
     145              :     // rides-being-waited-on statistic
     146              :     std::map<std::string, int> stats;
     147            0 :     for (const MSTransportable* t : getTransportables()) {
     148            0 :         MSStageDriving* s = dynamic_cast<MSStageDriving*>(t->getCurrentStage());
     149            0 :         if (s != nullptr) {
     150            0 :             if (s->getIntendedVehicleID() != "") {
     151            0 :                 stats[s->getIntendedVehicleID()] += 1;
     152              :             } else {
     153            0 :                 stats[joinToString(s->getLines(), " ")] += 1;
     154              :             }
     155              :         }
     156            0 :     }
     157            0 :     if (stats.size() > 0) {
     158            0 :         ret->mkItem(TL("waiting for:"), false, "[#]");
     159            0 :         for (auto item : stats) {
     160            0 :             ret->mkItem(item.first.c_str(), false, toString(item.second));
     161              :         }
     162              :     }
     163              : 
     164              :     // close building
     165            0 :     ret->closeBuilding();
     166            0 :     return ret;
     167              : }
     168              : 
     169              : 
     170              : void
     171        52504 : GUIBusStop::drawGL(const GUIVisualizationSettings& s) const {
     172              :     // get colors
     173        52504 :     RGBColor color, colorSign;
     174        52504 :     if (myElement == SUMO_TAG_CONTAINER_STOP) {
     175         8469 :         color = s.colorSettings.containerStopColor;
     176         8469 :         colorSign = s.colorSettings.containerStopColorSign;
     177        44035 :     } else if (myElement == SUMO_TAG_TRAIN_STOP) {
     178         8392 :         color = s.colorSettings.trainStopColor;
     179         8392 :         colorSign = s.colorSettings.trainStopColorSign;
     180              :     } else {
     181        35643 :         color = s.colorSettings.busStopColor;
     182        35643 :         colorSign = s.colorSettings.busStopColorSign;
     183              :     }
     184              :     // set color
     185        52504 :     if (getColor() != RGBColor::INVISIBLE) {
     186           14 :         color = getColor();
     187              :     }
     188        52504 :     GLHelper::pushName(getGlID());
     189        52504 :     GLHelper::pushMatrix();
     190              :     // draw the area
     191        52504 :     glTranslated(0, 0, getType());
     192        52504 :     GLHelper::setColor(color);
     193        52504 :     const double exaggeration = getExaggeration(s);
     194              :     // only shrink the box but never enlarge it (only enlarge the sign)
     195        52504 :     const bool s2 = s.secondaryShape;
     196        52504 :     if (s2) {
     197            0 :         GLHelper::drawBoxLines(myFGShape2, myFGShapeRotations2, myFGShapeLengths2, myWidth * 0.5 * MIN2(1.0, exaggeration), 0, 0);
     198              :     } else {
     199       105008 :         GLHelper::drawBoxLines(myFGShape, myFGShapeRotations, myFGShapeLengths, myWidth * 0.5 * MIN2(1.0, exaggeration), 0, 0);
     200              :     }
     201        52504 :     const double signRot = s2 ? myFGSignRot2 : myFGSignRot;
     202        52504 :     const Position& signPos = s2 ? myFGSignPos2 : myFGSignPos;
     203              :     // draw details unless zoomed out to far
     204        52504 :     if (s.drawDetail(10, exaggeration)) {
     205            4 :         GLHelper::pushMatrix();
     206              :         // draw the lines
     207            4 :         const double rotSign = MSGlobals::gLefthand ? 1 : -1;
     208            4 :         const double lineAngle = s.getTextAngle(signRot);
     209              :         // Iterate over every line
     210            4 :         RGBColor lineColor = color.changedBrightness(-51);
     211            4 :         const double textOffset = s.flippedTextAngle(rotSign * signRot) ? -1 : 1;
     212            4 :         const double textOffset2 = s.flippedTextAngle(rotSign * signRot) ? -1 : 0.3;
     213            4 :         for (int i = 0; i < (int)myLines.size(); ++i) {
     214              :             // push a new matrix for every line
     215            0 :             GLHelper::pushMatrix();
     216              :             // traslate and rotate
     217            0 :             glTranslated(signPos.x(), signPos.y(), 0);
     218            0 :             glRotated(-lineAngle, 0, 0, 1);
     219              :             // draw line
     220            0 :             GLHelper::drawText(myLines[i].c_str(), Position(1.2, i * textOffset + textOffset2), .1, 1.f, lineColor, 0, FONS_ALIGN_LEFT);
     221              :             // pop matrix for every line
     222            0 :             GLHelper::popMatrix();
     223              :         }
     224            4 :         GLHelper::setColor(color);
     225            4 :         const Position accessOrigin = getCenterPos();
     226            4 :         for (std::vector<Position>::const_iterator i = myAccessCoords.begin(); i != myAccessCoords.end(); ++i) {
     227            0 :             GLHelper::drawBoxLine(*i, RAD2DEG(accessOrigin.angleTo2D(*i)) - 90, accessOrigin.distanceTo2D(*i), .05);
     228              :         }
     229              :         // draw the sign
     230            4 :         glTranslated(signPos.x(), signPos.y(), 0);
     231              :         int noPoints = 9;
     232            4 :         if (s.scale * exaggeration > 25) {
     233            4 :             noPoints = MIN2((int)(9.0 + (s.scale * exaggeration) / 10.0), 36);
     234              :         }
     235            4 :         glScaled(exaggeration, exaggeration, 1);
     236            4 :         GLHelper::drawFilledCircle((double) 1.1, noPoints);
     237            4 :         glTranslated(0, 0, .1);
     238            4 :         GLHelper::setColor(colorSign);
     239            4 :         GLHelper::drawFilledCircle((double) 0.9, noPoints);
     240            4 :         if (myElement == SUMO_TAG_CONTAINER_STOP) {
     241            0 :             GLHelper::drawText("C", Position(), .1, 1.6, color, signRot);
     242            4 :         } else if (myElement == SUMO_TAG_TRAIN_STOP) {
     243            0 :             GLHelper::drawText("T", Position(), .1, 1.6, color, signRot);
     244              :         } else {
     245            8 :             GLHelper::drawText("H", Position(), .1, 1.6, color, signRot);
     246              :         }
     247            4 :         GLHelper::popMatrix();
     248              :     }
     249        52504 :     if (s.addFullName.show(this) && getMyName() != "") {
     250            0 :         GLHelper::drawTextSettings(s.addFullName, getMyName(), signPos, s.scale, s.getTextAngle(signRot), GLO_MAX - getType());
     251              :     }
     252        52504 :     GLHelper::popMatrix();
     253        52504 :     GLHelper::popName();
     254        52504 :     drawName(signPos, s.scale, s.addName, s.angle);
     255        52504 : }
     256              : 
     257              : 
     258              : double
     259        52504 : GUIBusStop::getExaggeration(const GUIVisualizationSettings& s) const {
     260        52504 :     return s.addSize.getExaggeration(s, this);
     261              : }
     262              : 
     263              : 
     264              : Boundary
     265         1691 : GUIBusStop::getCenteringBoundary() const {
     266         1691 :     const PositionVector& shape = GUIGlobals::gSecondaryShape ? myFGShape2 : myFGShape;
     267         1691 :     Boundary b = shape.getBoxBoundary();
     268         1691 :     b.grow(myWidth);
     269         1918 :     for (const Position& p : myAccessCoords) {
     270          227 :         b.add(p);
     271              :     }
     272         1691 :     return b;
     273            0 : }
     274              : 
     275              : const std::string
     276            0 : GUIBusStop::getOptionalName() const {
     277            0 :     return myName;
     278              : }
     279              : 
     280              : double
     281            0 : GUIBusStop::getCroppedLastFreePos() const {
     282            0 :     return MAX2(0., getLastFreePos());
     283              : }
     284              : 
     285              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1