SUMO - Simulation of Urban MObility
NIXMLTrafficLightsHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // Importer for traffic lights stored in XML
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2011-2016 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <string>
34 #include <iostream>
35 #include <xercesc/sax/HandlerBase.hpp>
36 #include <xercesc/sax/AttributeList.hpp>
37 #include <xercesc/sax/SAXParseException.hpp>
38 #include <xercesc/sax/SAXException.hpp>
42 #include <utils/common/ToString.h>
47 #include <netbuild/NBEdge.h>
48 #include <netbuild/NBEdgeCont.h>
49 #include <netbuild/NBNode.h>
50 #include <netbuild/NBOwnTLDef.h>
53 #include "NIImporter_SUMO.h"
55 
56 
57 // ===========================================================================
58 // method definitions
59 // ===========================================================================
61  NBTrafficLightLogicCont& tlCont, NBEdgeCont& ec) :
62  SUMOSAXHandler("xml-tllogics"),
63  myTLLCont(tlCont),
64  myEdgeCont(ec),
65  myCurrentTL(0),
66  myResetPhases(false) {
67 }
68 
69 
71 
72 
73 void
75  int element, const SUMOSAXAttributes& attrs) {
76  switch (element) {
77  case SUMO_TAG_TLLOGIC:
79  break;
80  case SUMO_TAG_PHASE:
81  if (myCurrentTL != 0) {
82  if (myResetPhases) {
84  myResetPhases = false;
85  }
87  }
88  break;
90  addTlConnection(attrs);
91  break;
92  case SUMO_TAG_DELETE:
93  removeTlConnection(attrs);
94  break;
95  default:
96  break;
97  }
98 }
99 
100 
101 void
103  switch (element) {
104  case SUMO_TAG_TLLOGIC:
105  if (!myCurrentTL) {
106  WRITE_ERROR("Unmatched closing tag for tlLogic.");
107  } else {
108  myCurrentTL = 0;
109  }
110  break;
111  default:
112  break;
113  }
114 }
115 
116 
119  if (currentTL) {
120  WRITE_ERROR("Definition of tlLogic '" + currentTL->getID() + "' was not finished.");
121  return 0;
122  }
123  bool ok = true;
124  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
125  std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
126  SUMOTime offset = attrs.hasAttribute(SUMO_ATTR_OFFSET) ? TIME2STEPS(attrs.get<double>(SUMO_ATTR_OFFSET, id.c_str(), ok)) : 0;
127  std::string typeS = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, 0, ok,
128  OptionsCont::getOptions().getString("tls.default-type"));
129  TrafficLightType type;
130  if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
132  } else {
133  WRITE_ERROR("Unknown traffic light type '" + typeS + "' for tlLogic '" + id + "'.");
134  return 0;
135  }
136  // there are three scenarios to consider
137  // 1) the tll.xml is loaded to update traffic lights defined in a net.xml:
138  // simply retrieve the loaded definitions and update them
139  // 2) the tll.xml is loaded to define new traffic lights
140  // nod.xml will have triggered building of NBOwnTLDef. Replace it with NBLoadedSUMOTLDef
141  // 3) the tll.xml is loaded to define new programs for a defined traffic light
142  // there should be a definition with the same id but different programID
143  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(id);
144  if (programs.size() == 0) {
145  WRITE_ERROR("Cannot load traffic light program for unknown id '" + id + "', programID '" + programID + "'.");
146  return 0;
147  }
148  const std::string existingProgram = programs.begin()->first; // arbitrary for our purpose
149  NBLoadedSUMOTLDef* loadedDef = dynamic_cast<NBLoadedSUMOTLDef*>(myTLLCont.getDefinition(id, programID));
150  if (loadedDef == 0) {
151  NBLoadedSUMOTLDef* oldDef = dynamic_cast<NBLoadedSUMOTLDef*>(myTLLCont.getDefinition(id, existingProgram));
152  if (oldDef == 0) {
153  // case 2
156  if (newDef == 0) {
157  // the default program may have already been replaced with a loaded program
158  newDef = dynamic_cast<NBLoadedSUMOTLDef*>(myTLLCont.getDefinition(
160  if (newDef == 0) {
161  WRITE_ERROR("Cannot load traffic light program for unknown id '" + id + "', programID '" + programID + "'.");
162  return 0;
163  }
164  }
165  assert(newDef != 0);
166  loadedDef = new NBLoadedSUMOTLDef(id, programID, offset, type);
167  // copy nodes and controlled inner edges
168  std::vector<NBNode*> nodes = newDef->getNodes();
169  for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
170  loadedDef->addNode(*it);
171  }
172  loadedDef->addControlledInnerEdges(newDef->getControlledInnerEdges());
174  // replace default Program
175  std::vector<NBNode*> nodes = newDef->getNodes();
176  for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
177  (*it)->removeTrafficLight(newDef);
178  }
180  }
181  myTLLCont.insert(loadedDef);
182  } else {
183  // case 3
184  NBTrafficLightLogic* oldLogic = oldDef->getLogic();
185  NBTrafficLightLogic* newLogic = new NBTrafficLightLogic(id, programID,
186  oldLogic->getNumLinks(), offset, type);
187  loadedDef = new NBLoadedSUMOTLDef(oldDef, newLogic);
188  // copy nodes
189  std::vector<NBNode*> nodes = oldDef->getNodes();
190  for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
191  loadedDef->addNode(*it);
192  }
193  myTLLCont.insert(loadedDef);
194  }
195  } else {
196  // case 1
197  loadedDef->setOffset(offset);
198  loadedDef->setType(type);
199  }
200  if (ok) {
201  myResetPhases = true;
202  return loadedDef;
203  } else {
204  return 0;
205  }
206 }
207 
208 
209 void
211  bool ok = true;
212  // parse identifying attributes
213  NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok);
214  NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok);
215  if (!ok) {
216  return;
217  }
218  int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok);
219  int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok);
220  if (!ok) {
221  return;
222  }
223  // retrieve connection
224  const std::vector<NBEdge::Connection>& connections = from->getConnections();
225  std::vector<NBEdge::Connection>::const_iterator con_it;
226  con_it = find_if(connections.begin(), connections.end(),
227  NBEdge::connections_finder(fromLane, to, toLane));
228  if (con_it == connections.end()) {
229  WRITE_ERROR("Connection from=" + from->getID() + " to=" + to->getID() +
230  " fromLane=" + toString(fromLane) + " toLane=" + toString(toLane) + " not found");
231  return;
232  }
233  NBEdge::Connection c = *con_it;
234  // read other attributes
235  std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, 0, ok, "");
236  if (tlID == "") {
237  // we are updating an existing tl-controlled connection
238  tlID = c.tlID;
239  assert(tlID != "");
240  }
241  int tlIndex = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX, 0, ok, -1);
242  if (tlIndex == -1) {
243  // we are updating an existing tl-controlled connection
244  tlIndex = c.tlLinkNo;
245  }
246 
247  // register the connection with all definitions
248  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(tlID);
249  if (programs.size() > 0) {
250  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
251  for (it = programs.begin(); it != programs.end(); it++) {
252  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
253  if (tlDef) {
254  tlDef->addConnection(from, c.toEdge, c.fromLane, c.toLane, tlIndex);
255  } else {
256  throw ProcessError("Corrupt traffic light definition '"
257  + tlID + "' (program '" + it->first + "')");
258  }
259  }
260  } else {
261  SumoXMLNodeType type = from->getToNode()->getType();
262  if (type != NODETYPE_RAIL_CROSSING && type != NODETYPE_RAIL_SIGNAL) {
263  WRITE_ERROR("The traffic light '" + tlID + "' is not known.");
264  }
265  }
266 }
267 
268 
269 void
271  bool ok = true;
272  std::string tlID = attrs.get<std::string>(SUMO_ATTR_TLID, 0, ok);
273  // does the traffic light still exist?
274  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(tlID);
275  if (programs.size() > 0) {
276  // parse identifying attributes
277  NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok);
278  NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok);
279  if (!ok) {
280  return;
281  }
282  int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok);
283  int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok);
284  if (!ok) {
285  return;
286  }
287  int tlIndex = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, 0, ok);
288 
289  NBConnection conn(from, fromLane, to, toLane, tlIndex);
290  // remove the connection from all definitions
291  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
292  for (it = programs.begin(); it != programs.end(); it++) {
293  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
294  if (tlDef) {
295  tlDef->removeConnection(conn, false);
296  } else {
297  throw ProcessError("Corrupt traffic light definition '"
298  + tlID + "' (program '" + it->first + "')");
299  }
300  }
301  }
302 }
303 
304 
305 NBEdge*
307  const SUMOSAXAttributes& attrs, SumoXMLAttr attr, bool& ok) {
308  std::string edgeID = attrs.get<std::string>(attr, 0, ok);
309  NBEdge* edge = myEdgeCont.retrieve(edgeID, true);
310  if (edge == 0) {
311  WRITE_ERROR("Unknown edge '" + edgeID + "' given in connection.");
312  ok = false;
313  }
314  return edge;
315 }
316 
317 
318 int
320  const SUMOSAXAttributes& attrs, SumoXMLAttr attr, NBEdge* edge, bool& ok) {
321  int laneIndex = attrs.get<int>(attr, 0, ok);
322  if (edge->getNumLanes() <= laneIndex) {
323  WRITE_ERROR("Invalid lane index '" + toString(laneIndex) + "' for edge '" + edge->getID() + "'.");
324  ok = false;
325  }
326  return laneIndex;
327 }
328 
329 
330 /****************************************************************************/
331 
int tlLinkNo
The index of this connection within the controlling traffic light.
Definition: NBEdge.h:196
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
void removeConnection(const NBConnection &conn, bool reconstruct=true)
removes the given connection from the traffic light if recontruct=true, reconstructs the logic and in...
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
A structure which describes a connection between edges or lanes.
Definition: NBEdge.h:164
int toLane
The lane the connections yields in.
Definition: NBEdge.h:190
static void addPhase(const SUMOSAXAttributes &attrs, NBLoadedSUMOTLDef *currentTL)
adds a phase to the traffic lights logic currently build
bool removeProgram(const std::string id, const std::string programID, bool del=true)
Removes a program of a logic definition from the dictionary.
virtual void addNode(NBNode *node)
Adds a node to the traffic light logic.
NBEdge * toEdge
The edge the connections yields in.
Definition: NBEdge.h:187
void setOffset(SUMOTime offset)
Sets the offset of this tls.
int getNumLinks()
Returns the number of participating links.
A loaded (complete) traffic light logic.
NBEdgeCont & myEdgeCont
The edge container for retrieving edges.
A container for traffic light definitions and built programs.
A SUMO-compliant built logic for a traffic light.
NBEdge * retrieveEdge(const SUMOSAXAttributes &attrs, SumoXMLAttr attr, bool &ok)
parses and edge id an returns an existing edge
connectio between two lanes
The representation of a single edge during network building.
Definition: NBEdge.h:71
The base class for traffic light logic definitions.
link,node: the traffic light id responsible for this link
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
const std::string & getID() const
Returns the id.
Definition: Named.h:66
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
NBLoadedSUMOTLDef * initTrafficLightLogic(const SUMOSAXAttributes &attrs, NBLoadedSUMOTLDef *currentTL)
SAX-handler base for SUMO-files.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:65
NBTrafficLightLogicCont & myTLLCont
The traffic light container to fill.
int retrieveLaneIndex(const SUMOSAXAttributes &attrs, SumoXMLAttr attr, NBEdge *edge, bool &ok)
parses a lane index and verifies its correctness
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
NBTrafficLightDefinition * getDefinition(const std::string &id, const std::string &programID) const
Returns the named definition.
Encapsulated SAX-Attributes.
std::string tlID
The id of the traffic light that controls this connection.
Definition: NBEdge.h:193
void addTlConnection(const SUMOSAXAttributes &attrs)
reads and adds tl-controlled connection
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:413
int fromLane
The lane the connections starts at.
Definition: NBEdge.h:184
T get(const std::string &str) const
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
NBLoadedSUMOTLDef * myCurrentTL
The currently parsed traffic light.
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
void removeTlConnection(const SUMOSAXAttributes &attrs)
reads and removes tl-controlled connection
NBTrafficLightLogic * getLogic()
Returns the internal logic.
static const std::string DefaultProgramID
void addControlledInnerEdges(const std::vector< std::string > &edges)
Adds the given ids into the list of inner edges controlled by the tls.
bool myResetPhases
whether phases of a previously loaded traffic light must be reset
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
void myEndElement(int element)
Called when a closing tag occurs.
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:834
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:251
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:257
NIXMLTrafficLightsHandler(NBTrafficLightLogicCont &tlCont, NBEdgeCont &ec)
Constructor.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
link: the index of the link within the traffic light
long long int SUMOTime
Definition: TraCIDefs.h:52
void setType(TrafficLightType type)
Sets the algorithm type of this tls.
a traffic light logic
A traffic light logics which must be computed (only nodes/edges are given)
Definition: NBOwnTLDef.h:54
delete certain element
std::vector< std::string > getControlledInnerEdges() const
Retrieve the ids of edges explicitly controlled by the tls.
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:434
a single phase description
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex)
Adds a connection and immediately informs the edges.
TrafficLightType