/****************************************************************************/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 NIXMLEdgesHandler.h14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @author Leonhard Luecken18/// @date Tue, 20 Nov 200119///20// Importer for network edges stored in XML21/****************************************************************************/22#pragma once23#include <config.h>2425#include <utils/common/SUMOVehicleClass.h>26#include <utils/geom/PositionVector.h>27#include <utils/xml/SUMOSAXHandler.h>28#include <netbuild/NBEdge.h>29#include <netbuild/NBEdgeCont.h>303132// ===========================================================================33// class declarations34// ===========================================================================35class OptionsCont;36class NBNode;37class NBEdge;38class NBNodeCont;39class NBTypeCont;40class NBDistrictCont;41class NBTrafficLightLogicCont;4243// ===========================================================================44// class definitions45// ===========================================================================46/**47* @class NIXMLEdgesHandler48* @brief Importer for network edges stored in XML49*50* This SAX-handler parses edge information and stores it in the given51* container.52* @todo revalidate node retrieval53* @todo One day, one should rethink the order of parsing. Now, the handler54* is able to load edges, using information from the types, first, and extending55* them by given information. In addition, if the read edge is already known,56* its values are also used. Then, defining vehicles allowed per lane, and57* additional edge split definitions add some further complexity. This all58* works somehow for most of our use cases, but it's definitely not as consistent59* that everything what seems to be possible would also work appropriately.60*/61class NIXMLEdgesHandler : public SUMOSAXHandler {62public:63/** @brief Constructor64* @param[in] nc The nodes container (for retrieval of referenced nodes)65* @param[in] ec The edges container (for insertion of build edges)66* @param[in] tc The types container (for retrieval of type defaults)67* @param[in] dc The districts container (needed if an edge must be split)68* @param[in] options The options to use while building edges69*/70NIXMLEdgesHandler(NBNodeCont& nc, NBEdgeCont& ec,71NBTypeCont& tc, NBDistrictCont& dc,72NBTrafficLightLogicCont& tlc,73OptionsCont& options);747576/// @brief Destructor77~NIXMLEdgesHandler();7879protected:80/// @name inherited from GenericSAXHandler81//@{8283/** @brief Called on the opening of a tag;84*85* @param[in] element ID of the currently opened element86* @param[in] attrs Attributes within the currently opened element87* @exception ProcessError If something fails88* @see GenericSAXHandler::myStartElement89*/90void myStartElement(int element,91const SUMOSAXAttributes& attrs);929394/** @brief Called when a closing tag occurs95*96* @param[in] element ID of the currently opened element97* @exception ProcessError If something fails98* @see GenericSAXHandler::myEndElement99*/100void myEndElement(int element);101//@}102103104private:105/** @brief Tries to parse the shape definition106*107* Returns the edge's geometry (may be empty if no one was defined).108* Writes an error message if an error occurred.109* @param[in] attrs The attributes to read the shape from110* @return The edge's shape111*/112PositionVector tryGetShape(const SUMOSAXAttributes& attrs);113114115/** @brief Tries to parse the spread type116*/117LaneSpreadFunction tryGetLaneSpread(const SUMOSAXAttributes& attrs);118119120/** @brief Sets from/to node information of the currently parsed edge121*122* If the nodes could be retrieved/built, they are set in myFromNode/myToNode,123* respectively, and true is returned. If not, false is returned.124* @param[in] attrs The SAX-attributes to parse the nodes from125* @return Whether valid nodes exist126*/127bool setNodes(const SUMOSAXAttributes& attrs);128129130private:131/// @brief A reference to the program's options132OptionsCont& myOptions;133134135/// @name Currently parsed edge's values136/// @{137138/// @brief The current edge's id139std::string myCurrentID;140141/// @brief The current edge's maximum speed142double myCurrentSpeed;143144/// @brief The current edge's friction145double myCurrentFriction;146147/// @brief The current edge's priority148int myCurrentPriority;149150/// @brief The current edge's number of lanes151int myCurrentLaneNo;152153/// @brief The current edge's lane width154double myCurrentWidth;155156/// @brief The current edge's offset till the destination node157double myCurrentEndOffset;158159/// @brief The current edge's street name160std::string myCurrentStreetName;161162/// @brief The current edge's type163std::string myCurrentType;164165/// @brief The nodes the edge starts and ends at166NBNode* myFromNode, *myToNode;167168/// @brief The current edge's length169double myLength;170171/// @brief The shape of the edge172PositionVector myShape;173174/// @brief Information about how to spread the lanes175LaneSpreadFunction myLanesSpread;176177/// @brief Information about lane permissions178SVCPermissions myPermissions;179180/// @brief Whether the edge shape shall be kept at reinitilization181bool myReinitKeepEdgeShape;182183/// @brief The width of the sidewalk that shall be added to the current edge184double mySidewalkWidth;185186/// @brief The width of the bike lane that shall be added to the current edge187double myBikeLaneWidth;188189/// @}190191192/// @brief Whether this edge definition is an update of a previously inserted edge193bool myIsUpdate;194195196/// @name Used instance containers (access to nodes, edges, types, etc.)197/// @{198199/// @brief The nodes container (for retrieval of referenced nodes)200NBNodeCont& myNodeCont;201202/// @brief The edges container (for insertion of build edges)203NBEdgeCont& myEdgeCont;204205/// @brief The types container (for retrieval of type defaults)206NBTypeCont& myTypeCont;207208/// @brief The districts container (needed if an edge must be split)209NBDistrictCont& myDistrictCont;210211/** @brief The traffic lights container to add built tls to (when212* invalidating tls because of splits) */213NBTrafficLightLogicCont& myTLLogicCont;214/// @}215216217/// @brief The currently processed edge218NBEdge* myCurrentEdge;219220/// @brief The currently processed lane index221int myCurrentLaneIndex;222223/// @brief The list of this edge's splits224std::vector<NBEdgeCont::Split> mySplits;225226/** @class split_by_pos_finder227* @brief Finds a split at the given position228*/229class split_by_pos_finder {230public:231/// @brief Constructor232explicit split_by_pos_finder(double pos)233: myPosition(pos) { }234235/// @brief Comparing operator236bool operator()(const NBEdgeCont::Split& e) {237return e.pos == myPosition;238}239240private:241/// @brief The position to search for242double myPosition;243244};245246247/// @brief Information whether at least one edge's attributes were overwritten248bool myHaveReportedAboutOverwriting;249250/// @brief Information whether at least one edge's type was changed251bool myHaveReportedAboutTypeOverride;252253bool myHaveWarnedAboutDeprecatedLaneId;254255/// @brief Whether the edge shape shall be kept generally256const bool myKeepEdgeShape;257258/// @brief element to receive parameters259std::vector<Parameterised*> myLastParameterised;260261/// @brief The coordinate transformation which was used compute the node coordinates262GeoConvHelper* myLocation = nullptr;263264private:265266/** @brief Parses an edge and stores the values in "myCurrentEdge"267* @param[in] attrs The attributes to get the edge's values from268*/269void addEdge(const SUMOSAXAttributes& attrs);270271/** @brief parses delete tag and deletes the specified edge or lane272* @param[in] attrs The attributes to get the edge id and the optional lane index from273*/274void deleteEdge(const SUMOSAXAttributes& attrs);275276/** @brief Parses a lane and modifies myCurrentEdge according to the given277* attribures278* @param[in] attrs The attributes to get the lanes's values from279*/280void addLane(const SUMOSAXAttributes& attrs);281282/** @brief Parses a split and stores it in mySplits. Splits are executed Upon reading the end283* tag of an edge284* @param[in] attrs The attributes to get the splits's values from285*/286void addSplit(const SUMOSAXAttributes& attrs);287288/** @brief Parses a roundabout and stores it in myEdgeCont.289* @param[in] attrs The attributes to get the roundabouts values from290*/291void addRoundabout(const SUMOSAXAttributes& attrs);292293294private:295/** @brief invalid copy constructor */296NIXMLEdgesHandler(const NIXMLEdgesHandler& s);297298/** @brief invalid assignment operator */299NIXMLEdgesHandler& operator=(const NIXMLEdgesHandler& s);300301};302303304