Eclipse SUMO - Simulation of Urban MObility
NLNetShapeHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
23 // The XML-Handler for network loading
24 /****************************************************************************/
25 #include <config.h>
26 
27 #include <string>
28 #include <microsim/MSEdge.h>
29 #include <microsim/MSLane.h>
30 #include <microsim/MSLink.h>
31 #include <microsim/MSJunction.h>
33 #include "NLNetShapeHandler.h"
34 
35 
36 // ===========================================================================
37 // method definitions
38 // ===========================================================================
39 NLNetShapeHandler::NLNetShapeHandler(const std::string& file, MSNet& net) :
40  SUMOSAXHandler(file, "net"),
41  myNet(net),
42  myPrimaryEdges(MSEdge::getAllEdges().begin(), MSEdge::getAllEdges().end()) {
43 }
44 
45 
47 
48 
49 void
51  const SUMOSAXAttributes& attrs) {
52  switch (element) {
53  case SUMO_TAG_LANE:
54  addLane(attrs);
55  break;
56  case SUMO_TAG_JUNCTION:
57  addJunction(attrs);
58  break;
60  if (myNet.hasInternalLinks()) {
61  // see sortInternalShapes
62  addConnection(attrs);
63  }
64  break;
65  default:
66  break;
67  }
68 }
69 
70 
71 void
73  bool ok = true;
74  // get the id, report an error if not given or empty...
75  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
76  if (!myNet.hasInternalLinks() && id[0] == ':') {
77  return;
78  }
79  MSLane* lane = MSLane::dictionary(id);
80  if (lane == nullptr) {
81  WRITE_WARNINGF("The lane '%' does not exist in the primary network.", id);
82  return;
83  }
84  const PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
85  lane->addSecondaryShape(shape);
86  myPrimaryEdges.erase(&lane->getEdge());
87 }
88 
89 
90 void
92  bool ok = true;
93  // get the id, report an error if not given or empty...
94  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
95  if (!myNet.hasInternalLinks() && id[0] == ':') {
96  return;
97  }
98  MSJunction* junction = myNet.getJunctionControl().get(id);
99  if (junction == nullptr) {
100  WRITE_WARNINGF("The junction '%' does not exist in the primary network.", id);
101  return;
102  }
103  double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
104  double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
105  double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0);
106  junction->addSecondaryPosition(Position(x, y, z));
107 }
108 
109 
110 void
112  if (!attrs.hasAttribute(SUMO_ATTR_VIA)) {
113  return;
114  }
115  bool ok = true;
116  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
117  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
118  const int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
119  const int toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
120  std::string viaID = attrs.get<std::string>(SUMO_ATTR_VIA, nullptr, ok);
121  MSLane* lane = MSLane::dictionary(viaID);
122  if (lane == nullptr) {
123  // warning already given in addLane
124  return;
125  }
126  std::string fromLaneID = fromID + "_" + toString(fromLaneIdx);
127  std::string toLaneID = toID + "_" + toString(toLaneIdx);
128 
129  if (lane->getLinkCont()[0]->getLane()->getID() != toLaneID
130  || lane->getIncomingLanes()[0].lane->getID() != fromLaneID) {
131  // mismatch: find the correct lane that connects fromLaneID and toLaneID
132  const MSJunction* junction = lane->getEdge().getToJunction();
133  for (MSLane* lane2 : junction->getInternalLanes()) {
134  if (lane2->getLinkCont()[0]->getLane()->getID() == toLaneID
135  && lane2->getIncomingLanes()[0].lane->getID() == fromLaneID) {
136  myShuffledJunctions[junction][lane2] = lane;
137  break;
138  }
139  }
140  }
141 }
142 
143 
144 void
146  // even when the alternative network has the same topology as
147  // the primary network, the ids of internal lanes may differ
148  // since they are based on a clockwise sorting of the edges.
149  // hence we must verify connections and shuffle the shapes as needed
150  for (auto item : myShuffledJunctions) {
151  const MSJunction* junction = item.first;
152  std::map<MSLane*, PositionVector> shapes2;
153  for (MSLane* lane : junction->getInternalLanes()) {
154  shapes2[lane] = lane->getShape(true);
155  }
156 
157  for (auto laneMap : item.second) {
158  laneMap.first->addSecondaryShape(shapes2[laneMap.second]);
159  }
160  }
161  // final warning
162  if (myPrimaryEdges.size() > 0) {
163  WRITE_WARNING(TLF("% edges of the primary network did not occur in the alternative-net-file", myPrimaryEdges.size()));
164  }
165 }
166 /****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#define TLF(string,...)
Definition: MsgHandler.h:317
@ SUMO_TAG_CONNECTION
connectioon between two lanes
@ SUMO_TAG_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_ATTR_VIA
@ SUMO_ATTR_Y
@ SUMO_ATTR_FROM_LANE
@ SUMO_ATTR_Z
@ SUMO_ATTR_X
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_TO_LANE
@ SUMO_ATTR_ID
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A road/street connecting two junctions.
Definition: MSEdge.h:77
The base class for an intersection.
Definition: MSJunction.h:58
const PositionVector & getShape() const
Returns this junction's shape.
Definition: MSJunction.h:91
virtual const std::vector< MSLane * > getInternalLanes() const
Returns all internal lanes on the junction.
Definition: MSJunction.h:120
void addSecondaryPosition(const Position &pos)
used by the gui
Definition: MSJunction.h:81
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
virtual void addSecondaryShape(const PositionVector &)
Definition: MSLane.h:288
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:2375
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:756
The simulated network and simulation perfomer.
Definition: MSNet.h:89
MSJunctionControl & getJunctionControl()
Returns the junctions control.
Definition: MSNet.h:461
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:774
void sortInternalShapes()
resolve mismatch between internal lane ids of both networks
NLNetShapeHandler(const std::string &file, MSNet &net)
Constructor.
void addConnection(const SUMOSAXAttributes &attrs)
records connection topology for later resorting
void addLane(const SUMOSAXAttributes &attrs)
adds a secondary lane shape
std::map< const MSJunction *, std::map< MSLane *, MSLane * > > myShuffledJunctions
mapping between primary internal lane and corresponding secondary internal lane
std::set< const MSEdge * > myPrimaryEdges
lanes of the primary network that should receive a secondary shape
virtual ~NLNetShapeHandler()
Destructor.
MSNet & myNet
The net to fill (preinitialised)
void addJunction(const SUMOSAXAttributes &attrs)
adds a junction position
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
T get(const std::string &id) const
Retrieves an item.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
A list of positions.
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
SAX-handler base for SUMO-files.