SUMO - Simulation of Urban MObility
NIXMLNodesHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
20 // Importer for network nodes stored in XML
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>
43 #include <utils/common/ToString.h>
47 #include <netbuild/NBNodeCont.h>
49 #include <netbuild/NBOwnTLDef.h>
50 #include <netbuild/NBNetBuilder.h>
51 #include "NIXMLNodesHandler.h"
52 #include "NIImporter_SUMO.h"
53 
54 
55 // ===========================================================================
56 // method definitions
57 // ===========================================================================
60  OptionsCont& options) :
61  SUMOSAXHandler("xml-nodes - file"),
62  myOptions(options),
63  myNodeCont(nc),
64  myTLLogicCont(tlc),
65  myLocation(0),
66  myLastParameterised(0) {
67 }
68 
69 
71  delete myLocation;
72 }
73 
74 
75 void
77  const SUMOSAXAttributes& attrs) {
78  switch (element) {
79  case SUMO_TAG_LOCATION:
81  break;
82  case SUMO_TAG_NODE:
83  addNode(attrs);
84  break;
85  case SUMO_TAG_JOIN:
86  addJoinCluster(attrs);
87  break;
89  addJoinExclusion(attrs);
90  break;
91  case SUMO_TAG_DELETE:
92  deleteNode(attrs);
93  break;
94  case SUMO_TAG_PARAM:
95  if (myLastParameterised != 0) {
96  bool ok = true;
97  const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, 0, ok);
98  // circumventing empty string test
99  const std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
101  }
102  default:
103  break;
104  }
105 }
106 
107 
108 void
110  switch (element) {
111  case SUMO_TAG_NODE:
113  break;
114  default:
115  break;
116  }
117 }
118 
119 
120 void
122  bool ok = true;
123  // get the id, report a warning if not given or empty...
124  myID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
125  if (!ok) {
126  return;
127  }
128  NBNode* node = myNodeCont.retrieve(myID);
129  // retrieve the position of the node
130  bool xOk = false;
131  bool yOk = false;
132  bool needConversion = true;
133  if (node != 0) {
134  myPosition = node->getPosition();
135  xOk = yOk = true;
136  needConversion = false;
137  } else {
138  myPosition.set(0, 0, 0); // better to reset than to reuse the previous (z)-value
139  }
140  if (attrs.hasAttribute(SUMO_ATTR_X)) {
141  myPosition.set(attrs.get<double>(SUMO_ATTR_X, myID.c_str(), ok), myPosition.y());
142  xOk = true;
143  needConversion = true;
144  }
145  if (attrs.hasAttribute(SUMO_ATTR_Y)) {
146  myPosition.set(myPosition.x(), attrs.get<double>(SUMO_ATTR_Y, myID.c_str(), ok));
147  yOk = true;
148  needConversion = true;
149  }
150  if (attrs.hasAttribute(SUMO_ATTR_Z)) {
151  myPosition.set(myPosition.x(), myPosition.y(), attrs.get<double>(SUMO_ATTR_Z, myID.c_str(), ok));
152  }
153  if (xOk && yOk) {
154  if (needConversion && !NBNetBuilder::transformCoordinate(myPosition, true, myLocation)) {
155  WRITE_ERROR("Unable to project coordinates for node '" + myID + "'.");
156  }
157  } else {
158  WRITE_ERROR("Missing position (at node ID='" + myID + "').");
159  }
160  bool updateEdgeGeometries = node != 0 && myPosition != node->getPosition();
161  // check whether the y-axis shall be flipped
162  if (myOptions.getBool("flip-y-axis")) {
163  myPosition.mul(1.0, -1.0);
164  }
165  node = processNodeType(attrs, node, myID, myPosition, updateEdgeGeometries, myNodeCont, myTLLogicCont);
166  myLastParameterised = node;
167 }
168 
169 
170 NBNode*
171 NIXMLNodesHandler::processNodeType(const SUMOSAXAttributes& attrs, NBNode* node, const std::string& nodeID, const Position& position,
172  bool updateEdgeGeometries,
174  bool ok = true;
175  // get the type
177  if (node != 0) {
178  type = node->getType();
179  }
180  std::string typeS = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, nodeID.c_str(), ok, "");
181  if (SUMOXMLDefinitions::NodeTypes.hasString(typeS)) {
182  type = SUMOXMLDefinitions::NodeTypes.get(typeS);
183  if (type == NODETYPE_DEAD_END_DEPRECATED || type == NODETYPE_DEAD_END) {
184  // dead end is a computed status. Reset this to unknown so it will
185  // be corrected if additional connections are loaded
186  type = NODETYPE_UNKNOWN;
187  }
188  }
189  std::set<NBTrafficLightDefinition*> oldTLS;
190  // check whether a prior node shall be modified
191  if (node == 0) {
192  node = new NBNode(nodeID, position, type);
193  if (!nc.insert(node)) {
194  throw ProcessError("Could not insert node though checked this before (id='" + nodeID + "').");
195  }
196  } else {
197  // patch information
198  oldTLS = node->getControllingTLS();
199  node->reinit(position, type, updateEdgeGeometries);
200  }
201  // process traffic light definition
202  if (NBNode::isTrafficLight(type)) {
203  processTrafficLightDefinitions(attrs, node, tlc);
204  }
205  // remove previously set tls if this node is not controlled by them
206  for (std::set<NBTrafficLightDefinition*>::iterator i = oldTLS.begin(); i != oldTLS.end(); ++i) {
207  if ((*i)->getNodes().size() == 0) {
208  tlc.removeFully((*i)->getID());
209  }
210  }
211 
212  // set optional shape
213  PositionVector shape;
214  if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
215  shape = attrs.getOpt<PositionVector>(SUMO_ATTR_SHAPE, nodeID.c_str(), ok, PositionVector());
216  if (shape.size() > 2) {
217  shape.closePolygon();
218  }
219  node->setCustomShape(shape);
220  }
221  // set optional radius
222  if (attrs.hasAttribute(SUMO_ATTR_RADIUS)) {
223  node->setRadius(attrs.get<double>(SUMO_ATTR_RADIUS, nodeID.c_str(), ok));
224  }
225  // set optional keepClear flag
226  if (attrs.hasAttribute(SUMO_ATTR_KEEP_CLEAR)) {
227  node->setKeepClear(attrs.get<bool>(SUMO_ATTR_KEEP_CLEAR, nodeID.c_str(), ok));
228  }
229  return node;
230 }
231 
232 
233 void
235  bool ok = true;
236  // get the id, report a warning if not given or empty...
237  myID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
238  if (!ok) {
239  return;
240  }
241  NBNode* node = myNodeCont.retrieve(myID);
242  if (node == 0) {
243  WRITE_WARNING("Ignoring tag '" + toString(SUMO_TAG_DELETE) + "' for unknown node '" +
244  myID + "'");
245  return;
246  } else {
247  myNodeCont.extract(node, true);
248  }
249 }
250 
251 
252 void
254  bool ok = true;
255  const std::string clusterString = attrs.get<std::string>(SUMO_ATTR_NODES, 0, ok);
256  const std::vector<std::string> ids = StringTokenizer(clusterString).getVector();
257  if (ok) {
258  myNodeCont.addCluster2Join(std::set<std::string>(ids.begin(), ids.end()));
259  }
260 }
261 
262 
263 void
265  bool ok = true;
266  const std::vector<std::string> ids = StringTokenizer(
267  attrs.get<std::string>(SUMO_ATTR_NODES, 0, ok)).getVector();
268  if (ok) {
270  }
271 }
272 
273 
274 void
276  NBNode* currentNode, NBTrafficLightLogicCont& tlc) {
277  // try to get the tl-id
278  // if a tl-id is given, we will look whether this tl already exists
279  // if so, we will add the node to it (and to all programs with this id), otherwise allocate a new one with this id
280  // if no tl-id exists, we will build a tl with the node's id
281  std::set<NBTrafficLightDefinition*> tlDefs;
282  bool ok = true;
283 
284  std::string oldTlID = "";
285  std::string oldTypeS = OptionsCont::getOptions().getString("tls.default-type");
286 
287  if (currentNode->isTLControlled()) {
288  NBTrafficLightDefinition* oldDef = *(currentNode->getControllingTLS().begin());
289  oldTlID = oldDef->getID();
290  oldTypeS = toString(oldDef->getType());
291  }
292  std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, 0, ok, oldTlID);
293  std::string typeS = attrs.getOpt<std::string>(SUMO_ATTR_TLTYPE, 0, ok, oldTypeS);
294  if (tlID != oldTlID || typeS != oldTypeS) {
295  currentNode->removeTrafficLights();
296  }
297  TrafficLightType type;
298  if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
300  } else {
301  WRITE_ERROR("Unknown traffic light type '" + typeS + "' for node '" + currentNode->getID() + "'.");
302  return;
303  }
304  if (tlID != "" && tlc.getPrograms(tlID).size() > 0) {
305  // we already have definitions for this tlID
306  const std::map<std::string, NBTrafficLightDefinition*>& programs = tlc.getPrograms(tlID);
307  std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
308  for (it = programs.begin(); it != programs.end(); it++) {
309  if (it->second->getType() != type) {
310  WRITE_ERROR("Mismatched traffic light type '" + typeS + "' for tl '" + tlID + "'.");
311  ok = false;
312  } else {
313  tlDefs.insert(it->second);
314  it->second->addNode(currentNode);
315  }
316  }
317  } else {
318  // we need to add a new defition
319  tlID = (tlID == "" ? currentNode->getID() : tlID);
320  NBTrafficLightDefinition* tlDef = new NBOwnTLDef(tlID, currentNode, 0, type);
321  if (!tlc.insert(tlDef)) {
322  // actually, nothing should fail here
323  delete tlDef;
324  throw ProcessError("Could not allocate tls '" + currentNode->getID() + "'.");
325  }
326  tlDefs.insert(tlDef);
327  }
328  // process inner edges which shall be controlled
329  std::vector<std::string> controlledInner;
330  SUMOSAXAttributes::parseStringVector(attrs.getOpt<std::string>(SUMO_ATTR_CONTROLLED_INNER, 0, ok, ""), controlledInner);
331  if (controlledInner.size() != 0) {
332  for (std::set<NBTrafficLightDefinition*>::iterator it = tlDefs.begin(); it != tlDefs.end(); it++) {
333  (*it)->addControlledInnerEdges(controlledInner);
334  }
335  }
336 }
337 
338 
339 
340 /****************************************************************************/
341 
const std::map< std::string, NBTrafficLightDefinition * > & getPrograms(const std::string &id) const
Returns all programs for the given tl-id.
NBNode * retrieve(const std::string &id) const
Returns the node with the given name.
Definition: NBNodeCont.cpp:108
static StringBijection< SumoXMLNodeType > NodeTypes
node types
GeoConvHelper * myLocation
The coordinate transformation which was used compute the node coordinates.
a list of node ids, used for controlling joining
Whether vehicles must keep the junction clear.
static bool transformCoordinate(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
std::string myID
The id of the currently parsed node.
void addJoinExclusion(const std::vector< std::string > &ids, bool check=false)
Definition: NBNodeCont.cpp:503
static NBNode * processNodeType(const SUMOSAXAttributes &attrs, NBNode *node, const std::string &nodeID, const Position &position, bool updateEdgeGeometries, NBNodeCont &nc, NBTrafficLightLogicCont &tlc)
parses node attributes (not related to positioning)
A container for traffic light definitions and built programs.
~NIXMLNodesHandler()
Destructor.
void reinit(const Position &position, SumoXMLNodeType type, bool updateEdgeGeometries=false)
Resets initial values.
Definition: NBNode.cpp:273
double y() const
Returns the y-position.
Definition: Position.h:67
TrafficLightType getType() const
get the algorithm type (static etc..)
double x() const
Returns the x-position.
Definition: Position.h:62
Position myPosition
The position of the currently parsed node.
The base class for traffic light logic definitions.
link,node: the traffic light id responsible for this link
NBTrafficLightLogicCont & myTLLogicCont
The traffic lights container to add built tls to.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const std::string & getID() const
Returns the id.
Definition: Named.h:65
void set(double x, double y)
set positions x and y
Definition: Position.h:92
void setCustomShape(const PositionVector &shape)
set the junction shape
Definition: NBNode.cpp:1732
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...
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:199
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:64
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
NBNodeCont & myNodeCont
The node container to add built nodes to.
void setRadius(double radius)
set the turning radius
Definition: NBNode.h:479
bool isTLControlled() const
Returns whether this node is controlled by any tls.
Definition: NBNode.h:297
static void parseStringVector(const std::string &def, std::vector< std::string > &into)
Splits the given string.
The turning radius at an intersection in m.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
Encapsulated SAX-Attributes.
static GeoConvHelper * loadLocation(const SUMOSAXAttributes &attrs)
Parses network location description and registers it with GeoConveHelper::setLoaded.
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:45
parameter associated to a certain key
A list of positions.
T get(const std::string &str) const
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
void deleteNode(const SUMOSAXAttributes &attrs)
void removeTrafficLights()
Removes all references to traffic lights that control this tls.
Definition: NBNode.cpp:338
Parameterised * myLastParameterised
last item the could receive parameters
void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
node: the type of traffic light
edge: the shape in xml-definition
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
OptionsCont & myOptions
A reference to the program&#39;s options.
static void processTrafficLightDefinitions(const SUMOSAXAttributes &attrs, NBNode *currentNode, NBTrafficLightLogicCont &tlc)
Builds the defined traffic light or adds a node to it.
void setKeepClear(bool keepClear)
set the keepClear flag
Definition: NBNode.h:484
void addJoinExclusion(const SUMOSAXAttributes &attrs)
std::vector< std::string > getVector()
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
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.
void addCluster2Join(std::set< std::string > cluster)
add ids of nodes which shall be joined into a single node
Definition: NBNodeCont.cpp:519
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
const std::set< NBTrafficLightDefinition * > & getControllingTLS() const
Returns the traffic lights that were assigned to this node (The set of tls that control this node) ...
Definition: NBNode.h:302
void addJoinCluster(const SUMOSAXAttributes &attrs)
Join operation.
alternative definition for junction
A storage for options typed value containers)
Definition: OptionsCont.h:98
SumoXMLNodeType getType() const
Returns the type of this node.
Definition: NBNode.h:266
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:79
const Position & getPosition() const
Definition: NBNode.h:241
Represents a single node (junction) during network building.
Definition: NBNode.h:74
bool removeFully(const std::string id)
Removes a logic definition (and all programs) from the dictionary.
void myEndElement(int element)
Called when a closing tag occurs.
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
void addNode(const SUMOSAXAttributes &attrs)
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:66
void mul(double val)
Multiplies both positions with the given value.
Definition: Position.h:112
A traffic light logics which must be computed (only nodes/edges are given)
Definition: NBOwnTLDef.h:53
delete certain element
bool extract(NBNode *node, bool remember=false)
Removes the given node but does not delete it.
Definition: NBNodeCont.cpp:149
void closePolygon()
ensures that the last position equals the first
static bool isTrafficLight(SumoXMLNodeType type)
return whether the given type is a traffic light
Definition: NBNode.cpp:2793
join exlude operation
TrafficLightType
NIXMLNodesHandler(NBNodeCont &nc, NBTrafficLightLogicCont &tlc, OptionsCont &options)
Constructor.