SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NIXMLTrafficLightsHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // Importer for traffic lights stored in XML
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
10 // Copyright (C) 2001-2013 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #include <string>
32 #include <iostream>
33 #include <xercesc/sax/HandlerBase.hpp>
34 #include <xercesc/sax/AttributeList.hpp>
35 #include <xercesc/sax/SAXParseException.hpp>
36 #include <xercesc/sax/SAXException.hpp>
40 #include <utils/common/ToString.h>
45 #include <netbuild/NBEdge.h>
46 #include <netbuild/NBEdgeCont.h>
47 #include <netbuild/NBNode.h>
48 #include <netbuild/NBOwnTLDef.h>
51 #include "NIImporter_SUMO.h"
53 
54 #ifdef CHECK_MEMORY_LEAKS
55 #include <foreign/nvwa/debug_new.h>
56 #endif // CHECK_MEMORY_LEAKS
57 
58 
59 // ===========================================================================
60 // method definitions
61 // ===========================================================================
63  NBTrafficLightLogicCont& tlCont, NBEdgeCont& ec) :
64  SUMOSAXHandler("xml-tllogics"),
65  myTLLCont(tlCont),
66  myEdgeCont(ec),
67  myCurrentTL(0),
68  myResetPhases(false)
69 {}
70 
71 
73 
74 
75 void
77  int element, const SUMOSAXAttributes& attrs) {
78  switch (element) {
79  case SUMO_TAG_TLLOGIC:
81  break;
82  case SUMO_TAG_PHASE:
83  if (myCurrentTL != 0) {
84  if (myResetPhases) {
86  myResetPhases = false;
87  }
89  }
90  break;
92  addTlConnection(attrs);
93  break;
94  case SUMO_TAG_DELETE:
95  removeTlConnection(attrs);
96  break;
97  default:
98  break;
99  }
100 }
101 
102 
103 void
105  switch (element) {
106  case SUMO_TAG_TLLOGIC:
107  if (!myCurrentTL) {
108  WRITE_ERROR("Unmatched closing tag for tlLogic.");
109  } else {
110  if (!myTLLCont.insert(myCurrentTL)) {
111  WRITE_MESSAGE("Updating program '" + myCurrentTL->getProgramID() +
112  "' for traffic light '" + myCurrentTL->getID() + "'");
113  }
114  myCurrentTL = 0;
115  }
116  break;
117  default:
118  break;
119  }
120 }
121 
122 
125  if (currentTL) {
126  WRITE_ERROR("Definition of tlLogic '" + currentTL->getID() + "' was not finished.");
127  return 0;
128  }
129  bool ok = true;
130  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
131  std::string programID = attrs.getOpt<std::string>(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
132  SUMOTime offset = attrs.hasAttribute(SUMO_ATTR_OFFSET) ? TIME2STEPS(attrs.get<SUMOReal>(SUMO_ATTR_OFFSET, id.c_str(), ok)) : 0;
133  std::string typeS = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, 0, ok,
134  OptionsCont::getOptions().getString("tls.default-type"));
135  TrafficLightType type;
136  if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
138  } else {
139  WRITE_ERROR("Unknown traffic light type '" + typeS + "' for tlLogic '" + id + "'.");
140  return 0;
141  }
142  // there are two scenarios to consider
143  // 1) the tll.xml is loaded to update traffic lights defined in a net.xml:
144  // simply retrieve the loaded definitions and update them
145  // 2) the tll.xml is loaded to define new traffic lights
146  // nod.xml will have triggered building of NBOwnTLDef. Replace it with NBLoadedSUMOTLDef
147  NBLoadedSUMOTLDef* loadedDef = dynamic_cast<NBLoadedSUMOTLDef*>(myTLLCont.getDefinition(id, programID));
148  if (loadedDef == 0) {
149  // case 2
152  if (newDef == 0) {
153  // the default program may have already been replaced with a loaded program
154  newDef = dynamic_cast<NBLoadedSUMOTLDef*>(myTLLCont.getDefinition(
156  if (newDef == 0) {
157  WRITE_ERROR("Cannot load traffic light program for unknown id '" + id + "', programID '" + programID + "'.");
158  return 0;
159  }
160  }
161  assert(newDef != 0);
162  loadedDef = new NBLoadedSUMOTLDef(id, programID, offset, type);
163  // copy nodes
164  std::vector<NBNode*> nodes = newDef->getControlledNodes();
165  for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
166  loadedDef->addNode(*it);
167  }
169  // replace default Program
170  std::vector<NBNode*> nodes = newDef->getControlledNodes();
171  for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
172  (*it)->removeTrafficLight(newDef);
173  }
175  }
176  myTLLCont.insert(loadedDef);
177  }
178  if (ok) {
179  myResetPhases = true;
180  return loadedDef;
181  } else {
182  return 0;
183  }
184 }
185 
186 
187 void
189  bool ok = true;
190  // parse identifying attributes
191  NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok);
192  NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok);
193  if (!ok) {
194  return;
195  }
196  int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok);
197  int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok);
198  if (!ok) {
199  return;
200  }
201  // retrieve connection
202  const std::vector<NBEdge::Connection>& connections = from->getConnections();
203  std::vector<NBEdge::Connection>::const_iterator con_it;
204  con_it = find_if(connections.begin(), connections.end(),
205  NBEdge::connections_finder(fromLane, to, toLane));
206  if (con_it == connections.end()) {
207  WRITE_ERROR("Connection from=" + from->getID() + " to=" + to->getID() +
208  " fromLane=" + toString(fromLane) + " toLane=" + toString(toLane) + " not found");
209  return;
210  }
211  NBEdge::Connection c = *con_it;
212  // read other attributes
213  std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, 0, ok, "");
214  if (tlID == "") {
215  // we are updating an existing tl-controlled connection
216  tlID = c.tlID;
217  assert(tlID != "");
218  }
219  int tlIndex = attrs.getOpt<int>(SUMO_ATTR_TLLINKINDEX, 0, ok, -1);
220  if (tlIndex == -1) {
221  // we are updating an existing tl-controlled connection
222  tlIndex = c.tlLinkNo;
223  }
224 
225  // register the connection with all definitions
226  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(tlID);
227  if (programs.size() > 0) {
228  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
229  for (it = programs.begin(); it != programs.end(); it++) {
230  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
231  if (tlDef) {
232  tlDef->addConnection(from, c.toEdge, c.fromLane, c.toLane, tlIndex);
233  } else {
234  throw ProcessError("Corrupt traffic light definition '"
235  + tlID + "' (program '" + it->first + "')");
236  }
237  }
238  } else {
239  WRITE_ERROR("The traffic light '" + tlID + "' is not known.");
240  }
241 }
242 
243 
244 void
246  bool ok = true;
247  std::string tlID = attrs.get<std::string>(SUMO_ATTR_TLID, 0, ok);
248  // does the traffic light still exist?
249  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(tlID);
250  if (programs.size() > 0) {
251  // parse identifying attributes
252  NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok);
253  NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok);
254  if (!ok) {
255  return;
256  }
257  int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok);
258  int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok);
259  if (!ok) {
260  return;
261  }
262  int tlIndex = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, 0, ok);
263 
264  NBConnection conn(from, fromLane, to, toLane, tlIndex);
265  // remove the connection from all definitions
266  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
267  for (it = programs.begin(); it != programs.end(); it++) {
268  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
269  if (tlDef) {
270  tlDef->removeConnection(conn, false);
271  } else {
272  throw ProcessError("Corrupt traffic light definition '"
273  + tlID + "' (program '" + it->first + "')");
274  }
275  }
276  }
277 }
278 
279 
280 NBEdge*
282  const SUMOSAXAttributes& attrs, SumoXMLAttr attr, bool& ok) {
283  std::string edgeID = attrs.get<std::string>(attr, 0, ok);
284  NBEdge* edge = myEdgeCont.retrieve(edgeID, true);
285  if (edge == 0) {
286  WRITE_ERROR("Unknown edge '" + edgeID + "' given in connection.");
287  ok = false;
288  }
289  return edge;
290 }
291 
292 
293 int
295  const SUMOSAXAttributes& attrs, SumoXMLAttr attr, NBEdge* edge, bool& ok) {
296  int laneIndex = attrs.get<int>(attr, 0, ok);
297  if (edge->getNumLanes() <= (size_t) laneIndex) {
298  WRITE_ERROR("Invalid lane index '" + toString(laneIndex) + "' for edge '" + edge->getID() + "'.");
299  ok = false;
300  }
301  return laneIndex;
302 }
303 
304 
305 /****************************************************************************/
306