LCOV - code coverage report
Current view: top level - src/netbuild - NBContHelper.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 77 106 72.6 %
Date: 2024-05-06 15:32:35 Functions: 10 17 58.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    NBContHelper.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Jakob Erdmann
      17             : /// @author  Michael Behrisch
      18             : /// @date    Tue, 20 Nov 2001
      19             : ///
      20             : // Some methods for traversing lists of edges
      21             : /****************************************************************************/
      22             : #include <config.h>
      23             : 
      24             : #include <vector>
      25             : #include <map>
      26             : #include <cassert>
      27             : #include "NBContHelper.h"
      28             : #include <utils/geom/GeomHelper.h>
      29             : 
      30             : 
      31             : // ===========================================================================
      32             : // method definitions
      33             : // ===========================================================================
      34             : /* -------------------------------------------------------------------------
      35             :  * utility methods
      36             :  * ----------------------------------------------------------------------- */
      37             : void
      38     6234404 : NBContHelper::nextCW(const EdgeVector& edges, EdgeVector::const_iterator& from) {
      39             :     from++;
      40     6234404 :     if (from == edges.end()) {
      41     1006576 :         from = edges.begin();
      42             :     }
      43     6234404 : }
      44             : 
      45             : 
      46             : void
      47     5835985 : NBContHelper::nextCCW(const EdgeVector& edges, EdgeVector::const_iterator& from) {
      48     5835985 :     if (from == edges.begin()) {
      49      715438 :         from = edges.end() - 1;
      50             :     } else {
      51             :         --from;
      52             :     }
      53     5835985 : }
      54             : 
      55             : 
      56             : std::ostream&
      57           0 : NBContHelper::out(std::ostream& os, const std::vector<bool>& v) {
      58           0 :     for (std::vector<bool>::const_iterator i = v.begin(); i != v.end(); i++) {
      59           0 :         os << *i;
      60             :     }
      61           0 :     return os;
      62             : }
      63             : 
      64             : 
      65             : NBEdge*
      66           0 : NBContHelper::findConnectingEdge(const EdgeVector& edges,
      67             :                                  NBNode* from, NBNode* to) {
      68           0 :     for (EdgeVector::const_iterator i = edges.begin(); i != edges.end(); i++) {
      69           0 :         if ((*i)->getToNode() == to && (*i)->getFromNode() == from) {
      70             :             return *i;
      71             :         }
      72             :     }
      73             :     return nullptr;
      74             : }
      75             : 
      76             : 
      77             : 
      78             : double
      79        3650 : NBContHelper::maxSpeed(const EdgeVector& ev) {
      80             :     assert(ev.size() > 0);
      81        3650 :     double max = (*(ev.begin()))->getSpeed();
      82       14896 :     for (EdgeVector::const_iterator i = ev.begin() + 1; i != ev.end(); i++) {
      83             :         max =
      84       11246 :             max > (*i)->getSpeed()
      85       11246 :             ? max : (*i)->getSpeed();
      86             :     }
      87        3650 :     return max;
      88             : }
      89             : 
      90             : 
      91             : 
      92             : /* -------------------------------------------------------------------------
      93             :  * methods from node_with_incoming_finder
      94             :  * ----------------------------------------------------------------------- */
      95     1187169 : NBContHelper::node_with_incoming_finder::node_with_incoming_finder(const NBEdge* const e)
      96     1187169 :     : myEdge(e) {}
      97             : 
      98             : 
      99             : bool
     100     2957441 : NBContHelper::node_with_incoming_finder::operator()(const NBNode* const n) const {
     101             :     const EdgeVector& incoming = n->getIncomingEdges();
     102     2957441 :     return std::find(incoming.begin(), incoming.end(), myEdge) != incoming.end();
     103             : }
     104             : 
     105             : 
     106             : 
     107             : /* -------------------------------------------------------------------------
     108             :  * methods from node_with_outgoing_finder
     109             :  * ----------------------------------------------------------------------- */
     110     1187908 : NBContHelper::node_with_outgoing_finder::node_with_outgoing_finder(const NBEdge* const e)
     111     1187908 :     : myEdge(e) {}
     112             : 
     113             : 
     114             : bool
     115     2968897 : NBContHelper::node_with_outgoing_finder::operator()(const NBNode* const n) const {
     116             :     const EdgeVector& outgoing = n->getOutgoingEdges();
     117     2968897 :     return std::find(outgoing.begin(), outgoing.end(), myEdge) != outgoing.end();
     118             : }
     119             : 
     120             : 
     121             : /* -------------------------------------------------------------------------
     122             :  * methods from edge_with_destination_finder
     123             :  * ----------------------------------------------------------------------- */
     124           0 : NBContHelper::edge_with_destination_finder::edge_with_destination_finder(NBNode* dest)
     125           0 :     : myDestinationNode(dest) {}
     126             : 
     127             : 
     128             : bool
     129           0 : NBContHelper::edge_with_destination_finder::operator()(NBEdge* e) const {
     130           0 :     return e->getToNode() == myDestinationNode;
     131             : }
     132             : 
     133             : 
     134             : /* -------------------------------------------------------------------------
     135             :  * methods from relative_outgoing_edge_sorter
     136             :  * ----------------------------------------------------------------------- */
     137             : bool
     138      264536 : NBContHelper::relative_outgoing_edge_sorter::operator()(const NBEdge* e1, const NBEdge* e2) const {
     139             :     assert(e1 != nullptr && e2 != nullptr);
     140      264536 :     double relAngle1 = NBHelpers::normRelAngle(myAngle, e1->getStartAngle());
     141      264536 :     double relAngle2 = NBHelpers::normRelAngle(myAngle, e2->getStartAngle());
     142      264536 :     const double length1 = e1->getGeometry().length2D();
     143      264536 :     const double length2 = e2->getGeometry().length2D();
     144             : 
     145      264536 :     double lookAhead = 2 * NBEdge::ANGLE_LOOKAHEAD;
     146      265033 :     while (fabs(relAngle1 - relAngle2) < 3.0) {
     147             :         // look at further geometry segments to resolve ambiguity
     148             :         const double offset1 = MAX2(0.0, MIN2(length1, lookAhead));
     149             :         const double offset2 = MAX2(0.0, MIN2(length2, lookAhead));
     150         801 :         const Position referencePos1 = e1->getGeometry().positionAtOffset2D(offset1);
     151         801 :         const Position referencePos2 = e2->getGeometry().positionAtOffset2D(offset2);
     152         801 :         const double angle1 = GeomHelper::legacyDegree(e1->getFromNode()->getPosition().angleTo2D(referencePos1), true);
     153         801 :         const double angle2 = GeomHelper::legacyDegree(e2->getFromNode()->getPosition().angleTo2D(referencePos2), true);
     154         801 :         relAngle1 = NBHelpers::normRelAngle(myAngle, angle1);
     155         801 :         relAngle2 = NBHelpers::normRelAngle(myAngle, angle2);
     156         801 :         if (lookAhead > MAX2(length1, length2)) {
     157             :             break;
     158             :         }
     159         497 :         lookAhead *= 2;
     160             :     }
     161      264536 :     if (fabs(relAngle1 - relAngle2) < NUMERICAL_EPS) {
     162             :         // need to break ties for windows debug version, numerical id may be -1 for both
     163         201 :         return e1->getID() > e2->getID();
     164             :     }
     165      264335 :     return relAngle1 > relAngle2;
     166             : }
     167             : 
     168             : 
     169             : /* -------------------------------------------------------------------------
     170             :  * methods from relative_incoming_edge_sorter
     171             :  * ----------------------------------------------------------------------- */
     172             : bool
     173        4703 : NBContHelper::relative_incoming_edge_sorter::operator()(const NBEdge* e1, const NBEdge* e2) const {
     174             :     assert(e1 != nullptr && e2 != nullptr);
     175        4703 :     double relAngle1 = NBHelpers::normRelAngle(myAngle, e1->getEndAngle());
     176        4703 :     double relAngle2 = NBHelpers::normRelAngle(myAngle, e2->getEndAngle());
     177        4703 :     const double length1 = e1->getGeometry().length2D();
     178        4703 :     const double length2 = e2->getGeometry().length2D();
     179             : 
     180        4703 :     double lookAhead = 2 * NBEdge::ANGLE_LOOKAHEAD;
     181        4779 :     while (fabs(relAngle1 - relAngle2) < 3.0) {
     182             :         // look at further geometry segments to resolve ambiguity
     183          83 :         const double offset1 = MAX2(0.0, MIN2(length1, length1 - lookAhead));
     184          83 :         const double offset2 = MAX2(0.0, MIN2(length2, length2 - lookAhead));
     185          83 :         const Position referencePos1 = e1->getGeometry().positionAtOffset2D(offset1);
     186          83 :         const Position referencePos2 = e2->getGeometry().positionAtOffset2D(offset2);
     187          83 :         const double angle1 = GeomHelper::legacyDegree(referencePos1.angleTo2D(e1->getToNode()->getPosition()), true);
     188          83 :         const double angle2 = GeomHelper::legacyDegree(referencePos2.angleTo2D(e2->getToNode()->getPosition()), true);
     189          83 :         relAngle1 = NBHelpers::normRelAngle(myAngle, angle1);
     190          83 :         relAngle2 = NBHelpers::normRelAngle(myAngle, angle2);
     191          83 :         if (lookAhead > MAX2(length1, length2)) {
     192             :             break;
     193             :         }
     194          76 :         lookAhead *= 2;
     195             :     }
     196        4703 :     if (fabs(relAngle1 - relAngle2) < NUMERICAL_EPS) {
     197             :         // need to break ties for windows debug version, numerical id may be -1 for both
     198           4 :         return e1->getID() > e2->getID();
     199             :     }
     200        4699 :     return relAngle1 > relAngle2;
     201             : }
     202             : 
     203             : 
     204             : std::ostream&
     205           0 : operator<<(std::ostream& os, const EdgeVector& ev) {
     206           0 :     for (EdgeVector::const_iterator i = ev.begin(); i != ev.end(); i++) {
     207           0 :         if (i != ev.begin()) {
     208           0 :             os << ", ";
     209             :         }
     210           0 :         os << (*i)->getID();
     211             :     }
     212           0 :     return os;
     213             : }
     214             : 
     215             : 
     216             : double
     217           0 : NBContHelper::getMaxSpeed(const EdgeVector& edges) {
     218           0 :     if (edges.size() == 0) {
     219             :         return -1;
     220             :     }
     221           0 :     double ret = (*(edges.begin()))->getSpeed();
     222           0 :     for (EdgeVector::const_iterator i = edges.begin() + 1; i != edges.end(); i++) {
     223           0 :         if ((*i)->getSpeed() > ret) {
     224           0 :             ret = (*i)->getSpeed();
     225             :         }
     226             :     }
     227             :     return ret;
     228             : }
     229             : 
     230             : 
     231             : double
     232           0 : NBContHelper::getMinSpeed(const EdgeVector& edges) {
     233           0 :     if (edges.size() == 0) {
     234             :         return -1;
     235             :     }
     236           0 :     double ret = (*(edges.begin()))->getSpeed();
     237           0 :     for (EdgeVector::const_iterator i = edges.begin() + 1; i != edges.end(); i++) {
     238           0 :         if ((*i)->getSpeed() < ret) {
     239           0 :             ret = (*i)->getSpeed();
     240             :         }
     241             :     }
     242             :     return ret;
     243             : }
     244             : 
     245             : 
     246             : bool
     247     3298267 : NBContHelper::edge_by_angle_to_nodeShapeCentroid_sorter::operator()(const NBEdge* e1, const NBEdge* e2) const {
     248             :     assert(e1->getFromNode() == myNode || e1->getToNode() == myNode);
     249             :     assert(e2->getFromNode() == myNode || e2->getToNode() == myNode);
     250     3298267 :     const double angle1 = e1->getAngleAtNodeToCenter(myNode);
     251     3298267 :     const double angle2 = e2->getAngleAtNodeToCenter(myNode);
     252     3298267 :     const double absDiff = fabs(angle1 - angle2);
     253             : 
     254             :     // cannot trust the angle difference hence a heuristic:
     255     3298267 :     if (absDiff < 2 || absDiff > (360 - 2)) {
     256      320426 :         const bool sameDir = ((e1->getFromNode() == myNode && e2->getFromNode() == myNode)
     257      698044 :                               || (e1->getToNode() == myNode && e2->getToNode() == myNode));
     258             :         if (sameDir) {
     259             :             // put edges that allow pedestrians on the 'outside', but be aware if both allow / disallow
     260       11707 :             const bool e1Peds = (e1->getPermissions() & SVC_PEDESTRIAN) != 0;
     261       11707 :             const bool e2Peds = (e2->getPermissions() & SVC_PEDESTRIAN) != 0;
     262       11707 :             if (e1->getToNode() == myNode) {
     263        6457 :                 if (e1Peds && !e2Peds) {
     264             :                     return true;
     265        5799 :                 } else if (!e1Peds && e2Peds) {
     266             :                     return false;
     267             :                 }
     268             :             } else {
     269        5250 :                 if (!e1Peds && e2Peds) {
     270             :                     return true;
     271        4756 :                 } else if (e1Peds && !e2Peds) {
     272             :                     return false;
     273             :                 }
     274             :             }
     275             :             // break ties to ensure strictly weak ordering
     276        7938 :             return e1->getID() < e2->getID();
     277             :         } else {
     278             :             // sort incoming before outgoing, no need to break ties here
     279      371161 :             return e1->getToNode() == myNode;
     280             :         }
     281             :     }
     282     2915399 :     return angle1 < angle2;
     283             : }
     284             : 
     285             : 
     286             : /****************************************************************************/

Generated by: LCOV version 1.14