/****************************************************************************/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_OpenDrive.h14/// @author Daniel Krajzewicz15/// @date Tue, 04.05.201116///17// Exporter writing networks using the openDRIVE format18/****************************************************************************/19#pragma once20#include <config.h>2122#include <utils/common/StringBijection.h>23#include <utils/common/SUMOVehicleClass.h>24#include <netbuild/NBEdge.h>252627// ===========================================================================28// class declarations29// ===========================================================================30class NBNetBuilder;31class NBEdge;32class OptionsCont;33class PositionVector;34class OutputDevice;35class OutputDevice_String;36class ShapeContainer;37class PointOfInterest;38class SUMOPolygon;394041// ===========================================================================42// class definitions43// ===========================================================================44/**45* @class NWWriter_OpenDrive46* @brief Exporter writing networks using the openDRIVE format47*48*/49class NWWriter_OpenDrive {50public:51/** @brief Writes the network into a openDRIVE-file52*53* @param[in] oc The options to use54* @param[in] nb The network builder to fill55*/56static void writeNetwork(const OptionsCont& oc, NBNetBuilder& nb);5758protected:59/// @brief signalID -> (lanes, dirs)60typedef std::map<std::string, std::pair<std::set<int>, std::set<LinkDirection> > > SignalLanes;6162/// @brief retrieve divider type63static std::string getDividerType(const NBEdge* e);6465/// @brief write normal edge to device66static void writeNormalEdge(OutputDevice& device, const NBEdge* e,67int edgeID, int fromNodeID, int toNodeID,68const bool origNames,69const double straightThresh,70const ShapeContainer& shc,71SignalLanes& signalLanes,72const std::vector<std::string>& crossings);7374/// @brief write internal edge to device, return next connectionID75static int writeInternalEdge(OutputDevice& device, OutputDevice& junctionDevice,76const NBEdge* inEdge, int nodeID,77int edgeID, int inEdgeID, int outEdgeID,78int connectionID,79const std::vector<NBEdge::Connection>& parallel,80const bool isOuterEdge,81const double straightThresh,82const std::string& centerMark,83SignalLanes& signalLanes);8485static void addPedestrianConnection(const NBEdge* inEdge, const NBEdge* outEdge, std::vector<NBEdge::Connection>& parallel);8687/// @brief write geometry as sequence of lines (sumo style)88static double writeGeomLines(const PositionVector& shape, OutputDevice& device, OutputDevice& elevationDevice, double offset = 0);8990/* @brief write geometry as sequence of lines and bezier curves91*92* @param[in] straightThresh angular changes below threshold are considered to be straight and no curve will be fitted between the segments93* @param[out] length Return the total length of the reference line94*/95static bool writeGeomSmooth(const PositionVector& shape, double speed, OutputDevice& device, OutputDevice& elevationDevice, double straightThresh, double& length);9697/// @brief write geometry as a single bezier curve (paramPoly3)98static double writeGeomPP3(OutputDevice& device,99OutputDevice& elevationDevice,100PositionVector init,101double length,102double offset = 0);103104static void writeElevationProfile(const PositionVector& shape, OutputDevice& device, const OutputDevice_String& elevationDevice);105106static void writeEmptyCenterLane(OutputDevice& device, const std::string& mark, double markWidth);107static int getID(const std::string& origID, StringBijection<int>& map, int& lastID);108109static std::string getLaneType(SVCPermissions permissions);110111/// @brief get the lane border that is closer to the reference line (center line of the edge)112static PositionVector getInnerLaneBorder(const NBEdge* edge, int laneIndex = -1, double widthOffset = 0);113/// @brief get the lane border that is further away from the reference line (center line of the edge)114static PositionVector getOuterLaneBorder(const NBEdge* edge, int laneIndex = -1);115116/// @brief check if the lane geometries are compatible with OpenDRIVE assumptions (colinear stop line)117static void checkLaneGeometries(const NBEdge* e);118119/// @brief write road objects referenced as edge parameters120static void writeRoadObjects(OutputDevice& device, const NBEdge* e, const ShapeContainer& shc, const std::vector<std::string>& crossings);121122/// @brief write signal record for traffic light123static void writeSignals(OutputDevice& device, const NBEdge* e, double length, SignalLanes& signalLanes, const ShapeContainer& shc);124125/// @brief convert sumo lane index to xodr lane index126static int s2x(int sumoIndex, int numLanes);127128/// @brief map pois and polygons to the closes edge129static void mapmatchRoadObjects(const ShapeContainer& shc, const NBEdgeCont& ec);130131static void writeRoadObjectPOI(OutputDevice& device, const NBEdge* e, const PositionVector& roadShape, const PointOfInterest* poi);132133static void writeRoadObjectPoly(OutputDevice& device, const NBEdge* e, const PositionVector& roadShape, const SUMOPolygon* p);134135struct TrafficSign {136std::string country;137std::string type;138std::string subtype;139std::string value;140};141142static std::vector<TrafficSign> parseTrafficSign(const std::string& trafficSign, PointOfInterest* poi);143static TrafficSign parseTrafficSignId(const std::string& trafficSign);144145// @brief return road postion in s,t coordinates146static double getRoadSideOffset(const NBEdge* e);147148149protected:150/// @brief whether a lefthand network is being written151static bool lefthand;152153/* @brief whether a the lanes in a lefthand network shall be written to the154* left of the reference line (positive indices)155* This style is not support by some older programs.156* */157static bool LHLL;158159// lefthand but lanes written as right lanes160static bool LHRL;161162};163164165