/****************************************************************************/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 NBNetBuilder.h14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Sascha Krieg17/// @author Michael Behrisch18/// @author Gregor Laemmel19/// @date Fri, 29.04.200520///21// Instance responsible for building networks22/****************************************************************************/23#pragma once24#include <config.h>2526#include <string>27#include <iostream>28#include <vector>29#include <set>30#include <utils/shapes/ShapeContainer.h>31#include "NBEdgeCont.h"32#include "NBTypeCont.h"33#include "NBNodeCont.h"34#include "NBNode.h"35#include "NBParking.h"36#include "NBTrafficLightLogicCont.h"37#include "NBDistrictCont.h"38#include "NBPTStopCont.h"39#include "NBPTLineCont.h"40#include <utils/common/UtilExceptions.h>414243// ===========================================================================44// class declarations45// ===========================================================================46class OptionsCont;47class OutputDevice;48class GeoConvHelper;495051// ===========================================================================52// class definitions53// ===========================================================================54/**55* @class NBNetBuilder56* @brief Instance responsible for building networks57*58* The class' - and the netbuild module's - functionality is embedded within the59* compute() method.60*61* @addtogroup netbuild62* @{63*64* -# Removing self loops65* \n Removes edges which end at the node they start at using NBNodeCont::removeSelfLoops().66* -# Joining double connections67* \n Joins edges between same nodes using NBNodeCont::recheckEdges().68* -# Finding isolated roads (optional)69* -# Removing empty nodes and geometry nodes (optional)70* \n Removed nodes with no incoming/outgoing edges and nodes which can be transformed into71* geometry point using NBNodeCont::removeUnwishedNodes().72* -# Removing unwished edges (optional)73* \n If "keep-edges.postload" and "keep-edges.explicit" are set, the edges not within "keep-edges.explicit" are74* removed from the network using NBEdgeCont::removeUnwishedEdges().75* -# Rechecking nodes after edge removal (optional)76* \n If any of the edge removing options was set ("keep-edges.explicit", "remove-edges.explicit", "keep-edges.postload",77* "keep-edges.by-vclass", "keep-edges.input-file"), the now orphaned nodes are removed using78* NBNodeCont::removeUnwishedNodes().79* -# Splitting geometry edges (optional)80* \n If "geometry.split" is set, edge geometries are converted to nodes using81* NBEdgeCont::splitGeometry().82* -# Normalising/transposing node positions83* \n If "offset.disable-normalization", "offset.x", and "offset.y" are not84* set, the road graph's instances are moved to the origin.85* -# Guessing and setting on-/off-ramps86* -# Guessing and setting TLs87* -# Computing turning directions88* -# Sorting nodes' edges89* -# Guessing and setting roundabouts90* -# Computing Approached Edges91* -# Computing Approaching Lanes92* -# Dividing of Lanes on Approached Lanes93* -# Appending Turnarounds (optional)94* -# Rechecking of lane endings95* -# Computing node shapes96* -# Computing edge shapes97* -# Computing tls logics98* -# Computing node logics99* -# Computing traffic light logics100*101* @todo Removing unwished edges: Recheck whether this can be done during loading - whether this option/step is really needed.102* @todo Finding isolated roads: Describe103* @bug Removing empty nodes and geometry nodes: Ok, empty nodes should be removed, uh? But this is only done if "geometry.remove" is set.104* @}105*/106class NBNetBuilder {107friend class GNENet; // for triggering intermediate build steps108109public:110/// @brief Constructor111NBNetBuilder();112113/// @brief Destructor114~NBNetBuilder();115116/** @brief Initialises the storage by applying given options117*118* Options, mainly steering the acceptance of edges, are parsed119* and the according internal variables are set.120*121* @param[in] oc The options container to read options from122* @exception ProcessError If something fails (message is included)123*/124void applyOptions(OptionsCont& oc);125126/** @brief Performs the network building steps127*128* @param[in] oc Container that contains options for building129* @param[in] explicitTurnarounds List of edge ids for which turn-arounds should be added (used by netedit)130* @param[in] mayAddOrRemove whether processing steps which cause nodes and edges to be added or removed shall be triggered (used by netedit)131* @exception ProcessError (recheck)132*/133void compute(OptionsCont& oc, const std::set<std::string>& explicitTurnarounds = std::set<std::string>(), bool mayAddOrRemove = true);134135/// @name Retrieval of subcontainers136/// @{137/// @brief Returns a reference to edge container138inline NBEdgeCont& getEdgeCont() {139return myEdgeCont;140}141142/// @brief Returns a reference to the node container143inline NBNodeCont& getNodeCont() {144return myNodeCont;145}146147/// @brief Returns a reference to the type container148inline NBTypeCont& getTypeCont() {149return myTypeCont;150}151152/// @brief Returns a reference to the traffic light logics container153inline NBTrafficLightLogicCont& getTLLogicCont() {154return myTLLCont;155}156157/// @brief Returns a reference the districts container158inline NBDistrictCont& getDistrictCont() {159return myDistrictCont;160}161162/// @brief Returns a reference to the pt stop container163inline NBPTStopCont& getPTStopCont() {164return myPTStopCont;165}166167/// @brief Returns a reference to the pt line container168inline NBPTLineCont& getPTLineCont() {169return myPTLineCont;170}171172inline NBParkingCont& getParkingCont() {173return myParkingCont;174}175176inline ShapeContainer& getShapeCont() {177return myShapeCont;178}179/// @}180181/// @brief notify about style of loaded network (Without Crossings)182inline bool haveNetworkCrossings() {183return myNetworkHaveCrossings;184}185186/// @brief enable crossing in networks187inline void setHaveNetworkCrossings(bool value) {188myNetworkHaveCrossings = value;189}190191/**192* @brief transforms loaded coordinates193* handles projections, offsets (using GeoConvHelper) and import of height data (using NBHeightMapper)194* @param[in,out] from The coordinate to be transformed195* @param[in] includeInBoundary Whether to patch the convex boundary of the GeoConvHelper default instance196* @param[in] from_srs The spatial reference system of the input coordinate197* @note These methods are located outside of GeoConvHelper to avoid linker-dependencies on GDAL for libgeom198*/199static bool transformCoordinate(Position& from, bool includeInBoundary = true, GeoConvHelper* from_srs = nullptr);200static bool transformCoordinates(PositionVector& from, bool includeInBoundary = true, GeoConvHelper* from_srs = nullptr);201202/// @brief insertion geometry points to ensure maximum segment length between points203static int addGeometrySegments(PositionVector& from, const PositionVector& cartesian, const double maxLength);204205/// @brief whether netbuilding takes place in the context of netedit206static bool runningNetedit();207208209protected:210/**211* @class by_id_sorter212* @brief Sorts nodes by their ids213*/214class by_id_sorter {215public:216/// @brief constructor217explicit by_id_sorter() {}218219/// @brief selection operator220int operator()(const NBNode* n1, const NBNode* n2) const {221return n1->getID() < n2->getID();222}223};224225protected:226/// @brief The used container for nodes227NBNodeCont myNodeCont;228229/// @brief The used container for street types230NBTypeCont myTypeCont;231232/// @brief The used container for edges233NBEdgeCont myEdgeCont;234235/// @brief The used container for traffic light logics236NBTrafficLightLogicCont myTLLCont;237238/// @brief The used container for districts239NBDistrictCont myDistrictCont;240241/// @brief The used container for pt stops242NBPTStopCont myPTStopCont;243244/// @brief The used container for pt stops245NBPTLineCont myPTLineCont;246247NBParkingCont myParkingCont;248249/// @brief container for loaded polygon data250ShapeContainer myShapeCont;251252/// @brief flag to indicate that network has crossings253bool myNetworkHaveCrossings;254255private:256/// @brief shift network so its lower left corner is at 0,0257void moveToOrigin(GeoConvHelper& geoConvHelper, bool lefthand);258259/// @brief ensure consistency between input and output geometries and speeds260void roundInputs();261262/// @brief mirror the network along the X-axis263void mirrorX();264265private:266/// @brief invalidated copy constructor267NBNetBuilder(const NBNetBuilder& s);268269/// @brief invalidated assignment operator270NBNetBuilder& operator=(const NBNetBuilder& s);271};272273274