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.sourceforge.net/
10 // Copyright (C) 2001-2012 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 (myResetPhases) {
85  myResetPhases = false;
86  }
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 tl-logic.");
107  } else {
108  if (!myTLLCont.insert(myCurrentTL)) {
109  WRITE_MESSAGE("Updating program '" + myCurrentTL->getProgramID() +
110  "' for traffic light '" + myCurrentTL->getID() + "'");
111  }
112  myCurrentTL = 0;
113  }
114  break;
115  default:
116  break;
117  }
118 }
119 
120 
123  if (currentTL) {
124  WRITE_ERROR("Definition of tl-logic '" + currentTL->getID() + "' was not finished.");
125  return 0;
126  }
127  bool ok = true;
128  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
129  std::string programID = attrs.getOptStringReporting(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
130  SUMOTime offset = attrs.hasAttribute(SUMO_ATTR_OFFSET) ? TIME2STEPS(attrs.getSUMORealReporting(SUMO_ATTR_OFFSET, id.c_str(), ok)) : 0;
131 
132  // there are two scenarios to consider
133  // 1) the tll.xml is loaded to update traffic lights defined in a net.xml:
134  // simply retrieve the loaded definitions and update them
135  // 2) the tll.xml is loaded to define new traffic lights
136  // nod.xml will have triggered building of NBOwnTLDef. Replace it with NBLoadedSUMOTLDef
137  NBLoadedSUMOTLDef* loadedDef = dynamic_cast<NBLoadedSUMOTLDef*>(myTLLCont.getDefinition(id, programID));
138  if (loadedDef == 0) {
139  // case 2
140  NBOwnTLDef* newDef = dynamic_cast<NBOwnTLDef*>(myTLLCont.getDefinition(
142  assert(newDef != 0);
143  loadedDef = new NBLoadedSUMOTLDef(id, programID, offset);
144  std::vector<NBNode*> nodes = newDef->getControlledNodes();
145  for (std::vector<NBNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
146  (*it)->removeTrafficLight(newDef);
147  (*it)->addTrafficLight(loadedDef);
148  }
150  myTLLCont.insert(loadedDef);
151 
152  std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, 0, ok, toString(TLTYPE_STATIC));
153  if (type != toString(TLTYPE_STATIC)) {
154  WRITE_WARNING("Traffic light '" + id + "' has unsupported type '" + type + "' and will be converted to '" + toString(TLTYPE_STATIC) + "'");
155  }
156  }
157  if (ok) {
158  myResetPhases = true;
159  return loadedDef;
160  } else {
161  return 0;
162  }
163 }
164 
165 
166 void
168  bool ok = true;
169  // parse identifying attributes
170  NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok);
171  NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok);
172  if (!ok) {
173  return;
174  }
175  int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok);
176  int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok);
177  if (!ok) {
178  return;
179  }
180  // retrieve connection
181  const std::vector<NBEdge::Connection>& connections = from->getConnections();
182  std::vector<NBEdge::Connection>::const_iterator con_it;
183  con_it = find_if(connections.begin(), connections.end(),
184  NBEdge::connections_finder(fromLane, to, toLane));
185  if (con_it == connections.end()) {
186  WRITE_ERROR("Connection from=" + from->getID() + " to=" + to->getID() +
187  " fromLane=" + toString(fromLane) + " toLane=" + toString(toLane) + " not found");
188  return;
189  }
190  NBEdge::Connection c = *con_it;
191  // read other attributes
192  std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, "");
193  if (tlID == "") {
194  // we are updating an existing tl-controlled connection
195  tlID = c.tlID;
196  assert(tlID != "");
197  }
198  int tlIndex = attrs.getOptIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok, -1);
199  if (tlIndex == -1) {
200  // we are updating an existing tl-controlled connection
201  tlIndex = c.tlLinkNo;
202  }
203 
204  // register the connection with all definitions
205  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(tlID);
206  if (programs.size() > 0) {
207  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
208  for (it = programs.begin(); it != programs.end(); it++) {
209  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
210  if (tlDef) {
211  tlDef->addConnection(from, c.toEdge, c.fromLane, c.toLane, tlIndex);
212  } else {
213  throw ProcessError("Corrupt traffic light definition '"
214  + tlID + "' (program '" + it->first + "')");
215  }
216  }
217  } else {
218  WRITE_ERROR("The traffic light '" + tlID + "' is not known.");
219  }
220 }
221 
222 
223 void
225  bool ok = true;
226  std::string tlID = attrs.getStringReporting(SUMO_ATTR_TLID, 0, ok);
227  // does the traffic light still exist?
228  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(tlID);
229  if (programs.size() > 0) {
230  // parse identifying attributes
231  NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok);
232  NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok);
233  if (!ok) {
234  return;
235  }
236  int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok);
237  int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok);
238  if (!ok) {
239  return;
240  }
241  int tlIndex = attrs.getIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok);
242 
243  NBConnection conn(from, fromLane, to, toLane, tlIndex);
244  // remove the connection from all definitions
245  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
246  for (it = programs.begin(); it != programs.end(); it++) {
247  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
248  if (tlDef) {
249  tlDef->removeConnection(conn, false);
250  } else {
251  throw ProcessError("Corrupt traffic light definition '"
252  + tlID + "' (program '" + it->first + "')");
253  }
254  }
255  }
256 }
257 
258 
259 NBEdge*
261  const SUMOSAXAttributes& attrs, SumoXMLAttr attr, bool& ok) {
262  std::string edgeID = attrs.getStringReporting(attr, 0, ok);
263  NBEdge* edge = myEdgeCont.retrieve(edgeID, true);
264  if (edge == 0) {
265  WRITE_ERROR("Unknown edge '" + edgeID + "' given in connection.");
266  ok = false;
267  }
268  return edge;
269 }
270 
271 
272 int
274  const SUMOSAXAttributes& attrs, SumoXMLAttr attr, NBEdge* edge, bool& ok) {
275  int laneIndex = attrs.getIntReporting(attr, 0, ok);
276  if (edge->getNumLanes() <= (size_t) laneIndex) {
277  WRITE_ERROR("Invalid lane index '" + toString(laneIndex) + "' for edge '" + edge->getID() + "'.");
278  ok = false;
279  }
280  return laneIndex;
281 }
282 
283 
284 /****************************************************************************/
285