/****************************************************************************/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 NWWriter_SUMO.h14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @author Leonhard Luecken18/// @date Tue, 04.05.201119///20// Exporter writing networks using the SUMO format21/****************************************************************************/22#pragma once23#include <config.h>2425#include <string>26#include <map>27#include <netbuild/NBEdge.h>28#include <utils/xml/SUMOSAXHandler.h>29#include <utils/common/UtilExceptions.h>30#include <netbuild/NBConnectionDefs.h>313233// ===========================================================================34// class declarations35// ===========================================================================36class OutputDevice;37class OptionsCont;38class NBNetBuilder;39class NBTrafficLightLogic;40class NBTrafficLightLogicCont;41class NBNode;42class NBDistrict;43class NBEdgeControl;444546// ===========================================================================47// class definitions48// ===========================================================================49/**50* @class NWWriter_SUMO51* @brief Exporter writing networks using the SUMO format52*53*/54class NWWriter_SUMO {55public:5657enum ConnectionStyle {58SUMONET, // all connection information59PLAIN, // only edges and link indices60TLL // like plain but include tl information61};6263/** @brief Writes the network into a SUMO-file64*65* @param[in] oc The options to use66* @param[in] nb The network builder to fill67*/68static void writeNetwork(const OptionsCont& oc, NBNetBuilder& nb);697071/** @brief Writes connections outgoing from the given edge (also used in NWWriter_XML)72* @param[in] into The device to write the edge into73* @param[in] from The edge to write connections for74* @param[in] c The connection to write75* @param[in] includeInternal Whether information about inner-lanes used to cross the intersection shall be written76* @param[in] plain Whether only plain-xml output should be written (omit some attributes)77*/78static void writeConnection(OutputDevice& into, const NBEdge& from, const NBEdge::Connection& c,79bool includeInternal, ConnectionStyle style = SUMONET, bool geoAccuracy = false);8081/// @brief writes the given prohibitions82static void writeProhibitions(OutputDevice& into, const NBConnectionProhibits& prohibitions);8384/// @brief writes the traffic light logics to the given device85static void writeTrafficLights(OutputDevice& into, const NBTrafficLightLogicCont& tllCont);8687/// @brief writes a single traffic light logic to the given device88static void writeTrafficLight(OutputDevice& into, const NBTrafficLightLogic* logic);8990/** @brief Writes roundabouts91* @param[in] into The device to write the edge into92* @param[in] roundaboutes The roundabouts to write93* @param[in] ec The edge control to retrieve named edges from94*/95static void writeRoundabouts(OutputDevice& into, const std::set<EdgeSet>& roundabouts,96const NBEdgeCont& ec);9798/** @brief Write a stopOffset element into output device99*/100static void writeStopOffsets(OutputDevice& into, const StopOffset& stopOffset);101102/** @brief Writes a district103* @param[in] into The device to write the edge into104* @param[in] d The district105*/106static void writeDistrict(OutputDevice& into, const NBDistrict& d);107108109private:110/// @name Methods for writing network parts111/// @{112113/** @brief Writes internal edges (<edge ... with id[0]==':') of the given node114* @param[in] into The device to write the edges into115* @param[in] n The node to write the edges of116* @return Whether an internal edge was written117*/118static bool writeInternalEdges(OutputDevice& into, const NBEdgeCont& ec, const NBNode& n);119120121/// @brief retrieve bidi edge id for internal corresponding to the given connection122static std::string getInternalBidi(const NBEdge* e, const NBEdge::Connection& k, double& length);123124125/** @brief Writes an edge (<edge ...)126* @param[in] into The device to write the edge into127* @param[in] e The edge to write128* @param[in] noNames Whether names shall be ignored129* @see writeLane()130*/131static void writeEdge(OutputDevice& into, const NBEdge& e, bool noNames, LaneSpreadFunction defaultSpread);132133134/** @brief Writes a lane (<lane ...) of an edge135* @param[in] into The device to write the edge into136* @param[in] lID The ID of the lane137* @param[in] origID The original ID of the edge in the input138* @param[in] length Lane's length139* @param[in] index The index of the lane within the edge140* @param[in] oppositeID The ID of the opposite lane for overtaking141* @param[in] accelRamp whether this lane is an acceleration lane142* @param[in] customShape whether this lane has a custom shape143*/144static void writeLane(OutputDevice& into, const std::string& lID,145double speed, double friction,146SVCPermissions permissions, SVCPermissions preferred,147SVCPermissions changeLeft, SVCPermissions changeRight,148double startOffset, double endOffset,149const StopOffset& stopOffset, double width, PositionVector shape,150const Parameterised* params, double length, int index,151const std::string& oppositeID, const std::string& type,152bool accelRamp = false,153bool customShape = false,154const PositionVector& outlineShape = PositionVector());155156157/** @brief Writes a junction (<junction ...)158* @param[in] into The device to write the edge into159* @param[in] n The junction/node to write160*/161static void writeJunction(OutputDevice& into, const NBNode& n);162163164/** @brief Writes internal junctions (<junction with id[0]==':' ...) of the given node165* @param[in] into The device to write the edge into166* @param[in] n The junction/node to write internal nodes for167*/168static bool writeInternalNodes(OutputDevice& into, const NBNode& n);169170171/** @brief Writes inner connections within the node172* @param[in] into The device to write the edge into173* @param[in] n The node to write inner links for174*/175static bool writeInternalConnections(OutputDevice& into, const NBNode& n);176177178/** @brief Writes a single internal connection179* @param[in] from The id of the from-edge180* @param[in] to The id of the to-edge181* @param[in] toLane The indexd of the to-lane182* @param[in] via The (optional) via edge183*/184static void writeInternalConnection(OutputDevice& into,185const std::string& from, const std::string& to,186int fromLane, int toLane, const std::string& via,187LinkDirection dir = LinkDirection::STRAIGHT,188const std::string& tlID = "",189int linkIndex = NBConnection::InvalidTlIndex,190bool minor = false,191double visibility = NBEdge::UNSPECIFIED_VISIBILITY_DISTANCE);192193/// @brief writes a SUMOTime as int if possible, otherwise as a float194static std::string writeSUMOTime(SUMOTime time);195196/// @brief the attribute value for a prohibition197static std::string prohibitionConnection(const NBConnection& c);198199/** @brief Writes a roundabout200* @param[in] into The device to write the edge into201* @param[in] r The roundabout to write202* @param[in] ec The edge control to retrieve named edges from203*/204static void writeRoundabout(OutputDevice& into, const std::vector<std::string>& r,205const NBEdgeCont& ec);206207/// @brief retrieve the id of the opposite direction internal lane if it exists208static std::string getOppositeInternalID(const NBEdgeCont& ec, const NBEdge* from, const NBEdge::Connection& con, double& oppositeLength);209210};211212213