LCOV - code coverage report
Current view: top level - src/guisim - GUIBusStop.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 95 143 66.4 %
Date: 2024-04-27 15:34:54 Functions: 8 12 66.7 %

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

Generated by: LCOV version 1.14