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>
46 #include <netbuild/NBEdge.h>
47 #include <netbuild/NBEdgeCont.h>
48 #include <netbuild/NBNode.h>
49 #include <netbuild/NBOwnTLDef.h>
52 #include "NIImporter_SUMO.h"
54 
55 #ifdef CHECK_MEMORY_LEAKS
56 #include <foreign/nvwa/debug_new.h>
57 #endif // CHECK_MEMORY_LEAKS
58 
59 
60 // ===========================================================================
61 // method definitions
62 // ===========================================================================
64  NBTrafficLightLogicCont& tlCont, NBEdgeCont& ec) :
65  SUMOSAXHandler("xml-tllogics"),
66  myTLLCont(tlCont),
67  myEdgeCont(ec),
68  myCurrentTL(0),
69  myResetPhases(false)
70 {}
71 
72 
74 
75 
76 void
78  int element, const SUMOSAXAttributes& attrs) {
79  switch (element) {
80  case SUMO_TAG_TLLOGIC:
82  break;
83  case SUMO_TAG_PHASE:
84  if (myResetPhases) {
86  myResetPhases = false;
87  }
89  break;
91  addTlConnection(attrs);
92  break;
93  case SUMO_TAG_DELETE:
94  removeTlConnection(attrs);
95  break;
96  default:
97  break;
98  }
99 }
100 
101 
102 void
104  switch (element) {
105  case SUMO_TAG_TLLOGIC:
106  if (!myCurrentTL) {
107  WRITE_ERROR("Unmatched closing tag for tl-logic.");
108  } else {
109  if (!myTLLCont.insert(myCurrentTL)) {
110  WRITE_MESSAGE("Updating program '" + myCurrentTL->getProgramID() +
111  "' for traffic light '" + myCurrentTL->getID() + "'");
112  }
113  myCurrentTL = 0;
114  }
115  break;
116  default:
117  break;
118  }
119 }
120 
121 
124  if (currentTL) {
125  WRITE_ERROR("Definition of tl-logic '" + currentTL->getID() + "' was not finished.");
126  return 0;
127  }
128  bool ok = true;
129  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
130  std::string programID = attrs.getOptStringReporting(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
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, 0);
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 '" +
155  toString(TLTYPE_STATIC) + "'");
156  }
157  }
158  if (attrs.hasAttribute(SUMO_ATTR_OFFSET)) {
159  SUMOTime offset = TIME2STEPS(attrs.getSUMORealReporting(SUMO_ATTR_OFFSET, id.c_str(), ok));
160  loadedDef->getLogic()->setOffset(offset);
161  }
162  if (ok) {
163  myResetPhases = true;
164  return loadedDef;
165  } else {
166  return 0;
167  }
168 }
169 
170 
171 void
173  bool ok = true;
174  // parse identifying attributes
175  NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok);
176  NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok);
177  if (!ok) {
178  return;
179  }
180  int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok);
181  int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok);
182  if (!ok) {
183  return;
184  }
185  // retrieve connection
186  const std::vector<NBEdge::Connection> &connections = from->getConnections();
187  std::vector<NBEdge::Connection>::const_iterator con_it;
188  con_it = find_if(connections.begin(), connections.end(),
189  NBEdge::connections_finder(fromLane, to, toLane));
190  if (con_it == connections.end()) {
191  WRITE_ERROR("Connection from=" + from->getID() + " to=" + to->getID() +
192  " fromLane=" + toString(fromLane) + " toLane=" + toString(toLane) + " not found");
193  return;
194  }
195  NBEdge::Connection c = *con_it;
196  // read other attributes
197  std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, "");
198  if (tlID == "") {
199  // we are updating an existing tl-controlled connection
200  tlID = c.tlID;
201  assert(tlID != "");
202  }
203  int tlIndex = attrs.getOptIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok, -1);
204  if (tlIndex == -1) {
205  // we are updating an existing tl-controlled connection
206  tlIndex = c.tlLinkNo;
207  }
208 
209  // register the connection with all definitions
210  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(tlID);
211  if (programs.size() > 0) {
212  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
213  for (it = programs.begin(); it != programs.end(); it++) {
214  NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
215  if (tlDef) {
216  tlDef->addConnection(from, c.toEdge, c.fromLane, c.toLane, tlIndex);
217  } else {
218  throw ProcessError("Corrupt traffic light definition '"
219  + tlID + "' (program '" + it->first + "')");
220  }
221  }
222  } else {
223  WRITE_ERROR("The traffic light '" + tlID + "' is not known.");
224  }
225 }
226 
227 
228 void
230  bool ok = true;
231  std::string tlID = attrs.getStringReporting(SUMO_ATTR_TLID, 0, ok);
232  // does the traffic light still exist?
233  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(tlID);
234  if (programs.size() > 0) {
235  // parse identifying attributes
236  NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok);
237  NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok);
238  if (!ok) {
239  return;
240  }
241  int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok);
242  int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok);
243  if (!ok) {
244  return;
245  }
246  int tlIndex = attrs.getIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok);
247 
248  NBConnection conn(from, fromLane, to, toLane, tlIndex);
249  // remove the connection from all definitions
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->removeConnection(conn, false);
255  } else {
256  throw ProcessError("Corrupt traffic light definition '"
257  + tlID + "' (program '" + it->first + "')");
258  }
259  }
260  }
261 }
262 
263 
264 NBEdge*
266  const SUMOSAXAttributes& attrs, SumoXMLAttr attr, bool& ok) {
267  std::string edgeID = attrs.getStringReporting(attr, 0, ok);
268  NBEdge* edge = myEdgeCont.retrieve(edgeID, true);
269  if (edge == 0) {
270  WRITE_ERROR("Unknown edge '" + edgeID + "' given in connection.");
271  ok = false;
272  }
273  return edge;
274 }
275 
276 
277 int
279  const SUMOSAXAttributes& attrs, SumoXMLAttr attr, NBEdge* edge, bool& ok) {
280  int laneIndex = attrs.getIntReporting(attr, 0, ok);
281  if (edge->getNumLanes() <= (size_t) laneIndex) {
282  WRITE_ERROR("Invalid lane index '" + toString(laneIndex) + "' for edge '" + edge->getID() + "'.");
283  ok = false;
284  }
285  return laneIndex;
286 }
287 
288 
289 /****************************************************************************/
290