SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 #ifdef CHECK_MEMORY_LEAKS
57 #include <foreign/nvwa/debug_new.h>
58 #endif // CHECK_MEMORY_LEAKS
59 
60 
61 // ===========================================================================
62 // method definitions
63 // ===========================================================================
65  NBTrafficLightLogicCont& tlCont, NBEdgeCont& ec) :
66  SUMOSAXHandler("xml-tllogics"),
67  myTLLCont(tlCont),
68  myEdgeCont(ec),
69  myCurrentTL(0),
70  myResetPhases(false) {
71 }
72 
73 
75 
76 
77 void
79  int element, const SUMOSAXAttributes& attrs) {
80  switch (element) {
81  case SUMO_TAG_TLLOGIC:
83  break;
84  case SUMO_TAG_PHASE:
85  if (myCurrentTL != 0) {
86  if (myResetPhases) {
88  myResetPhases = false;
89  }
91  }
92  break;
94  addTlConnection(attrs);
95  break;
96  case SUMO_TAG_DELETE:
97  removeTlConnection(attrs);
98  break;
99  default:
100  break;
101  }
102 }
103 
104 
105 void
107  switch (element) {
108  case SUMO_TAG_TLLOGIC:
109  if (!myCurrentTL) {
110  WRITE_ERROR("Unmatched closing tag for tlLogic.");
111  } else {
112  myCurrentTL = 0;
113  }
114  break;
115  default:
116  break;
117  }
118 }
119 
120 
123  if (currentTL) {
124  WRITE_ERROR("Definition of tlLogic '" + currentTL->getID() + "' was not finished.");
125  return 0;
126  }
127  bool ok = true;
128  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
129  std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
130  SUMOTime offset = attrs.hasAttribute(SUMO_ATTR_OFFSET) ? TIME2STEPS(attrs.get<SUMOReal>(SUMO_ATTR_OFFSET, id.c_str(), ok)) : 0;
131  std::string typeS = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, 0, ok,
132  OptionsCont::getOptions().getString("tls.default-type"));
133  TrafficLightType type;
134  if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
136  } else {
137  WRITE_ERROR("Unknown traffic light type '" + typeS + "' for tlLogic '" + id + "'.");
138  return 0;
139  }
140  // there are two scenarios to consider
141  // 1) the tll.xml is loaded to update traffic lights defined in a net.xml:
142  // simply retrieve the loaded definitions and update them
143  // 2) the tll.xml is loaded to define new traffic lights
144  // nod.xml will have triggered building of NBOwnTLDef. Replace it with NBLoadedSUMOTLDef
145  // 3) the tll.xml is loaded to define new programs for a defined traffic light
146  // there should be a definition with the same id but different programID
147  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(id);
148  if (programs.size() == 0) {
149  WRITE_ERROR("Cannot load traffic light program for unknown id '" + id + "', programID '" + programID + "'.");
150  return 0;
151  }
152  const std::string existingProgram = programs.begin()->first; // arbitrary for our purpose
153  NBLoadedSUMOTLDef* loadedDef = dynamic_cast<NBLoadedSUMOTLDef*>(myTLLCont.getDefinition(id, programID));
154  if (loadedDef == 0) {
155  NBLoadedSUMOTLDef* oldDef = dynamic_cast<NBLoadedSUMOTLDef*>(myTLLCont.getDefinition(id, existingProgram));
156  if (oldDef == 0) {
157  // case 2
160  if (newDef == 0) {
161  // the default program may have already been replaced with a loaded program
162  newDef = dynamic_cast<NBLoadedSUMOTLDef*>(myTLLCont.getDefinition(
164  if (newDef == 0) {
165  WRITE_ERROR("Cannot load traffic light program for unknown id '" + id + "', programID '" + programID + "'.");
166  return 0;
167  }
168  }
169  assert(newDef != 0);
170  loadedDef = new NBLoadedSUMOTLDef(id, programID, offset, type);
171  // copy nodes and controlled inner edges
172  std::vector<NBNode*> nodes = newDef->getNodes();
173  for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
174  loadedDef->addNode(*it);
175  }
176  loadedDef->addControlledInnerEdges(newDef->getControlledInnerEdges());
178  // replace default Program
179  std::vector<NBNode*> nodes = newDef->getNodes();
180  for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
181  (*it)->removeTrafficLight(newDef);
182  }
184  }
185  myTLLCont.insert(loadedDef);
186  } else {
187  // case 3
188  NBTrafficLightLogic* oldLogic = oldDef->getLogic();
189  NBTrafficLightLogic* newLogic = new NBTrafficLightLogic(id, programID,
190  oldLogic->getNumLinks(), offset, type);
191  loadedDef = new NBLoadedSUMOTLDef(oldDef, newLogic);
192  // copy nodes
193  std::vector<NBNode*> nodes = oldDef->getNodes();
194  for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
195  loadedDef->addNode(*it);
196  }
197  myTLLCont.insert(loadedDef);
198  }
199  } else {
200  // case 1
201  loadedDef->setOffset(offset);
202  loadedDef->setType(type);
203  }
204  if (ok) {
205  myResetPhases = true;
206  return loadedDef;
207  } else {
208  return 0;
209  }
210 }
211 
212 
213 void
215  bool ok = true;
216  // parse identifying attributes
217  NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok);
218  NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok);
219  if (!ok) {
220  return;
221  }
222  int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok);
223  int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok);
224  if (!ok) {
225  return;
226  }
227  // retrieve connection
228  const std::vector<NBEdge::Connection>& connections = from->getConnections();
229  std::vector<NBEdge::Connection>::const_iterator con_it;
230  con_it = find_if(connections.begin(), connections.end(),
231  NBEdge::connections_finder(fromLane, to, toLane));
232  if (con_it == connections.end()) {
233  WRITE_ERROR("Connection from=" + from->getID() + " to=" + to->getID() +
234  " fromLane=" + toString(fromLane) + " toLane=" + toString(toLane) + " not found");
235  return;
236  }
237  NBEdge::Connection c = *con_it;
238  // read other attributes
239  std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, 0, ok, "");
240  if (tlID == "") {
241  // we are updating an existing tl-controlled connection
242  tlID = c.tlID;
243  assert(tlID != "");
244  }
245  int tlIndex = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX, 0, ok, -1);
246  if (tlIndex == -1) {
247  // we are updating an existing tl-controlled connection
248  tlIndex = c.tlLinkNo;
249  }
250 
251  // register the connection with all definitions
252  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(tlID);
253  if (programs.size() > 0) {
254  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
255  for (it = programs.begin(); it != programs.end(); it++) {
256  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
257  if (tlDef) {
258  tlDef->addConnection(from, c.toEdge, c.fromLane, c.toLane, tlIndex);
259  } else {
260  throw ProcessError("Corrupt traffic light definition '"
261  + tlID + "' (program '" + it->first + "')");
262  }
263  }
264  } else {
265  WRITE_ERROR("The traffic light '" + tlID + "' is not known.");
266  }
267 }
268 
269 
270 void
272  bool ok = true;
273  std::string tlID = attrs.get<std::string>(SUMO_ATTR_TLID, 0, ok);
274  // does the traffic light still exist?
275  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(tlID);
276  if (programs.size() > 0) {
277  // parse identifying attributes
278  NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok);
279  NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok);
280  if (!ok) {
281  return;
282  }
283  int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok);
284  int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok);
285  if (!ok) {
286  return;
287  }
288  int tlIndex = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, 0, ok);
289 
290  NBConnection conn(from, fromLane, to, toLane, tlIndex);
291  // remove the connection from all definitions
292  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
293  for (it = programs.begin(); it != programs.end(); it++) {
294  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
295  if (tlDef) {
296  tlDef->removeConnection(conn, false);
297  } else {
298  throw ProcessError("Corrupt traffic light definition '"
299  + tlID + "' (program '" + it->first + "')");
300  }
301  }
302  }
303 }
304 
305 
306 NBEdge*
308  const SUMOSAXAttributes& attrs, SumoXMLAttr attr, bool& ok) {
309  std::string edgeID = attrs.get<std::string>(attr, 0, ok);
310  NBEdge* edge = myEdgeCont.retrieve(edgeID, true);
311  if (edge == 0) {
312  WRITE_ERROR("Unknown edge '" + edgeID + "' given in connection.");
313  ok = false;
314  }
315  return edge;
316 }
317 
318 
319 int
321  const SUMOSAXAttributes& attrs, SumoXMLAttr attr, NBEdge* edge, bool& ok) {
322  int laneIndex = attrs.get<int>(attr, 0, ok);
323  if (edge->getNumLanes() <= laneIndex) {
324  WRITE_ERROR("Invalid lane index '" + toString(laneIndex) + "' for edge '" + edge->getID() + "'.");
325  ok = false;
326  }
327  return laneIndex;
328 }
329 
330 
331 /****************************************************************************/
332 
int tlLinkNo
The index of this connection within the controlling traffic light.
Definition: NBEdge.h:184
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:157
int toLane
The lane the connections yields in.
Definition: NBEdge.h:178
static void addPhase(const SUMOSAXAttributes &attrs, NBLoadedSUMOTLDef *currentTL)
adds a phase to the traffic lights logic currently build
long long int SUMOTime
Definition: SUMOTime.h:43
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:175
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.
std::vector< std::string > getControlledInnerEdges() const
Retrieve the ids of edges explicitly controlled by the tls.
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
The representation of a single edge during network building.
Definition: NBEdge.h:71
The base class for traffic light logic definitions.
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
#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:69
NBTrafficLightDefinition * getDefinition(const std::string &id, const std::string &programID) const
Returns the named definition.
NBTrafficLightLogicCont & myTLLCont
The traffic light container to fill.
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
const std::string & getID() const
Returns the id.
Definition: Named.h:66
int retrieveLaneIndex(const SUMOSAXAttributes &attrs, SumoXMLAttr attr, NBEdge *edge, bool &ok)
parses a lane index and verifies its correctness
Encapsulated SAX-Attributes.
std::string tlID
The id of the traffic light that controls this connection.
Definition: NBEdge.h:181
void addTlConnection(const SUMOSAXAttributes &attrs)
reads and adds tl-controlled connection
static StringBijection< TrafficLightType > TrafficLightTypes
int fromLane
The lane the connections starts at.
Definition: NBEdge.h:172
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
NBLoadedSUMOTLDef * myCurrentTL
The currently parsed traffic light.
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:395
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.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
const std::vector< NBNode * > & getNodes() const
Returns the list of controlled nodes.
bool myResetPhases
whether phases of a previously loaded traffic light must be reset
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
void myEndElement(int element)
Called when a closing tag occurs.
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:247
T get(const std::string &str) const
NIXMLTrafficLightsHandler(NBTrafficLightLogicCont &tlCont, NBEdgeCont &ec)
Constructor.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
#define SUMOReal
Definition: config.h:214
void setType(TrafficLightType type)
Sets the algorithm type of this tls.
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.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
A traffic light logics which must be computed (only nodes/edges are given)
Definition: NBOwnTLDef.h:54
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:803
void addConnection(NBEdge *from, NBEdge *to, int fromLane, int toLane, int linkIndex)
Adds a connection and immediately informs the edges.
TrafficLightType