SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NIXMLNodesHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // Importer for network nodes stored in XML
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
13 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <string>
35 #include <iostream>
36 #include <xercesc/sax/HandlerBase.hpp>
37 #include <xercesc/sax/AttributeList.hpp>
38 #include <xercesc/sax/SAXParseException.hpp>
39 #include <xercesc/sax/SAXException.hpp>
44 #include <utils/common/ToString.h>
48 #include <netbuild/NBNodeCont.h>
50 #include <netbuild/NBOwnTLDef.h>
51 #include "NILoader.h"
52 #include "NIXMLNodesHandler.h"
53 #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 // ===========================================================================
65  OptionsCont& options) :
66  SUMOSAXHandler("xml-nodes - file"),
67  myOptions(options),
68  myNodeCont(nc),
69  myTLLogicCont(tlc),
70  myLocation(0)
71 {}
72 
73 
75  delete myLocation;
76 }
77 
78 
79 void
81  const SUMOSAXAttributes& attrs) {
82  switch (element) {
83  case SUMO_TAG_LOCATION:
85  break;
86  case SUMO_TAG_NODE:
87  addNode(attrs);
88  break;
89  case SUMO_TAG_JOIN:
90  addJoinCluster(attrs);
91  break;
93  addJoinExclusion(attrs);
94  break;
95  case SUMO_TAG_DELETE:
96  deleteNode(attrs);
97  break;
98  default:
99  break;
100  }
101 }
102 
103 
104 void
106  bool ok = true;
107  // get the id, report a warning if not given or empty...
108  myID = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
109  if (!ok) {
110  return;
111  }
112  NBNode* node = myNodeCont.retrieve(myID);
113  // retrieve the position of the node
114  bool xOk = false;
115  bool yOk = false;
116  bool needConversion = true;
117  if (node != 0) {
118  myPosition = node->getPosition();
119  xOk = yOk = true;
120  needConversion = false;
121  }
122  if (attrs.hasAttribute(SUMO_ATTR_X)) {
124  xOk = true;
125  needConversion = true;
126  }
127  if (attrs.hasAttribute(SUMO_ATTR_Y)) {
129  yOk = true;
130  needConversion = true;
131  }
132  if (attrs.hasAttribute(SUMO_ATTR_Z)) {
134  }
135  if (xOk && yOk) {
136  if (needConversion && !NILoader::transformCoordinates(myPosition, true, myLocation)) {
137  WRITE_ERROR("Unable to project coordinates for node '" + myID + "'.");
138  }
139  } else {
140  WRITE_ERROR("Missing position (at node ID='" + myID + "').");
141  }
142  bool updateEdgeGeometries = node != 0 && myPosition != node->getPosition();
143  // check whether the y-axis shall be flipped
144  if (myOptions.getBool("flip-y-axis")) {
145  myPosition.mul(1.0, -1.0);
146  }
147  // get the type
149  if (node != 0) {
150  type = node->getType();
151  }
152  std::string typeS = attrs.getOptStringReporting(SUMO_ATTR_TYPE, myID.c_str(), ok, "");
153  if (SUMOXMLDefinitions::NodeTypes.hasString(typeS)) {
154  type = SUMOXMLDefinitions::NodeTypes.get(typeS);
155  }
156 
157  // check whether a prior node shall be modified
158  if (node == 0) {
159  node = new NBNode(myID, myPosition, type);
160  if (!myNodeCont.insert(node)) {
161  throw ProcessError("Could not insert node though checked this before (id='" + myID + "').");
162  }
163  } else {
164  // remove previously set tls if this node is not controlled by a tls
165  std::set<NBTrafficLightDefinition*> tls = node->getControllingTLS();
166  node->removeTrafficLights();
167  for (std::set<NBTrafficLightDefinition*>::iterator i = tls.begin(); i != tls.end(); ++i) {
168  if ((*i)->getNodes().size() == 0) {
169  myTLLogicCont.removeFully((*i)->getID());
170  }
171  }
172  // patch information
173  node->reinit(myPosition, type, updateEdgeGeometries);
174  }
175  // process traffic light definition
176  if (type == NODETYPE_TRAFFIC_LIGHT) {
177  processTrafficLightDefinitions(attrs, node);
178  }
179 }
180 
181 
182 void
184  bool ok = true;
185  // get the id, report a warning if not given or empty...
186  myID = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
187  if (!ok) {
188  return;
189  }
190  NBNode* node = myNodeCont.retrieve(myID);
191  if (node == 0) {
192  WRITE_WARNING("Ignoring tag '" + toString(SUMO_TAG_DELETE) + "' for unknown node '" +
193  myID + "'");
194  return;
195  } else {
196  myNodeCont.extract(node, true);
197  }
198 }
199 
200 
201 void
203  bool ok = true;
204  const std::string clusterString = attrs.getStringReporting(SUMO_ATTR_NODES, 0, ok);
205  const std::vector<std::string> ids = StringTokenizer(clusterString).getVector();
206  if (ok) {
207  myNodeCont.addCluster2Join(std::set<std::string>(ids.begin(), ids.end()));
208  }
209 }
210 
211 
212 void
214  bool ok = true;
215  const std::vector<std::string> ids = StringTokenizer(
216  attrs.getStringReporting(SUMO_ATTR_NODES, 0, ok)).getVector();
217  if (ok) {
219  }
220 }
221 
222 
223 void
225  NBNode* currentNode) {
226  // try to get the tl-id
227  // if a tl-id is given, we will look whether this tl already exists
228  // if so, we will add the node to it (and to all programs with this id), otherwise allocate a new one with this id
229  // if no tl-id exists, we will build a tl with the node's id
230  std::set<NBTrafficLightDefinition*> tlDefs;
231  bool ok = true;
232  std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, "");
233  if (tlID != "" && myTLLogicCont.getPrograms(tlID).size() > 0) {
234  // we already have definitions for this tlID
235  const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLogicCont.getPrograms(tlID);
236  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
237  for (it = programs.begin(); it != programs.end(); it++) {
238  tlDefs.insert(it->second);
239  it->second->addNode(currentNode);
240  }
241  } else {
242  // we need to add a new defition
243  tlID = tlID == "" ? myID : tlID;
244  NBTrafficLightDefinition* tlDef = new NBOwnTLDef(tlID, currentNode, 0);
245  if (!myTLLogicCont.insert(tlDef)) {
246  // actually, nothing should fail here
247  delete tlDef;
248  throw ProcessError("Could not allocate tls '" + myID + "'.");
249  }
250  tlDefs.insert(tlDef);
251  }
252  // process inner edges which shall be controlled
253  std::vector<std::string> controlledInner;
255  if (controlledInner.size() != 0) {
256  for (std::set<NBTrafficLightDefinition*>::iterator it = tlDefs.begin(); it != tlDefs.end(); it++) {
257  (*it)->addControlledInnerEdges(controlledInner);
258  }
259  }
260 }
261 
262 
263 
264 /****************************************************************************/
265