/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file NBNodeShapeComputer.h14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @date 2004-01-1218///19// This class computes shapes of junctions20/****************************************************************************/21#pragma once22#include <config.h>2324#include <utils/geom/PositionVector.h>252627// ===========================================================================28// class definitions29// ===========================================================================30class NBNode;31class NBEdge;323334// ===========================================================================35// class declarations36// ===========================================================================37/**38* @class NBNodeShapeComputer39* @brief This class computes shapes of junctions40*/41class NBNodeShapeComputer {42public:43/// Constructor44NBNodeShapeComputer(const NBNode& node);4546/// Destructor47~NBNodeShapeComputer();4849/// Computes the shape of the assigned junction50const PositionVector compute(bool forceSmall);5152/// @brief get computed radius for node53double getRadius() const {54return myRadius;55}5657private:58typedef std::map<NBEdge*, PositionVector> GeomsMap;5960/** @brief Computes the node geometry61* Edges with the same direction are grouped.62* Then the node geometry is built from intersection between the borders63* of adjacent edge groups64*/65const PositionVector computeNodeShapeDefault(bool simpleContinuation);6667/** @brief Computes the node geometry using normals68*69* In the case the other method does not work, this method computes the geometry70* of a node by adding points to the polygon which are computed by building71* the normals of participating edges' geometry boundaries (cw/ccw)72* at the node's height (the length of the edge the edge would cross the node73* point).74*75* @note This usually gives a very small node shape, appropriate for76* dead-ends or turn-around-only situations77*/78const PositionVector computeNodeShapeSmall();7980/// @brief compute clockwise/counter-clockwise edge boundaries81void computeEdgeBoundaries(const EdgeVector& edges,82GeomsMap& geomsCCW,83GeomsMap& geomsCW);8485/** @brief Joins edges and computes ccw/cw boundaries86*87* This method goes through all edges and stores each edge's ccw and cw88* boundary in geomsCCW/geomsCW. This boundary is extrapolated by 100m89* at the node's position.90* In addition, "same" is filled so that this map contains a list of91* all edges within the value-vector which direction at the node differs92* less than 1 from the key-edge's direction.93*/94void joinSameDirectionEdges(const EdgeVector& edges, std::map<NBEdge*, std::set<NBEdge*, ComparatorIdLess> >& same, bool useEndpoints);9596/** @brief Joins edges97*98* This methods joins edges which are in marked as being "same" in the means99* as given by joinSameDirectionEdges. The result (list of so-to-say "directions"100* is returned;101*/102EdgeVector computeUniqueDirectionList(103const EdgeVector& all,104std::map<NBEdge*, std::set<NBEdge*, ComparatorIdLess> >& same,105GeomsMap& geomsCCW,106GeomsMap& geomsCW);107108/** @brief Compute smoothed corner shape109* @param[in] begShape110* @param[in] endShape111* @param[in] begPoint112* @param[in] endPoint113* @param[in] cornerDetail114* @return shape to be appended between begPoint and endPoint115*/116PositionVector getSmoothCorner(PositionVector begShape, PositionVector endShape,117const Position& begPoint, const Position& endPoint, int cornerDetail);118119/** @brief Initialize neighbors and angles120* @param[in] edges The list of edges sorted in clockwise direction121* @param[in] current An iterator to the current edge122* @param[in] geomsCW geometry map123* @param[in] geomsCCW geometry map124* @param[out] cwi An iterator to the clockwise neighbor125* @param[out] ccwi An iterator to the counter-clockwise neighbor126* @param[out] cad The angle difference to the clockwise neighbor127* @param[out] ccad The angle difference to the counter-clockwise neighbor128*/129static void initNeighbors(const EdgeVector& edges, const EdgeVector::const_iterator& current,130GeomsMap& geomsCW,131GeomsMap& geomsCCW,132EdgeVector::const_iterator& cwi,133EdgeVector::const_iterator& ccwi,134double& cad,135double& ccad);136137/// @return whether trying to intersect these edges would probably fail138bool badIntersection(const NBEdge* e1, const NBEdge* e2, double distance);139140/// @brief return the intersection point closest to the given offset141double closestIntersection(const PositionVector& geom1, const PositionVector& geom2, double offset);142143/// @brief whether the given edges (along with those in the same direction) requires a large turning radius144bool needsLargeTurn(NBEdge* e1, NBEdge* e2,145std::map<NBEdge*, std::set<NBEdge*, ComparatorIdLess> >& same) const;146147/// @brief determine the default radius appropriate for the current junction148double getDefaultRadius(const OptionsCont& oc);149150void computeSameEnd(PositionVector& l1, PositionVector& l2);151152bool isDivided(const NBEdge* e, std::set<NBEdge*, ComparatorIdLess> same, const PositionVector& ccw, const PositionVector& cw) const;153154/// @brief compute with of rightmost lanes that exlude the given permissions155static double getExtraWidth(const NBEdge* e, SVCPermissions exclude);156157/// @brief compute the width of the divider space for divided roads158static double divisionWidth(const NBEdge* e, std::set<NBEdge*, ComparatorIdLess> same, const Position& p, const Position& p2);159160private:161/// The node to compute the geometry for162const NBNode& myNode;163164/// @brief the computed node radius165double myRadius;166167/// @brief the maximum distance to search for a place where neighboring edges intersect and do not overlap168double EXT;169170static const SVCPermissions SVC_LARGE_TURN;171172private:173/// @brief Invalidated assignment operator174NBNodeShapeComputer& operator=(const NBNodeShapeComputer& s);175176};177178179