SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NWWriter_XML.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // Exporter writing networks using XML (native input) format
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
12 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
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 #include <algorithm>
34 #include <netbuild/NBEdge.h>
35 #include <netbuild/NBEdgeCont.h>
36 #include <netbuild/NBNode.h>
37 #include <netbuild/NBNodeCont.h>
38 #include <netbuild/NBNetBuilder.h>
39 #include <utils/common/ToString.h>
44 #include "NWFrame.h"
45 #include "NWWriter_SUMO.h"
46 #include "NWWriter_XML.h"
47 
48 #ifdef CHECK_MEMORY_LEAKS
49 #include <foreign/nvwa/debug_new.h>
50 #endif // CHECK_MEMORY_LEAKS
51 
52 
53 
54 // ===========================================================================
55 // method definitions
56 // ===========================================================================
57 // ---------------------------------------------------------------------------
58 // static methods
59 // ---------------------------------------------------------------------------
60 void
62  // check whether plain-output files shall be generated
63  if (oc.isSet("plain-output-prefix")) {
64  writeNodes(oc, nb.getNodeCont());
67  }
68  if (oc.isSet("junctions.join-output")) {
70  }
71  if (oc.isSet("street-sign-output")) {
72  writeStreetSigns(oc, nb.getEdgeCont());
73  }
74 }
75 
76 
77 void
80  bool useGeo = oc.exists("proj.plain-geo") && oc.getBool("proj.plain-geo");
81  if (useGeo && !gch.usingGeoProjection()) {
82  WRITE_WARNING("Ignoring option \"proj.plain-geo\" because no geo-conversion has been defined");
83  useGeo = false;
84  }
85  const bool geoAccuracy = useGeo || gch.usingInverseGeoProjection();
86 
87  OutputDevice& device = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".nod.xml");
88  device.writeXMLHeader("nodes", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/nodes_file.xsd\"");
89 
90  // write network offsets and projection to allow reconstruction of original coordinates
91  if (!useGeo) {
93  }
94 
95  // write nodes
96  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
97  NBNode* n = (*i).second;
98  device.openTag(SUMO_TAG_NODE);
99  device.writeAttr(SUMO_ATTR_ID, n->getID());
100  // write position
101  Position pos = n->getPosition();
102  if (useGeo) {
103  gch.cartesian2geo(pos);
104  }
105  if (geoAccuracy) {
107  }
108  NWFrame::writePositionLong(pos, device);
109  if (geoAccuracy) {
110  device.setPrecision();
111  }
112 
113  device.writeAttr(SUMO_ATTR_TYPE, toString(n->getType()));
114  if (n->isTLControlled()) {
115  const std::set<NBTrafficLightDefinition*>& tlss = n->getControllingTLS();
116  // set may contain multiple programs for the same id.
117  // make sure ids are unique and sorted
118  std::set<std::string> tlsIDs;
119  std::set<std::string> controlledInnerEdges;
120  for (std::set<NBTrafficLightDefinition*>::const_iterator it_tl = tlss.begin(); it_tl != tlss.end(); it_tl++) {
121  tlsIDs.insert((*it_tl)->getID());
122  std::vector<std::string> cie = (*it_tl)->getControlledInnerEdges();
123  controlledInnerEdges.insert(cie.begin(), cie.end());
124  }
125  std::vector<std::string> sortedIDs(tlsIDs.begin(), tlsIDs.end());
126  sort(sortedIDs.begin(), sortedIDs.end());
127  device.writeAttr(SUMO_ATTR_TLID, sortedIDs);
128  if (controlledInnerEdges.size() > 0) {
129  std::vector<std::string> sortedCIEs(controlledInnerEdges.begin(), controlledInnerEdges.end());
130  sort(sortedCIEs.begin(), sortedCIEs.end());
131  device.writeAttr(SUMO_ATTR_CONTROLLED_INNER, joinToString(sortedCIEs, " "));
132  }
133  }
134  if (n->hasCustomShape()) {
135  device.writeAttr(SUMO_ATTR_SHAPE, n->getShape());
136  }
137  device.closeTag();
138  }
139  device.close();
140 }
141 
142 
143 void
145  const GeoConvHelper& gch = GeoConvHelper::getFinal();
146  bool useGeo = oc.exists("proj.plain-geo") && oc.getBool("proj.plain-geo");
147  const bool geoAccuracy = useGeo || gch.usingInverseGeoProjection();
148 
149  OutputDevice& edevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".edg.xml");
150  edevice.writeXMLHeader("edges", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/edges_file.xsd\"");
151  OutputDevice& cdevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".con.xml");
152  cdevice.writeXMLHeader("connections", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/connections_file.xsd\"");
153  bool noNames = !oc.getBool("output.street-names");
154  for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
155  // write the edge itself to the edges-files
156  NBEdge* e = (*i).second;
157  edevice.openTag(SUMO_TAG_EDGE);
158  edevice.writeAttr(SUMO_ATTR_ID, e->getID());
159  edevice.writeAttr(SUMO_ATTR_FROM, e->getFromNode()->getID());
160  edevice.writeAttr(SUMO_ATTR_TO, e->getToNode()->getID());
161  if (!noNames && e->getStreetName() != "") {
163  }
165  // write the type if given
166  if (e->getTypeID() != "") {
167  edevice.writeAttr(SUMO_ATTR_TYPE, e->getTypeID());
168  }
170  if (!e->hasLaneSpecificSpeed()) {
171  edevice.writeAttr(SUMO_ATTR_SPEED, e->getSpeed());
172  }
173  // write non-default geometry
174  if (!e->hasDefaultGeometry()) {
175  PositionVector geom = e->getGeometry();
176  if (useGeo) {
177  for (int i = 0; i < (int) geom.size(); i++) {
178  gch.cartesian2geo(geom[i]);
179  }
180  }
181  if (geoAccuracy) {
183  }
184  edevice.writeAttr(SUMO_ATTR_SHAPE, geom);
185  if (geoAccuracy) {
186  edevice.setPrecision();
187  }
188  }
189  // write the spread type if not default ("right")
192  }
193  // write the length if it was specified
194  if (e->hasLoadedLength()) {
196  }
197  // some attributes can be set by edge default or per lane. Write as default if possible (efficiency)
199  edevice.writeAttr(SUMO_ATTR_WIDTH, e->getLaneWidth());
200  }
203  }
204  if (!e->needsLaneSpecificOutput()) {
205  edevice.closeTag();
206  } else {
207  for (unsigned int i = 0; i < e->getLanes().size(); ++i) {
208  const NBEdge::Lane& lane = e->getLanes()[i];
209  edevice.openTag(SUMO_TAG_LANE);
210  edevice.writeAttr(SUMO_ATTR_INDEX, i);
211  // write allowed lanes
214  // write other attributes
216  edevice.writeAttr(SUMO_ATTR_WIDTH, lane.width);
217  }
219  edevice.writeAttr(SUMO_ATTR_ENDOFFSET, lane.endOffset);
220  }
221  if (e->hasLaneSpecificSpeed()) {
222  edevice.writeAttr(SUMO_ATTR_SPEED, lane.speed);
223  }
224  edevice.closeTag();
225  }
226  edevice.closeTag();
227  }
228  // write this edge's connections to the connections-files
230  const std::vector<NBEdge::Connection> connections = e->getConnections();
231  for (std::vector<NBEdge::Connection>::const_iterator c = connections.begin(); c != connections.end(); ++c) {
232  NWWriter_SUMO::writeConnection(cdevice, *e, *c, false, NWWriter_SUMO::PLAIN);
233  }
234  if (connections.size() > 0) {
235  cdevice << "\n";
236  }
237  }
238 
239  // write loaded prohibitions to the connections-file
240  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
241  NWWriter_SUMO::writeProhibitions(cdevice, i->second->getProhibitions());
242  }
243  // write pedestrian crossings to the connections-file
244  for (std::map<std::string, NBNode*>::const_iterator it_node = nc.begin(); it_node != nc.end(); ++it_node) {
245  const std::vector<NBNode::Crossing>& crossings = (*it_node).second->getCrossings();
246  for (std::vector<NBNode::Crossing>::const_iterator it = crossings.begin(); it != crossings.end(); it++) {
247  cdevice.openTag(SUMO_TAG_CROSSING);
248  cdevice.writeAttr(SUMO_ATTR_NODE, (*it_node).second->getID());
249  cdevice.writeAttr(SUMO_ATTR_EDGES, (*it).edges);
250  cdevice.writeAttr(SUMO_ATTR_PRIORITY, (*it).priority);
251  if ((*it).width != NBNode::DEFAULT_CROSSING_WIDTH) {
252  cdevice.writeAttr(SUMO_ATTR_WIDTH, (*it).width);
253  }
254  cdevice.closeTag();
255  }
256  }
257  edevice.close();
258  cdevice.close();
259 }
260 
261 
262 void
264  OutputDevice& device = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".tll.xml");
265  device.writeXMLHeader("tlLogics", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/tllogic_file.xsd\"");
267  // we also need to remember the associations between tlLogics and connections
268  // since the information in con.xml is insufficient
269  for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
270  NBEdge* e = (*i).second;
271  // write this edge's tl-controlled connections
272  const std::vector<NBEdge::Connection> connections = e->getConnections();
273  for (std::vector<NBEdge::Connection>::const_iterator c = connections.begin(); c != connections.end(); ++c) {
274  if (c->tlID != "") {
275  NWWriter_SUMO::writeConnection(device, *e, *c, false, NWWriter_SUMO::TLL);
276  }
277  }
278  }
279  device.close();
280 }
281 
282 
283 void
285  OutputDevice& device = OutputDevice::getDevice(oc.getString("junctions.join-output"));
286  device.writeXMLHeader("nodes", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/nodes_file.xsd\"");
287  const std::vector<std::set<std::string> >& clusters = nc.getJoinedClusters();
288  for (std::vector<std::set<std::string> >::const_iterator it = clusters.begin(); it != clusters.end(); it++) {
289  assert((*it).size() > 0);
290  device.openTag(SUMO_TAG_JOIN);
291  // prepare string
292  std::ostringstream oss;
293  for (std::set<std::string>::const_iterator it_id = it->begin(); it_id != it->end(); it_id++) {
294  oss << *it_id << " ";
295  }
296  // remove final space
297  std::string ids = oss.str();
298  device.writeAttr(SUMO_ATTR_NODES, ids.substr(0, ids.size() - 1));
299  device.closeTag();
300  }
301  device.close();
302 }
303 
304 
305 void
307  OutputDevice& device = OutputDevice::getDevice(oc.getString("street-sign-output"));
308  device.writeXMLHeader("pois", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/poi_file.xsd\"");
309  for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
310  NBEdge* e = (*i).second;
311  const std::vector<NBSign>& signs = e->getSigns();
312  for (std::vector<NBSign>::const_iterator it = signs.begin(); it != signs.end(); ++it) {
313  it->writeAsPOI(device, e);
314  }
315  }
316  device.close();
317 }
318 /****************************************************************************/
319