/****************************************************************************/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 NIImporter_SUMO.h14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @date Mon, 14.04.200818///19// Importer for networks stored in SUMO format20/****************************************************************************/21#pragma once22#include <config.h>2324#include <string>25#include <map>26#include <utils/xml/SUMOSAXHandler.h>27#include <utils/geom/GeoConvHelper.h>28#include <utils/common/Parameterised.h>29#include <netbuild/NBLoadedSUMOTLDef.h>30#include "NIXMLTypesHandler.h"313233// ===========================================================================34// class declarations35// ===========================================================================36class NBNetBuilder;37class NBEdge;38class OptionsCont;394041// ===========================================================================42// class definitions43// ===========================================================================44/**45* @class NIImporter_SUMO46* @brief Importer for networks stored in SUMO format47*48*/49class NIImporter_SUMO : public SUMOSAXHandler {50public:51/** @brief Loads content of the optionally given SUMO file52*53* If the option "sumo-net-file" is set, the file stored therein is read and54* the network definition stored therein is stored within the given network55* builder.56*57* If the option "sumo-net-file" is not set, this method simply returns.58*59* The loading is done by parsing the network definition as an XML file60* using the SAXinterface and handling the incoming data via this class'61* methods.62*63* @param[in,out] oc The options to use (option no-internal-links may be modified)64* @param[in] nb The network builder to fill65*/66static void loadNetwork(OptionsCont& oc, NBNetBuilder& nb);6768/// begins the reading of a traffic lights logic69static NBLoadedSUMOTLDef* initTrafficLightLogic(const SUMOSAXAttributes& attrs, NBLoadedSUMOTLDef* currentTL);7071/// adds a phase to the traffic lights logic currently build72static void addPhase(const SUMOSAXAttributes& attrs, NBLoadedSUMOTLDef* currentTL);7374/// Parses network location description and registers it with GeoConveHelper::setLoaded75static GeoConvHelper* loadLocation(const SUMOSAXAttributes& attrs, bool setLoaded = true);7677protected:78/** @brief Constructor79* @param[in] nc The network builder to fill80*/81NIImporter_SUMO(NBNetBuilder& nb);8283/// @brief Destructor84~NIImporter_SUMO();8586/// @name inherited from GenericSAXHandler87//@{8889/** @brief Called on the opening of a tag;90*91* In dependence to the obtained type, an appropriate parsing92* method is called ("addEdge" if an edge encounters, f.e.).93*94* @param[in] element ID of the currently opened element95* @param[in] attrs Attributes within the currently opened element96* @exception ProcessError If something fails97* @see GenericSAXHandler::myStartElement98*/99void myStartElement(int element,100const SUMOSAXAttributes& attrs);101102103/** @brief Called when a closing tag occurs104*105* @param[in] element ID of the currently opened element106* @exception ProcessError If something fails107* @see GenericSAXHandler::myEndElement108*/109void myEndElement(int element);110//@}111112113private:114/// @brief load the network115void _loadNetwork(OptionsCont& oc);116117/// @name Object instance parsing methods118//@{119120/** @brief Parses an edge and stores the values in "myCurrentEdge"121* @param[in] attrs The attributes to get the edge's values from122*/123void addEdge(const SUMOSAXAttributes& attrs);124125126/** @brief Parses a lane and stores the values in "myCurrentLane"127* @param[in] attrs The attributes to get the lane's values from128*/129void addLane(const SUMOSAXAttributes& attrs);130131/** @brief parses stop offsets for the current lane or edge132* @param[in] attrs The attributes to get the stop offset specifics from133*/134void addStopOffsets(const SUMOSAXAttributes& attrs, bool& ok);135136/** @brief Parses a junction and saves it in the node control137* @param[in] attrs The attributes to get the junction's values from138*/139void addJunction(const SUMOSAXAttributes& attrs);140141142/** @brief Parses a request and saves selected attributes in myCurrentJunction143* @param[in] attrs The attributes to get the junction's values from144*/145void addRequest(const SUMOSAXAttributes& attrs);146147148/** @brief Parses a connection and saves it149* into the lane's definition stored in "myCurrentLane"150* @param[in] attrs The attributes to get the connection from151*/152void addConnection(const SUMOSAXAttributes& attrs);153154/** @brief Parses a prohibition and saves it155* @param[in] attrs The attributes to get the connection from156*/157void addProhibition(const SUMOSAXAttributes& attrs);158159/** @brief Parses a roundabout and stores it in myEdgeCont.160* @param[in] attrs The attributes to get the roundabouts values from161*/162void addRoundabout(const SUMOSAXAttributes& attrs);163164//@}165166167168private:169/**170* @struct Connection171* @brief A connection description.172*/173class Connection final : public Parameterised {174public:175/// @brief The id of the target edge176std::string toEdgeID;177/// @brief The index of the target lane178int toLaneIdx;179/// @brief The id of the traffic light that controls this connection180std::string tlID;181/// @brief The index of this connection within the controlling traffic light182int tlLinkIndex;183int tlLinkIndex2;184/// @brief Information about being definitely free to drive (on-ramps)185bool mayDefinitelyPass;186/* @brief Whether the junction must be kept clear coming from this connection187* @note: The enum NBEdge::KeepClear is not needed here because data188* from a .net.xml is fully specified */189bool keepClear;190/// @brief custom position for internal junction on this connection191double contPos;192/// @brief custom foe visibility for connection193double visibility;194/// @brief custom permissions for connection195SVCPermissions permissions;196/// @brief custom lane changing permissions for connection197SVCPermissions changeLeft;198/// @brief custom lane changing permissions for connection199SVCPermissions changeRight;200/// @brief custom speed for connection201double speed;202/// @brief custom friction for connection203double friction;204/// @brief custom length for connection205double customLength;206/// @brief custom shape connection207PositionVector customShape;208/// @brief if set to true, This connection will not be TLS-controlled despite its node being controlled.209bool uncontrolled;210/// @brief Whether this connection is an indirect left turn211bool indirectLeft;212/// @brief optional edge type213std::string edgeType;214};215216217/** @struct LaneAttrs218* @brief Describes the values found in a lane's definition219*/220class LaneAttrs final : public Parameterised {221public:222/// @brief The maximum velocity allowed on this lane223double maxSpeed;224/// @brief The friction on this lane225double friction;226/// @brief This lane's shape (may be custom)227PositionVector shape;228/// @brief This lane's connections229std::vector<Connection> connections;230/// @brief This lane's allowed vehicle classes231std::string allow;232/// @brief This lane's disallowed vehicle classes233std::string disallow;234/// @brief This lane's vehicle classes allowed to change left235std::string changeLeft;236/// @brief This lane's vehicle classes allowed to change right237std::string changeRight;238/// @brief The width of this lane239double width;240/// @brief This lane's offset from the intersection241double endOffset;242/// @brief This lane's vehicle specific stop offsets243StopOffset laneStopOffset;244/// @brief Whether this lane is an acceleration lane245bool accelRamp;246/// @brief This lane's opposite lane247std::string oppositeID;248/// @brief Whether this lane has a custom shape249bool customShape;250/// @brief the type of this lane251std::string type;252};253254255/** @struct EdgeAttrs256* @brief Describes the values found in an edge's definition and this edge's lanes257*/258class EdgeAttrs final : public Parameterised {259public:260/// @brief This edge's id261std::string id;262/// @brief This edge's street name263std::string streetName;264/// @brief This edge's type265std::string type;266/// @brief This edge's function267SumoXMLEdgeFunc func;268/// @brief The node this edge starts at269std::string fromNode;270/// @brief The node this edge ends at271std::string toNode;272/// @brief This edges's shape273PositionVector shape;274/// @brief The length of the edge if set explicitly275double length;276/// @brief This edge's priority277int priority;278/// @brief The maximum velocity allowed on this edge (!!!)279double maxSpeed;280/// @brief The friction on this edge281//double friction;282/// @brief This edge's lanes283std::vector<LaneAttrs*> lanes;284/// @brief The built edge285NBEdge* builtEdge;286/// @brief The lane spread function287LaneSpreadFunction lsf;288/// @brief This edge's vehicle specific stop offsets (used for lanes, that do not have a specified stopOffset)289StopOffset edgeStopOffset;290/// @brief The position at the start of this edge (kilometrage/mileage)291double distance;292/// @brief the bidi edge293std::string bidi;294};295296297/** @struct Prohibition298* @brief Describes the values found in a prohibition299*/300struct Prohibition {301std::string prohibitorFrom;302std::string prohibitorTo;303std::string prohibitedFrom;304std::string prohibitedTo;305};306307/** @struct Crossing308* @brief Describes a pedestrian crossing309*/310struct Crossing : public Parameterised {311Crossing(const std::string& _edgeID) :312edgeID(_edgeID), customTLIndex(-1), customTLIndex2(-1) {}313314std::string edgeID;315std::vector<std::string> crossingEdges;316double width;317bool priority;318PositionVector customShape;319int customTLIndex;320int customTLIndex2;321};322323/** @struct WalkingAreaParsedCustomShape324* @brief Describes custom shape for a walking area during parsing325*/326struct WalkingAreaParsedCustomShape {327PositionVector shape;328std::vector<std::string> fromEdges;329std::vector<std::string> toEdges;330std::vector<std::string> fromCrossed;331std::vector<std::string> toCrossed;332double width;333};334335/** @struct JunctionAttrs336* @brief Describes the values found in a junction337*/338struct JunctionAttrs {339NBNode* node;340// @the list of internal lanes corresponding to each link341std::vector<std::string> intLanes;342// @brief the complete response definition for all links343std::vector<std::string> response;344};345346/// @brief Loaded edge definitions347std::map<std::string, EdgeAttrs*> myEdges;348349/// @brief Loaded prohibitions350std::vector<Prohibition> myProhibitions;351352/// @brief The network builder to fill353NBNetBuilder& myNetBuilder;354355/// @brief The node container to fill356NBNodeCont& myNodeCont;357358/// @brief The node container to fill359NBTrafficLightLogicCont& myTLLCont;360361/// @brief The handler for parsing edge types and restrictions362NIXMLTypesHandler myTypesHandler;363364/// @brief The currently parsed edge's definition (to add loaded lanes to)365EdgeAttrs* myCurrentEdge;366367/// @brief The currently parsed junction definition to help in reconstructing crossings368JunctionAttrs myCurrentJunction;369370/// @brief The currently parsed lanes's definition (to add the shape to)371LaneAttrs* myCurrentLane;372373/// @brief The currently parsed traffic light374NBLoadedSUMOTLDef* myCurrentTL;375376/// @brief The coordinate transformation which was used to build the loaded network.377GeoConvHelper* myLocation;378379/// @brief The pedestrian crossings found in the network380std::map<std::string, std::vector<Crossing> > myPedestrianCrossings;381382/// @brief Map from walkingArea edge IDs to custom shapes383std::map<std::string, WalkingAreaParsedCustomShape> myWACustomShapes;384385/// @brief element to receive parameters386std::vector<Parameterised*> myLastParameterised;387388/// @brief the loaded network version389MMVersion myNetworkVersion;390391/// @brief whether the loaded network contains internal lanes392bool myHaveSeenInternalEdge;393394/// @brief whether the loaded network was built for lefthand traffic395bool myAmLefthand;396397/// @brief whether the written network should have a different "handedness" (LHT/RHT) than the loaded network398bool myChangeLefthand;399400/// @brief the level of corner detail in the loaded network401int myCornerDetail;402403/// @brief the level of geometry detail for internal lanes in the loaded network404int myLinkDetail;405406/// @brief whether all lanes of an edge should have the same stop line407bool myRectLaneCut;408409/// @brief whether walkingareas must be built410bool myWalkingAreas;411412/// @brief whether turning speed was limited in the network413double myLimitTurnSpeed;414415/// @brief whether foe-relationships where checked at lane-level416bool myCheckLaneFoesAll;417bool myCheckLaneFoesRoundabout;418/// @brief whether some right-of-way checks at traffic light junctions should be disabled419bool myTlsIgnoreInternalJunctionJam;420/// @brief default spreadType defined in the network421std::string myDefaultSpreadType;422/// @brief overlap option for loaded network423bool myGeomAvoidOverlap;424/// @brief higherSpeed option for loaded network425bool myJunctionsHigherSpeed;426/// @brief custom settings for internal junction computation427double myInternalJunctionsVehicleWidth;428/// @brief custom settings for junction shape computation429bool myJunctionsMinimalShape;430bool myJunctionsEndpointShape;431432/// @brief loaded roundabout edges433std::vector<std::vector<std::string> > myRoundabouts;434435/// @brief list of node id with rail signals (no NBTrafficLightDefinition exists)436std::set<std::string> myRailSignals;437438/// @brief list of parameter keys to discard439std::set<std::string> myDiscardableParams;440441private:442443/// @brief read position from the given attributes, attribute errors to id444static Position readPosition(const SUMOSAXAttributes& attrs, const std::string& id, bool& ok);445446/** @brief parses connection string of a prohibition (very old school)447* @param[in] attr The connection attribute448* @param[out] from ID of the source edge449* @param[out] to ID of the destination edge450* @param[out] ok Whether parsing completed successfully451*/452void parseProhibitionConnection(const std::string& attr, std::string& from, std::string& to, bool& ok);453};454455456