LCOV - code coverage report
Current view: top level - src/guisim - GUIJunctionWrapper.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 69 115 60.0 %
Date: 2024-04-27 15:34:54 Functions: 7 11 63.6 %

          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    GUIJunctionWrapper.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Jakob Erdmann
      17             : /// @author  Michael Behrisch
      18             : /// @author  Laura Bieker
      19             : /// @author  Andreas Gaubatz
      20             : /// @date    Mon, 1 Jul 2003
      21             : ///
      22             : // }
      23             : /****************************************************************************/
      24             : #include <config.h>
      25             : 
      26             : #include <string>
      27             : #include <utility>
      28             : #include <microsim/MSLane.h>
      29             : #include <microsim/MSEdge.h>
      30             : #include <microsim/MSJunction.h>
      31             : #include <utils/geom/Position.h>
      32             : #include <utils/geom/GeomHelper.h>
      33             : #include <microsim/MSNet.h>
      34             : #include <microsim/MSInternalJunction.h>
      35             : #include <microsim/traffic_lights/MSTrafficLightLogic.h>
      36             : #include <microsim/traffic_lights/MSTLLogicControl.h>
      37             : #include <gui/GUIApplicationWindow.h>
      38             : #include <gui/GUIGlobals.h>
      39             : #include <utils/gui/windows/GUIAppEnum.h>
      40             : #include <utils/gui/windows/GUISUMOAbstractView.h>
      41             : #include "GUIJunctionWrapper.h"
      42             : #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
      43             : #include <utils/gui/div/GUIGlobalSelection.h>
      44             : #include <utils/gui/div/GUIParameterTableWindow.h>
      45             : #include <utils/gui/div/GLHelper.h>
      46             : #include <utils/gui/globjects/GLIncludes.h>
      47             : 
      48             : #include <osgview/GUIOSGHeader.h>
      49             : 
      50             : // ===========================================================================
      51             : // method definitions
      52             : // ===========================================================================
      53       82100 : GUIJunctionWrapper::GUIJunctionWrapper(MSJunction& junction, const std::string& tllID):
      54             :     GUIGlObject(GLO_JUNCTION, junction.getID(), GUIIconSubSys::getIcon(GUIIcon::JUNCTION)),
      55       82100 :     myJunction(junction),
      56      164200 :     myTesselation(junction.getID(), "", RGBColor::MAGENTA, junction.getShape(), false, true, 0),
      57       82100 :     myExaggeration(1),
      58      164200 :     myTLLID(tllID) {
      59       82100 :     if (myJunction.getShape().size() == 0) {
      60       22904 :         Position pos = myJunction.getPosition();
      61       22904 :         myBoundary = Boundary(pos.x() - 1., pos.y() - 1., pos.x() + 1., pos.y() + 1.);
      62             :     } else {
      63       59196 :         myBoundary = myJunction.getShape().getBoxBoundary();
      64             :     }
      65       82100 :     myMaxSize = MAX2(myBoundary.getWidth(), myBoundary.getHeight());
      66       82100 :     myIsInternal = myJunction.getType() == SumoXMLNodeType::INTERNAL;
      67       82100 :     myAmWaterway = myJunction.getIncoming().size() + myJunction.getOutgoing().size() > 0;
      68       82100 :     myAmRailway = myJunction.getIncoming().size() + myJunction.getOutgoing().size() > 0;
      69      244445 :     for (auto it = myJunction.getIncoming().begin(); it != myJunction.getIncoming().end() && (myAmWaterway || myAmRailway); ++it) {
      70      162345 :         if (!(*it)->isInternal()) {
      71       56011 :             if (!isWaterway((*it)->getPermissions())) {
      72       55974 :                 myAmWaterway = false;
      73             :             }
      74       56011 :             if (!isRailway((*it)->getPermissions())) {
      75       51767 :                 myAmRailway = false;
      76             :             }
      77             :         }
      78             :     }
      79       93589 :     for (auto it = myJunction.getOutgoing().begin(); it != myJunction.getOutgoing().end() && (myAmWaterway || myAmRailway); ++it) {
      80       11489 :         if (!(*it)->isInternal()) {
      81        8185 :             if (!isWaterway((*it)->getPermissions())) {
      82        8153 :                 myAmWaterway = false;
      83             :             }
      84        8185 :             if (!isRailway((*it)->getPermissions())) {
      85        3999 :                 myAmRailway = false;
      86             :             }
      87             :         }
      88             :     }
      89       82100 :     myTesselation.getShapeRef().closePolygon();
      90       82100 : }
      91             : 
      92             : 
      93      245778 : GUIJunctionWrapper::~GUIJunctionWrapper() {}
      94             : 
      95             : 
      96             : GUIGLObjectPopupMenu*
      97           0 : GUIJunctionWrapper::getPopUpMenu(GUIMainWindow& app,
      98             :                                  GUISUMOAbstractView& parent) {
      99           0 :     GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
     100           0 :     buildPopupHeader(ret, app);
     101           0 :     buildCenterPopupEntry(ret);
     102           0 :     buildNameCopyPopupEntry(ret);
     103           0 :     buildSelectionPopupEntry(ret);
     104           0 :     buildShowParamsPopupEntry(ret);
     105           0 :     buildPositionCopyEntry(ret, app);
     106           0 :     return ret;
     107             : }
     108             : 
     109             : 
     110             : GUIParameterTableWindow*
     111           0 : GUIJunctionWrapper::getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView&) {
     112           0 :     GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
     113             :     // add items
     114           0 :     ret->mkItem(TL("type"), false, toString(myJunction.getType()));
     115           0 :     ret->mkItem(TL("name"), false, myJunction.getName());
     116             :     // close building
     117           0 :     ret->closeBuilding(&myJunction);
     118           0 :     return ret;
     119             : }
     120             : 
     121             : 
     122             : double
     123     5484591 : GUIJunctionWrapper::getExaggeration(const GUIVisualizationSettings& s) const {
     124     5484591 :     return s.junctionSize.getExaggeration(s, this, 4);
     125             : }
     126             : 
     127             : 
     128             : Boundary
     129           0 : GUIJunctionWrapper::getCenteringBoundary() const {
     130             :     Boundary b = myBoundary;
     131           0 :     b.grow(1);
     132           0 :     return b;
     133           0 : }
     134             : 
     135             : const std::string
     136           0 : GUIJunctionWrapper::getOptionalName() const {
     137           0 :     return myJunction.getName();
     138             : }
     139             : 
     140             : void
     141     7446534 : GUIJunctionWrapper::drawGL(const GUIVisualizationSettings& s) const {
     142     7446534 :     const bool s2 = s.secondaryShape;
     143     7446534 :     if (!myIsInternal && s.drawJunctionShape && !s2) {
     144             :         // check whether it is not too small
     145     5484591 :         const double exaggeration = getExaggeration(s);
     146     5484591 :         if (s.scale * exaggeration >= s.junctionSize.minSize) {
     147     1191919 :             GLHelper::pushMatrix();
     148     1191919 :             GLHelper::pushName(getGlID());
     149     1191919 :             const double colorValue = getColorValue(s, s.junctionColorer.getActive());
     150     1191919 :             const RGBColor color = s.junctionColorer.getScheme().getColor(colorValue);
     151     1191919 :             GLHelper::setColor(color);
     152             : 
     153             :             // recognize full transparency and simply don't draw
     154     1191919 :             if (color.alpha() != 0) {
     155     1181861 :                 if ((exaggeration > 1 || myExaggeration > 1) && exaggeration != myExaggeration) {
     156           0 :                     myExaggeration = exaggeration;
     157           0 :                     myTesselation.setShape(myJunction.getShape());
     158           0 :                     myTesselation.getShapeRef().closePolygon();
     159           0 :                     myTesselation.getShapeRef().scaleRelative(exaggeration);
     160             :                     myTesselation.myTesselation.clear();
     161             :                 }
     162     1181861 :                 glTranslated(0, 0, getType());
     163     1181861 :                 if (s.scale * myMaxSize < 40.) {
     164     1014165 :                     GLHelper::drawFilledPoly(myTesselation.getShape(), true);
     165             :                 } else {
     166      167696 :                     myTesselation.drawTesselation(myTesselation.getShape());
     167             :                 }
     168             :                 // make small junctions more visible when coloring by type
     169     1181861 :                 if (myJunction.getType() == SumoXMLNodeType::RAIL_SIGNAL && s.junctionColorer.getActive() == 2) {
     170           0 :                     glTranslated(myJunction.getPosition(s2).x(), myJunction.getPosition(s2).y(), getType() + 0.05);
     171           0 :                     GLHelper::drawFilledCircle(2 * exaggeration, 12);
     172             :                 }
     173             :             }
     174     1191919 :             GLHelper::popName();
     175     1191919 :             GLHelper::popMatrix();
     176     1191918 :             if (s.geometryIndices.show(this)) {
     177           0 :                 GLHelper::debugVertices(myJunction.getShape(), s.geometryIndices, s.scale);
     178             :             }
     179             :         }
     180             :     }
     181     7446533 :     if (myIsInternal) {
     182     1961943 :         drawName(myJunction.getPosition(s2), s.scale, s.internalJunctionName, s.angle);
     183             :     } else {
     184     5484590 :         drawName(myJunction.getPosition(s2), s.scale, s.junctionID, s.angle);
     185     5484590 :         if (s.junctionName.show(this) && myJunction.getName() != "") {
     186           0 :             GLHelper::drawTextSettings(s.junctionName, myJunction.getName(), myJunction.getPosition(s2), s.scale, s.angle);
     187             :         }
     188     5484590 :         if ((s.tlsPhaseIndex.show(this) || s.tlsPhaseName.show(this)) && myTLLID != "") {
     189           0 :             const MSTrafficLightLogic* active = MSNet::getInstance()->getTLSControl().getActive(myTLLID);
     190           0 :             if (s.tlsPhaseIndex.show(this)) {
     191           0 :                 const int index = active->getCurrentPhaseIndex();
     192           0 :                 GLHelper::drawTextSettings(s.tlsPhaseIndex, toString(index), myJunction.getPosition(s2), s.scale, s.angle);
     193             :             }
     194           0 :             if (s.tlsPhaseName.show(this)) {
     195           0 :                 const std::string& name = active->getCurrentPhaseDef().getName();
     196           0 :                 if (name != "") {
     197           0 :                     const Position offset = (s.tlsPhaseIndex.show(this) ?
     198           0 :                                              Position(0, 0.8 * s.tlsPhaseIndex.scaledSize(s.scale)).rotateAround2D(DEG2RAD(-s.angle), Position(0, 0))
     199           0 :                                              : Position(0, 0));
     200           0 :                     GLHelper::drawTextSettings(s.tlsPhaseName, name, myJunction.getPosition(s2) - offset, s.scale, s.angle);
     201             :                 }
     202             :             }
     203             :         }
     204             :     }
     205     7446533 : }
     206             : 
     207             : 
     208             : double
     209     1279350 : GUIJunctionWrapper::getColorValue(const GUIVisualizationSettings& /* s */, int activeScheme) const {
     210     1279350 :     switch (activeScheme) {
     211     1279350 :         case 0:
     212     1279350 :             if (myAmWaterway) {
     213             :                 return 1;
     214     1279169 :             } else if (myAmRailway && MSNet::getInstance()->hasInternalLinks()) {
     215             :                 return 2;
     216             :             } else {
     217     1266935 :                 return 0;
     218             :             }
     219           0 :         case 1:
     220           0 :             return gSelected.isSelected(getType(), getGlID()) ? 1 : 0;
     221           0 :         case 2:
     222           0 :             switch (myJunction.getType()) {
     223             :                 case SumoXMLNodeType::TRAFFIC_LIGHT:
     224             :                     return 0;
     225             :                 case SumoXMLNodeType::TRAFFIC_LIGHT_NOJUNCTION:
     226             :                     return 1;
     227             :                 case SumoXMLNodeType::PRIORITY:
     228             :                     return 2;
     229             :                 case SumoXMLNodeType::PRIORITY_STOP:
     230             :                     return 3;
     231             :                 case SumoXMLNodeType::RIGHT_BEFORE_LEFT:
     232             :                     return 4;
     233             :                 case SumoXMLNodeType::ALLWAY_STOP:
     234             :                     return 5;
     235             :                 case SumoXMLNodeType::DISTRICT:
     236             :                     return 6;
     237             :                 case SumoXMLNodeType::NOJUNCTION:
     238             :                     return 7;
     239             :                 case SumoXMLNodeType::DEAD_END:
     240             :                 case SumoXMLNodeType::DEAD_END_DEPRECATED:
     241             :                     return 8;
     242             :                 case SumoXMLNodeType::UNKNOWN:
     243             :                 case SumoXMLNodeType::INTERNAL:
     244             :                     assert(false);
     245             :                     return 8;
     246             :                 case SumoXMLNodeType::RAIL_SIGNAL:
     247             :                     return 9;
     248             :                 case SumoXMLNodeType::ZIPPER:
     249             :                     return 10;
     250             :                 case SumoXMLNodeType::TRAFFIC_LIGHT_RIGHT_ON_RED:
     251             :                     return 11;
     252             :                 case SumoXMLNodeType::RAIL_CROSSING:
     253             :                     return 12;
     254             :                 case SumoXMLNodeType::LEFT_BEFORE_RIGHT:
     255             :                     return 13;
     256             :                 default:
     257             :                     assert(false);
     258             :                     return 0;
     259             :             }
     260           0 :         case 3:
     261           0 :             return myJunction.getPosition().z();
     262             :         default:
     263             :             assert(false);
     264             :             return 0;
     265             :     }
     266             : }
     267             : 
     268             : #ifdef HAVE_OSG
     269             : void
     270       87431 : GUIJunctionWrapper::updateColor(const GUIVisualizationSettings& s) {
     271       87431 :     const double colorValue = getColorValue(s, s.junctionColorer.getActive());
     272       87431 :     const RGBColor& col = s.junctionColorer.getScheme().getColor(colorValue);
     273       87431 :     osg::Vec4ubArray* colors = dynamic_cast<osg::Vec4ubArray*>(myGeom->getColorArray());
     274       87431 :     (*colors)[0].set(col.red(), col.green(), col.blue(), col.alpha());
     275       87431 :     myGeom->setColorArray(colors);
     276       87431 : }
     277             : #endif
     278             : 
     279             : 
     280             : /****************************************************************************/

Generated by: LCOV version 1.14